From cef885cfde9b3673f5241ad480558c38bb48273b Mon Sep 17 00:00:00 2001 From: Daniel Otto de Mentock Date: Tue, 14 Dec 2021 17:05:00 +0100 Subject: [PATCH 01/72] added first typehints for rotation and orientation modules --- python/damask/_orientation.py | 136 ++++++++++-------- python/damask/_rotation.py | 251 ++++++++++++++++++---------------- 2 files changed, 211 insertions(+), 176 deletions(-) diff --git a/python/damask/_orientation.py b/python/damask/_orientation.py index e727c54ae..6c0dd2fa3 100644 --- a/python/damask/_orientation.py +++ b/python/damask/_orientation.py @@ -1,5 +1,6 @@ import inspect import copy +from typing import Union, Callable, Sequence, Dict, Any, Tuple, List import numpy as np @@ -93,12 +94,12 @@ class Orientation(Rotation,Crystal): @util.extend_docstring(_parameter_doc) def __init__(self, - rotation = np.array([1.0,0.0,0.0,0.0]), *, - family = None, - lattice = None, - a = None,b = None,c = None, - alpha = None,beta = None,gamma = None, - degrees = False): + rotation: Union[Sequence[float], np.ndarray, Rotation] = np.array([1.,0.,0.,0.]), *, + family: str = None, + lattice: str = None, + a: float = None, b: float = None, c: float = None, + alpha: float = None, beta: float = None, gamma: float = None, + degrees: bool = False): """ New orientation. @@ -115,13 +116,12 @@ class Orientation(Rotation,Crystal): a=a,b=b,c=c, alpha=alpha,beta=beta,gamma=gamma, degrees=degrees) - def __repr__(self): + def __repr__(self) -> str: """Represent.""" return '\n'.join([Crystal.__repr__(self), Rotation.__repr__(self)]) - - def __copy__(self,rotation=None): + def __copy__(self,rotation: Union[Sequence[float], np.ndarray, Rotation] = None) -> "Orientation": """Create deep copy.""" dup = copy.deepcopy(self) if rotation is not None: @@ -131,7 +131,8 @@ class Orientation(Rotation,Crystal): copy = __copy__ - def __eq__(self,other): + + def __eq__(self, other: object) -> bool: """ Equal to other. @@ -141,12 +142,14 @@ class Orientation(Rotation,Crystal): Orientation to check for equality. """ + if not isinstance(other, Orientation): + raise TypeError matching_type = self.family == other.family and \ self.lattice == other.lattice and \ self.parameters == other.parameters return np.logical_and(matching_type,super(self.__class__,self.reduced).__eq__(other.reduced)) - def __ne__(self,other): + def __ne__(self, other: object) -> bool: """ Not equal to other. @@ -156,10 +159,16 @@ class Orientation(Rotation,Crystal): Orientation to check for equality. """ + if not isinstance(other, Orientation): + raise TypeError return np.logical_not(self==other) - def isclose(self,other,rtol=1e-5,atol=1e-8,equal_nan=True): + def isclose(self, + other: object, + rtol: float = 1e-5, + atol: float = 1e-8, + equal_nan: bool = True) -> bool: """ Report where values are approximately equal to corresponding ones of other Orientation. @@ -180,6 +189,8 @@ class Orientation(Rotation,Crystal): Mask indicating where corresponding orientations are close. """ + if not isinstance(other, Orientation): + raise TypeError matching_type = self.family == other.family and \ self.lattice == other.lattice and \ self.parameters == other.parameters @@ -187,7 +198,11 @@ class Orientation(Rotation,Crystal): - def allclose(self,other,rtol=1e-5,atol=1e-8,equal_nan=True): + def allclose(self, + other: object, + rtol: float = 1e-5, + atol: float = 1e-8, + equal_nan: bool = True) -> Union[bool, np.bool_]: """ Test whether all values are approximately equal to corresponding ones of other Orientation. @@ -208,10 +223,12 @@ class Orientation(Rotation,Crystal): Whether all values are close between both orientations. """ + if not isinstance(other, Orientation): + raise TypeError return np.all(self.isclose(other,rtol,atol,equal_nan)) - def __mul__(self,other): + def __mul__(self, other: Union[Rotation, "Orientation"]) -> "Orientation": """ Compose this orientation with other. @@ -233,7 +250,7 @@ class Orientation(Rotation,Crystal): @staticmethod - def _split_kwargs(kwargs,target): + def _split_kwargs(kwargs: Dict[str, Any], target: Callable) -> Tuple[Dict[str, Any], ...]: """ Separate keyword arguments in 'kwargs' targeted at 'target' from general keyword arguments of Orientation objects. @@ -252,7 +269,7 @@ class Orientation(Rotation,Crystal): Valid keyword arguments of Orientation object. """ - kws = () + kws: Tuple[Dict[str, Any], ...] = () for t in (target,Orientation.__init__): kws += ({key: kwargs[key] for key in set(inspect.signature(t).parameters) & set(kwargs)},) @@ -264,85 +281,88 @@ class Orientation(Rotation,Crystal): @classmethod - @util.extended_docstring(Rotation.from_random,_parameter_doc) - def from_random(cls,**kwargs): + @util.extended_docstring(Rotation.from_random, _parameter_doc) + def from_random(cls, **kwargs) -> "Orientation": kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_random) return cls(rotation=Rotation.from_random(**kwargs_rot),**kwargs_ori) @classmethod @util.extended_docstring(Rotation.from_quaternion,_parameter_doc) - def from_quaternion(cls,**kwargs): + def from_quaternion(cls, **kwargs) -> "Orientation": kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_quaternion) return cls(rotation=Rotation.from_quaternion(**kwargs_rot),**kwargs_ori) @classmethod @util.extended_docstring(Rotation.from_Euler_angles,_parameter_doc) - def from_Euler_angles(cls,**kwargs): + def from_Euler_angles(cls, **kwargs) -> "Orientation": kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_Euler_angles) return cls(rotation=Rotation.from_Euler_angles(**kwargs_rot),**kwargs_ori) @classmethod @util.extended_docstring(Rotation.from_axis_angle,_parameter_doc) - def from_axis_angle(cls,**kwargs): + def from_axis_angle(cls, **kwargs) -> "Orientation": kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_axis_angle) return cls(rotation=Rotation.from_axis_angle(**kwargs_rot),**kwargs_ori) @classmethod @util.extended_docstring(Rotation.from_basis,_parameter_doc) - def from_basis(cls,**kwargs): + def from_basis(cls, **kwargs) -> "Orientation": kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_basis) return cls(rotation=Rotation.from_basis(**kwargs_rot),**kwargs_ori) @classmethod @util.extended_docstring(Rotation.from_matrix,_parameter_doc) - def from_matrix(cls,**kwargs): + def from_matrix(cls, **kwargs) -> "Orientation": kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_matrix) return cls(rotation=Rotation.from_matrix(**kwargs_rot),**kwargs_ori) @classmethod @util.extended_docstring(Rotation.from_Rodrigues_vector,_parameter_doc) - def from_Rodrigues_vector(cls,**kwargs): + def from_Rodrigues_vector(cls, **kwargs) -> "Orientation": kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_Rodrigues_vector) return cls(rotation=Rotation.from_Rodrigues_vector(**kwargs_rot),**kwargs_ori) @classmethod @util.extended_docstring(Rotation.from_homochoric,_parameter_doc) - def from_homochoric(cls,**kwargs): + def from_homochoric(cls, **kwargs) -> "Orientation": kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_homochoric) return cls(rotation=Rotation.from_homochoric(**kwargs_rot),**kwargs_ori) @classmethod @util.extended_docstring(Rotation.from_cubochoric,_parameter_doc) - def from_cubochoric(cls,**kwargs): + def from_cubochoric(cls, **kwargs) -> "Orientation": kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_cubochoric) return cls(rotation=Rotation.from_cubochoric(**kwargs_rot),**kwargs_ori) @classmethod @util.extended_docstring(Rotation.from_spherical_component,_parameter_doc) - def from_spherical_component(cls,**kwargs): + def from_spherical_component(cls, **kwargs) -> "Orientation": kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_spherical_component) return cls(rotation=Rotation.from_spherical_component(**kwargs_rot),**kwargs_ori) @classmethod @util.extended_docstring(Rotation.from_fiber_component,_parameter_doc) - def from_fiber_component(cls,**kwargs): + def from_fiber_component(cls, **kwargs) -> "Orientation": kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_fiber_component) return cls(rotation=Rotation.from_fiber_component(**kwargs_rot),**kwargs_ori) @classmethod @util.extend_docstring(_parameter_doc) - def from_directions(cls,uvw,hkl,**kwargs): + def from_directions(cls, + uvw: Union[Sequence[float], np.ndarray], + hkl: Union[Sequence[float], np.ndarray], + **kwargs) -> "Orientation": """ Initialize orientation object from two crystallographic directions. @@ -362,7 +382,7 @@ class Orientation(Rotation,Crystal): @property - def equivalent(self): + def equivalent(self) -> "Orientation": """ Orientations that are symmetrically equivalent. @@ -376,7 +396,7 @@ class Orientation(Rotation,Crystal): @property - def reduced(self): + def reduced(self) -> "Orientation": """Select symmetrically equivalent orientation that falls into fundamental zone according to symmetry.""" eq = self.equivalent ok = eq.in_FZ @@ -385,9 +405,8 @@ class Orientation(Rotation,Crystal): sort = 0 if len(loc) == 1 else np.lexsort(loc[:0:-1]) return eq[ok][sort].reshape(self.shape) - @property - def in_FZ(self): + def in_FZ(self) -> Union[np.bool_, np.ndarray]: """ Check whether orientation falls into fundamental zone of own symmetry. @@ -431,7 +450,7 @@ class Orientation(Rotation,Crystal): @property - def in_disorientation_FZ(self): + def in_disorientation_FZ(self) -> np.ndarray: """ Check whether orientation falls into fundamental zone of disorientations. @@ -471,8 +490,7 @@ class Orientation(Rotation,Crystal): else: return np.ones_like(rho[...,0],dtype=bool) - - def disorientation(self,other,return_operators=False): + def disorientation(self, other, return_operators = False): """ Calculate disorientation between myself and given other orientation. @@ -518,8 +536,8 @@ class Orientation(Rotation,Crystal): if self.family != other.family: raise NotImplementedError('disorientation between different crystal families') - blend = util.shapeblender(self.shape,other.shape) - s = self.equivalent + blend: Tuple[int, ...] = util.shapeblender(self.shape,other.shape) + s = self.equivalent o = other.equivalent s_ = s.reshape((s.shape[0],1)+ self.shape).broadcast_to((s.shape[0],o.shape[0])+blend,mode='right') @@ -534,10 +552,9 @@ class Orientation(Rotation,Crystal): r = np.where(np.any(forward[...,np.newaxis],axis=(0,1),keepdims=True), r_.quaternion, _r.quaternion) - loc = np.where(ok) - sort = 0 if len(loc) == 2 else np.lexsort(loc[:1:-1]) - quat = r[ok][sort].reshape(blend+(4,)) - + loc: Tuple[float] = np.where(ok) + sort: np.ndarray = 0 if len(loc) == 2 else np.lexsort(loc[:1:-1]) + quat: np.ndarray = r[ok][sort].reshape(blend+(4,)) return ( (self.copy(rotation=quat), (np.vstack(loc[:2]).T)[sort].reshape(blend+(2,))) @@ -546,7 +563,7 @@ class Orientation(Rotation,Crystal): ) - def average(self,weights=None,return_cloud=False): + def average(self, weights = None, return_cloud = False): """ Return orientation average over last dimension. @@ -587,7 +604,10 @@ class Orientation(Rotation,Crystal): ) - def to_SST(self,vector,proper=False,return_operators=False): + def to_SST(self, + vector: np.ndarray, + proper: bool = False, + return_operators: bool = False) -> np.ndarray: """ Rotate vector to ensure it falls into (improper or proper) standard stereographic triangle of crystal symmetry. @@ -626,7 +646,7 @@ class Orientation(Rotation,Crystal): ) - def in_SST(self,vector,proper=False): + def in_SST(self, vector: np.ndarray, proper: bool = False) -> Union[np.bool_, np.ndarray]: """ Check whether given crystal frame vector falls into standard stereographic triangle of own symmetry. @@ -667,7 +687,7 @@ class Orientation(Rotation,Crystal): return np.all(components >= 0.0,axis=-1) - def IPF_color(self,vector,in_SST=True,proper=False): + def IPF_color(self, vector: np.ndarray, in_SST: bool = True, proper: bool = False) -> np.ndarray: """ Map vector to RGB color within standard stereographic triangle of own symmetry. @@ -715,30 +735,30 @@ class Orientation(Rotation,Crystal): components_improper = np.around(np.einsum('...ji,...i', np.broadcast_to(self.standard_triangle['improper'], vector_.shape+(3,)), vector_), 12) - in_SST = np.all(components_proper >= 0.0,axis=-1) \ + in_SST_ = np.all(components_proper >= 0.0,axis=-1) \ | np.all(components_improper >= 0.0,axis=-1) - components = np.where((in_SST & np.all(components_proper >= 0.0,axis=-1))[...,np.newaxis], + components = np.where((in_SST_ & np.all(components_proper >= 0.0,axis=-1))[...,np.newaxis], components_proper,components_improper) else: components = np.around(np.einsum('...ji,...i', np.broadcast_to(self .standard_triangle['improper'], vector_.shape+(3,)), np.block([vector_[...,:2],np.abs(vector_[...,2:3])])), 12) - in_SST = np.all(components >= 0.0,axis=-1) + in_SST_ = np.all(components >= 0.0,axis=-1) with np.errstate(invalid='ignore',divide='ignore'): rgb = (components/np.linalg.norm(components,axis=-1,keepdims=True))**0.5 # smoothen color ramps rgb = np.clip(rgb,0.,1.) # clip intensity rgb /= np.max(rgb,axis=-1,keepdims=True) # normalize to (HS)V = 1 - rgb[np.broadcast_to(~in_SST[...,np.newaxis],rgb.shape)] = 0.0 + rgb[np.broadcast_to(~in_SST_[...,np.newaxis],rgb.shape)] = 0.0 return rgb @property - def symmetry_operations(self): + def symmetry_operations(self) -> Rotation: """Symmetry operations as Rotations.""" - _symmetry_operations = { + _symmetry_operations: Dict[str, List[List]] = { 'cubic': [ [ 1.0, 0.0, 0.0, 0.0 ], [ 0.0, 1.0, 0.0, 0.0 ], @@ -808,7 +828,10 @@ class Orientation(Rotation,Crystal): #################################################################################################### # functions that require lattice, not just family - def to_pole(self,*,uvw=None,hkl=None,with_symmetry=False): + def to_pole(self, *, + uvw: np.ndarray = None, + hkl: np.ndarray = None, + with_symmetry: bool = False) -> np.ndarray: """ Calculate lab frame vector along lattice direction [uvw] or plane normal (hkl). @@ -839,7 +862,9 @@ class Orientation(Rotation,Crystal): @ np.broadcast_to(v,blend+(3,)) - def Schmid(self,*,N_slip=None,N_twin=None): + def Schmid(self, *, + N_slip: Sequence[int] = None, + N_twin: Sequence[int] = None) -> np.ndarray: u""" Calculate Schmid matrix P = d ⨂ n in the lab frame for selected deformation systems. @@ -876,6 +901,7 @@ class Orientation(Rotation,Crystal): (self.kinematics('twin'),N_twin) if active == '*': active = [len(a) for a in kinematics['direction']] + assert active d = self.to_frame(uvw=np.vstack([kinematics['direction'][i][:n] for i,n in enumerate(active)])) p = self.to_frame(hkl=np.vstack([kinematics['plane'][i][:n] for i,n in enumerate(active)])) P = np.einsum('...i,...j',d/np.linalg.norm(d,axis=1,keepdims=True), @@ -886,7 +912,7 @@ class Orientation(Rotation,Crystal): @ np.broadcast_to(P.reshape(util.shapeshifter(P.shape,shape)),shape) - def related(self,model): + def related(self, model: str) -> "Orientation": """ Orientations derived from the given relationship. diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index ac921d70a..0a4421090 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -6,6 +6,8 @@ from . import tensor from . import util from . import grid_filters +from typing import Union, Sequence, Tuple, Literal, List + _P = -1 # parameters for conversion from/to cubochoric @@ -61,7 +63,7 @@ class Rotation: __slots__ = ['quaternion'] - def __init__(self,rotation = np.array([1.0,0.0,0.0,0.0])): + def __init__(self, rotation: Union[Sequence[float], np.ndarray, "Rotation"] = np.array([1.0,0.0,0.0,0.0])): """ New rotation. @@ -73,6 +75,7 @@ class Rotation: Defaults to no rotation. """ + self.quaternion: np.ndarray if isinstance(rotation,Rotation): self.quaternion = rotation.quaternion.copy() elif np.array(rotation).shape[-1] == 4: @@ -81,13 +84,13 @@ class Rotation: raise TypeError('"rotation" is neither a Rotation nor a quaternion') - def __repr__(self): + def __repr__(self) -> str: """Represent rotation as unit quaternion(s).""" return f'Quaternion{" " if self.quaternion.shape == (4,) else "s of shape "+str(self.quaternion.shape[:-1])+chr(10)}'\ + str(self.quaternion) - def __copy__(self,rotation=None): + def __copy__(self, rotation: Union[Sequence[float], np.ndarray, "Rotation"] = None) -> "Rotation": """Create deep copy.""" dup = copy.deepcopy(self) if rotation is not None: @@ -97,14 +100,14 @@ class Rotation: copy = __copy__ - def __getitem__(self,item): + def __getitem__(self, item: Union[Tuple[int], int, bool, np.bool_, np.ndarray]): """Return slice according to item.""" return self.copy() \ if self.shape == () else \ self.copy(rotation=self.quaternion[item+(slice(None),)] if isinstance(item,tuple) else self.quaternion[item]) - def __eq__(self,other): + def __eq__(self, other: object) -> bool: """ Equal to other. @@ -114,11 +117,13 @@ class Rotation: Rotation to check for equality. """ + if not isinstance(other, Rotation): + raise TypeError return np.logical_or(np.all(self.quaternion == other.quaternion,axis=-1), np.all(self.quaternion == -1.0*other.quaternion,axis=-1)) - def __ne__(self,other): + def __ne__(self, other: object) -> bool: """ Not equal to other. @@ -128,10 +133,12 @@ class Rotation: Rotation to check for inequality. """ + if not isinstance(other, Rotation): + raise TypeError return np.logical_not(self==other) - def isclose(self,other,rtol=1e-5,atol=1e-8,equal_nan=True): + def isclose(self, other: "Rotation", rtol: float = 1e-5, atol: float = 1e-8, equal_nan: bool = True) -> bool: """ Report where values are approximately equal to corresponding ones of other Rotation. @@ -158,7 +165,7 @@ class Rotation: np.all(np.isclose(s,-1.0*o,rtol,atol,equal_nan),axis=-1)) - def allclose(self,other,rtol=1e-5,atol=1e-8,equal_nan=True): + def allclose(self, other: "Rotation", rtol: float = 1e-5, atol: float = 1e-8, equal_nan: bool = True) -> Union[np.bool_, bool]: """ Test whether all values are approximately equal to corresponding ones of other Rotation. @@ -188,27 +195,27 @@ class Rotation: @property - def size(self): + def size(self) -> int: return self.quaternion[...,0].size @property - def shape(self): + def shape(self) -> Tuple[int, ...]: return self.quaternion[...,0].shape - def __len__(self): + def __len__(self) -> int: """Length of leading/leftmost dimension of array.""" return 0 if self.shape == () else self.shape[0] - def __invert__(self): + def __invert__(self) -> "Rotation": """Inverse rotation (backward rotation).""" dup = self.copy() dup.quaternion[...,1:] *= -1 return dup - def __pow__(self,exp): + def __pow__(self, exp: int) -> "Rotation": """ Perform the rotation 'exp' times. @@ -222,7 +229,7 @@ class Rotation: p = self.quaternion[...,1:]/np.linalg.norm(self.quaternion[...,1:],axis=-1,keepdims=True) return self.copy(rotation=Rotation(np.block([np.cos(exp*phi),np.sin(exp*phi)*p]))._standardize()) - def __ipow__(self,exp): + def __ipow__(self, exp: int) -> "Rotation": """ Perform the rotation 'exp' times (in-place). @@ -235,7 +242,7 @@ class Rotation: return self**exp - def __mul__(self,other): + def __mul__(self, other: "Rotation") -> "Rotation": """ Compose with other. @@ -261,7 +268,7 @@ class Rotation: else: raise TypeError('Use "R@b", i.e. matmul, to apply rotation "R" to object "b"') - def __imul__(self,other): + def __imul__(self, other: "Rotation") -> "Rotation": """ Compose with other (in-place). @@ -274,7 +281,7 @@ class Rotation: return self*other - def __truediv__(self,other): + def __truediv__(self, other: "Rotation") -> "Rotation": """ Compose with inverse of other. @@ -294,7 +301,7 @@ class Rotation: else: raise TypeError('Use "R@b", i.e. matmul, to apply rotation "R" to object "b"') - def __itruediv__(self,other): + def __itruediv__(self, other: "Rotation") -> "Rotation": """ Compose with inverse of other (in-place). @@ -307,7 +314,7 @@ class Rotation: return self/other - def __matmul__(self,other): + def __matmul__(self, other: np.ndarray) -> np.ndarray: """ Rotate vector, second order tensor, or fourth order tensor. @@ -350,13 +357,13 @@ class Rotation: apply = __matmul__ - def _standardize(self): + def _standardize(self) -> "Rotation": """Standardize quaternion (ensure positive real hemisphere).""" self.quaternion[self.quaternion[...,0] < 0.0] *= -1 return self - def append(self,other): + def append(self, other: Union["Rotation", List["Rotation"]]) -> "Rotation": """ Extend array along first dimension with other array(s). @@ -369,7 +376,7 @@ class Rotation: [self]+other if isinstance(other,list) else [self,other])))) - def flatten(self,order = 'C'): + def flatten(self, order: Literal['C','F','A'] = 'C') -> "Rotation": """ Flatten array. @@ -382,7 +389,7 @@ class Rotation: return self.copy(rotation=self.quaternion.reshape((-1,4),order=order)) - def reshape(self,shape,order = 'C'): + def reshape(self,shape: Union[int, Tuple[int, ...]], order: Literal['C','F','A'] = 'C') -> "Rotation": """ Reshape array. @@ -396,7 +403,7 @@ class Rotation: return self.copy(rotation=self.quaternion.reshape(tuple(shape)+(4,),order=order)) - def broadcast_to(self,shape,mode = 'right'): + def broadcast_to(self, shape: Union[int, Tuple[int, ...]], mode: Literal["left", "right"] = 'right') -> "Rotation": """ Broadcast array. @@ -458,7 +465,7 @@ class Rotation: accept_homomorph = True) - def misorientation(self,other): + def misorientation(self, other: "Rotation") -> "Rotation": """ Calculate misorientation to other Rotation. @@ -479,7 +486,7 @@ class Rotation: ################################################################################################ # convert to different orientation representations (numpy arrays) - def as_quaternion(self): + def as_quaternion(self) -> np.ndarray: """ Represent as unit quaternion. @@ -492,7 +499,7 @@ class Rotation: return self.quaternion.copy() def as_Euler_angles(self, - degrees = False): + degrees: bool = False) -> np.ndarray: """ Represent as Bunge Euler angles. @@ -526,8 +533,8 @@ class Rotation: return eu def as_axis_angle(self, - degrees = False, - pair = False): + degrees: bool = False, + pair: bool = False) -> Union[Tuple[float, ...], np.ndarray]: """ Represent as axis–angle pair. @@ -554,11 +561,11 @@ class Rotation: (array([0., 0., 1.]), array(0.)) """ - ax = Rotation._qu2ax(self.quaternion) + ax: np.ndarray = Rotation._qu2ax(self.quaternion) if degrees: ax[...,3] = np.degrees(ax[...,3]) return (ax[...,:3],ax[...,3]) if pair else ax - def as_matrix(self): + def as_matrix(self) -> np.ndarray: """ Represent as rotation matrix. @@ -582,7 +589,7 @@ class Rotation: return Rotation._qu2om(self.quaternion) def as_Rodrigues_vector(self, - compact = False): + compact: bool = False) -> np.ndarray: """ Represent as Rodrigues–Frank vector with separate axis and angle argument. @@ -615,7 +622,7 @@ class Rotation: else: return ro - def as_homochoric(self): + def as_homochoric(self) -> np.ndarray: """ Represent as homochoric vector. @@ -636,7 +643,7 @@ class Rotation: """ return Rotation._qu2ho(self.quaternion) - def as_cubochoric(self): + def as_cubochoric(self) -> np.ndarray: """ Represent as cubochoric vector. @@ -661,9 +668,9 @@ class Rotation: # Static constructors. The input data needs to follow the conventions, options allow to # relax the conventions. @staticmethod - def from_quaternion(q, - accept_homomorph = False, - P = -1): + def from_quaternion(q: Union[Sequence[Sequence[float]], np.ndarray], + accept_homomorph: bool = False, + P: Literal[1, -1] = -1) -> "Rotation": """ Initialize from quaternion. @@ -678,7 +685,7 @@ class Rotation: Sign convention. Defaults to -1. """ - qu = np.array(q,dtype=float) + qu: np.ndarray = np.array(q,dtype=float) if qu.shape[:-2:-1] != (4,): raise ValueError('Invalid shape.') if abs(P) != 1: @@ -696,8 +703,8 @@ class Rotation: return Rotation(qu) @staticmethod - def from_Euler_angles(phi, - degrees = False): + def from_Euler_angles(phi: np.ndarray, + degrees: bool = False) -> "Rotation": """ Initialize from Bunge Euler angles. @@ -725,10 +732,10 @@ class Rotation: return Rotation(Rotation._eu2qu(eu)) @staticmethod - def from_axis_angle(axis_angle, - degrees = False, - normalize = False, - P = -1): + def from_axis_angle(axis_angle: np.ndarray, + degrees:bool = False, + normalize: bool = False, + P: Literal[1, -1] = -1) -> "Rotation": """ Initialize from Axis angle pair. @@ -763,9 +770,9 @@ class Rotation: return Rotation(Rotation._ax2qu(ax)) @staticmethod - def from_basis(basis, - orthonormal = True, - reciprocal = False): + def from_basis(basis: np.ndarray, + orthonormal: bool = True, + reciprocal: bool = False) -> "Rotation": """ Initialize from lattice basis vectors. @@ -799,7 +806,7 @@ class Rotation: return Rotation(Rotation._om2qu(om)) @staticmethod - def from_matrix(R): + def from_matrix(R: np.ndarray) -> "Rotation": """ Initialize from rotation matrix. @@ -812,8 +819,9 @@ class Rotation: return Rotation.from_basis(R) @staticmethod - def from_parallel(a,b, - **kwargs): + def from_parallel(a: np.ndarray, + b: np.ndarray, + **kwargs) -> "Rotation": """ Initialize from pairs of two orthogonal lattice basis vectors. @@ -841,9 +849,9 @@ class Rotation: @staticmethod - def from_Rodrigues_vector(rho, - normalize = False, - P = -1): + def from_Rodrigues_vector(rho: np.ndarray, + normalize: bool = False, + P: Literal[1, -1] = -1) -> "Rotation": """ Initialize from Rodrigues–Frank vector (angle separated from axis). @@ -873,8 +881,8 @@ class Rotation: return Rotation(Rotation._ro2qu(ro)) @staticmethod - def from_homochoric(h, - P = -1): + def from_homochoric(h: np.ndarray, + P: Literal[1, -1] = -1) -> "Rotation": """ Initialize from homochoric vector. @@ -900,8 +908,8 @@ class Rotation: return Rotation(Rotation._ho2qu(ho)) @staticmethod - def from_cubochoric(x, - P = -1): + def from_cubochoric(x: np.ndarray, + P: Literal[1, -1] = -1) -> "Rotation": """ Initialize from cubochoric vector. @@ -928,8 +936,8 @@ class Rotation: @staticmethod - def from_random(shape = None, - rng_seed = None): + def from_random(shape: Tuple[int, ...] = None, + rng_seed: Union[None, int, Sequence[int], np.ndarray] = None) -> "Rotation": """ Initialize with random rotation. @@ -958,13 +966,13 @@ class Rotation: @staticmethod - def from_ODF(weights, - phi, - N = 500, - degrees = True, - fractions = True, - rng_seed = None, - **kwargs): + def from_ODF(weights: np.ndarray, + phi: np.ndarray, + N: int = 500, + degrees: bool = True, + fractions: bool = True, + rng_seed: Union[None, int, Sequence[int], np.ndarray] = None, + **kwargs) -> "Rotation": """ Sample discrete values from a binned orientation distribution function (ODF). @@ -1017,11 +1025,11 @@ class Rotation: @staticmethod - def from_spherical_component(center, - sigma, - N = 500, - degrees = True, - rng_seed = None): + def from_spherical_component(center: "Rotation", + sigma: float, + N: int = 500, + degrees: bool = True, + rng_seed: Union[None, int, Sequence[float], np.ndarray] = None) -> "Rotation": """ Calculate set of rotations with Gaussian distribution around center. @@ -1052,12 +1060,12 @@ class Rotation: @staticmethod - def from_fiber_component(alpha, - beta, - sigma = 0.0, - N = 500, - degrees = True, - rng_seed = None): + def from_fiber_component(alpha: np.ndarray, + beta: np.ndarray, + sigma: float = 0.0, + N: int = 500, + degrees: bool = True, + rng_seed: bool = None): """ Calculate set of rotations with Gaussian distribution around direction. @@ -1080,7 +1088,8 @@ class Rotation: """ rng = np.random.default_rng(rng_seed) - sigma_,alpha_,beta_ = map(np.radians,(sigma,alpha,beta)) if degrees else (sigma,alpha,beta) + sigma_: np.ndarray; alpha_: np.ndarray; beta_: np.ndarray + sigma_,alpha_,beta_ = map(np.radians,(sigma,alpha,beta)) if degrees else (sigma,alpha,beta) # type: ignore d_cr = np.array([np.sin(alpha_[0])*np.cos(alpha_[1]), np.sin(alpha_[0])*np.sin(alpha_[1]), np.cos(alpha_[0])]) d_lab = np.array([np.sin( beta_[0])*np.cos( beta_[1]), np.sin( beta_[0])*np.sin( beta_[1]), np.cos( beta_[0])]) @@ -1134,7 +1143,7 @@ class Rotation: #################################################################################################### #---------- Quaternion ---------- @staticmethod - def _qu2om(qu): + def _qu2om(qu: np.ndarray) -> np.ndarray: qq = qu[...,0:1]**2-(qu[...,1:2]**2 + qu[...,2:3]**2 + qu[...,3:4]**2) om = np.block([qq + 2.0*qu[...,1:2]**2, 2.0*(qu[...,2:3]*qu[...,1:2]-_P*qu[...,0:1]*qu[...,3:4]), @@ -1149,7 +1158,7 @@ class Rotation: return om @staticmethod - def _qu2eu(qu): + def _qu2eu(qu: np.ndarray) -> np.ndarray: """Quaternion to Bunge Euler angles.""" q02 = qu[...,0:1]*qu[...,2:3] q13 = qu[...,1:2]*qu[...,3:4] @@ -1177,7 +1186,7 @@ class Rotation: return eu @staticmethod - def _qu2ax(qu): + def _qu2ax(qu: np.ndarray) -> np.ndarray: """ Quaternion to axis–angle pair. @@ -1193,7 +1202,7 @@ class Rotation: return ax @staticmethod - def _qu2ro(qu): + def _qu2ro(qu: np.ndarray) -> np.ndarray: """Quaternion to Rodrigues–Frank vector.""" with np.errstate(invalid='ignore',divide='ignore'): s = np.linalg.norm(qu[...,1:4],axis=-1,keepdims=True) @@ -1207,7 +1216,7 @@ class Rotation: return ro @staticmethod - def _qu2ho(qu): + def _qu2ho(qu: np.ndarray) -> np.ndarray: """Quaternion to homochoric vector.""" with np.errstate(invalid='ignore'): omega = 2.0 * np.arccos(np.clip(qu[...,0:1],-1.0,1.0)) @@ -1218,14 +1227,14 @@ class Rotation: return ho @staticmethod - def _qu2cu(qu): + def _qu2cu(qu: np.ndarray) -> np.ndarray: """Quaternion to cubochoric vector.""" return Rotation._ho2cu(Rotation._qu2ho(qu)) #---------- Rotation matrix ---------- @staticmethod - def _om2qu(om): + def _om2qu(om: np.ndarray) -> np.ndarray: """ Rotation matrix to quaternion. @@ -1267,7 +1276,7 @@ class Rotation: return qu @staticmethod - def _om2eu(om): + def _om2eu(om: np.ndarray) -> np.ndarray: """Rotation matrix to Bunge Euler angles.""" with np.errstate(invalid='ignore',divide='ignore'): zeta = 1.0/np.sqrt(1.0-om[...,2,2:3]**2) @@ -1286,7 +1295,7 @@ class Rotation: return eu @staticmethod - def _om2ax(om): + def _om2ax(om: np.ndarray) -> np.ndarray: """Rotation matrix to axis–angle pair.""" diag_delta = -_P*np.block([om[...,1,2:3]-om[...,2,1:2], om[...,2,0:1]-om[...,0,2:3], @@ -1307,24 +1316,24 @@ class Rotation: return ax @staticmethod - def _om2ro(om): + def _om2ro(om: np.ndarray) -> np.ndarray: """Rotation matrix to Rodrigues–Frank vector.""" return Rotation._eu2ro(Rotation._om2eu(om)) @staticmethod - def _om2ho(om): + def _om2ho(om: np.ndarray) -> np.ndarray: """Rotation matrix to homochoric vector.""" return Rotation._ax2ho(Rotation._om2ax(om)) @staticmethod - def _om2cu(om): + def _om2cu(om: np.ndarray) -> np.ndarray: """Rotation matrix to cubochoric vector.""" return Rotation._ho2cu(Rotation._om2ho(om)) #---------- Bunge Euler angles ---------- @staticmethod - def _eu2qu(eu): + def _eu2qu(eu: np.ndarray) -> np.ndarray: """Bunge Euler angles to quaternion.""" ee = 0.5*eu cPhi = np.cos(ee[...,1:2]) @@ -1337,7 +1346,7 @@ class Rotation: return qu @staticmethod - def _eu2om(eu): + def _eu2om(eu: np.ndarray) -> np.ndarray: """Bunge Euler angles to rotation matrix.""" c = np.cos(eu) s = np.sin(eu) @@ -1355,7 +1364,7 @@ class Rotation: return om @staticmethod - def _eu2ax(eu): + def _eu2ax(eu: np.ndarray) -> np.ndarray: """Bunge Euler angles to axis–angle pair.""" t = np.tan(eu[...,1:2]*0.5) sigma = 0.5*(eu[...,0:1]+eu[...,2:3]) @@ -1374,7 +1383,7 @@ class Rotation: return ax @staticmethod - def _eu2ro(eu): + def _eu2ro(eu: np.ndarray) -> np.ndarray: """Bunge Euler angles to Rodrigues–Frank vector.""" ax = Rotation._eu2ax(eu) ro = np.block([ax[...,:3],np.tan(ax[...,3:4]*.5)]) @@ -1383,19 +1392,19 @@ class Rotation: return ro @staticmethod - def _eu2ho(eu): + def _eu2ho(eu: np.ndarray) -> np.ndarray: """Bunge Euler angles to homochoric vector.""" return Rotation._ax2ho(Rotation._eu2ax(eu)) @staticmethod - def _eu2cu(eu): + def _eu2cu(eu: np.ndarray) -> np.ndarray: """Bunge Euler angles to cubochoric vector.""" return Rotation._ho2cu(Rotation._eu2ho(eu)) #---------- Axis angle pair ---------- @staticmethod - def _ax2qu(ax): + def _ax2qu(ax: np.ndarray) -> np.ndarray: """Axis–angle pair to quaternion.""" c = np.cos(ax[...,3:4]*.5) s = np.sin(ax[...,3:4]*.5) @@ -1403,7 +1412,7 @@ class Rotation: return qu @staticmethod - def _ax2om(ax): + def _ax2om(ax: np.ndarray) -> np.ndarray: """Axis-angle pair to rotation matrix.""" c = np.cos(ax[...,3:4]) s = np.sin(ax[...,3:4]) @@ -1420,12 +1429,12 @@ class Rotation: return om if _P < 0.0 else np.swapaxes(om,-1,-2) @staticmethod - def _ax2eu(ax): + def _ax2eu(ax: np.ndarray) -> np.ndarray: """Rotation matrix to Bunge Euler angles.""" return Rotation._om2eu(Rotation._ax2om(ax)) @staticmethod - def _ax2ro(ax): + def _ax2ro(ax: np.ndarray) -> np.ndarray: """Axis–angle pair to Rodrigues–Frank vector.""" ro = np.block([ax[...,:3], np.where(np.isclose(ax[...,3:4],np.pi,atol=1.e-15,rtol=.0), @@ -1436,36 +1445,36 @@ class Rotation: return ro @staticmethod - def _ax2ho(ax): + def _ax2ho(ax: np.ndarray) -> np.ndarray: """Axis–angle pair to homochoric vector.""" f = (0.75 * ( ax[...,3:4] - np.sin(ax[...,3:4]) ))**(1.0/3.0) ho = ax[...,:3] * f return ho @staticmethod - def _ax2cu(ax): + def _ax2cu(ax: np.ndarray) -> np.ndarray: """Axis–angle pair to cubochoric vector.""" return Rotation._ho2cu(Rotation._ax2ho(ax)) #---------- Rodrigues-Frank vector ---------- @staticmethod - def _ro2qu(ro): + def _ro2qu(ro: np.ndarray) -> np.ndarray: """Rodrigues–Frank vector to quaternion.""" return Rotation._ax2qu(Rotation._ro2ax(ro)) @staticmethod - def _ro2om(ro): + def _ro2om(ro: np.ndarray) -> np.ndarray: """Rodgrigues–Frank vector to rotation matrix.""" return Rotation._ax2om(Rotation._ro2ax(ro)) @staticmethod - def _ro2eu(ro): + def _ro2eu(ro: np.ndarray) -> np.ndarray: """Rodrigues–Frank vector to Bunge Euler angles.""" return Rotation._om2eu(Rotation._ro2om(ro)) @staticmethod - def _ro2ax(ro): + def _ro2ax(ro: np.ndarray) -> np.ndarray: """Rodrigues–Frank vector to axis–angle pair.""" with np.errstate(invalid='ignore',divide='ignore'): ax = np.where(np.isfinite(ro[...,3:4]), @@ -1475,7 +1484,7 @@ class Rotation: return ax @staticmethod - def _ro2ho(ro): + def _ro2ho(ro: np.ndarray) -> np.ndarray: """Rodrigues–Frank vector to homochoric vector.""" f = np.where(np.isfinite(ro[...,3:4]),2.0*np.arctan(ro[...,3:4]) -np.sin(2.0*np.arctan(ro[...,3:4])),np.pi) ho = np.where(np.broadcast_to(np.sum(ro[...,0:3]**2.0,axis=-1,keepdims=True) < 1.e-8,ro[...,0:3].shape), @@ -1483,29 +1492,29 @@ class Rotation: return ho @staticmethod - def _ro2cu(ro): + def _ro2cu(ro: np.ndarray) -> np.ndarray: """Rodrigues–Frank vector to cubochoric vector.""" return Rotation._ho2cu(Rotation._ro2ho(ro)) #---------- Homochoric vector---------- @staticmethod - def _ho2qu(ho): + def _ho2qu(ho: np.ndarray) -> np.ndarray: """Homochoric vector to quaternion.""" return Rotation._ax2qu(Rotation._ho2ax(ho)) @staticmethod - def _ho2om(ho): + def _ho2om(ho: np.ndarray) -> np.ndarray: """Homochoric vector to rotation matrix.""" return Rotation._ax2om(Rotation._ho2ax(ho)) @staticmethod - def _ho2eu(ho): + def _ho2eu(ho: np.ndarray) -> np.ndarray: """Homochoric vector to Bunge Euler angles.""" return Rotation._ax2eu(Rotation._ho2ax(ho)) @staticmethod - def _ho2ax(ho): + def _ho2ax(ho: np.ndarray) -> np.ndarray: """Homochoric vector to axis–angle pair.""" tfit = np.array([+1.0000000000018852, -0.5000000002194847, -0.024999992127593126, -0.003928701544781374, @@ -1528,12 +1537,12 @@ class Rotation: return ax @staticmethod - def _ho2ro(ho): + def _ho2ro(ho: np.ndarray) -> np.ndarray: """Axis–angle pair to Rodrigues–Frank vector.""" return Rotation._ax2ro(Rotation._ho2ax(ho)) @staticmethod - def _ho2cu(ho): + def _ho2cu(ho: np.ndarray) -> np.ndarray: """ Homochoric vector to cubochoric vector. @@ -1573,32 +1582,32 @@ class Rotation: #---------- Cubochoric ---------- @staticmethod - def _cu2qu(cu): + def _cu2qu(cu: np.ndarray) -> np.ndarray: """Cubochoric vector to quaternion.""" return Rotation._ho2qu(Rotation._cu2ho(cu)) @staticmethod - def _cu2om(cu): + def _cu2om(cu: np.ndarray) -> np.ndarray: """Cubochoric vector to rotation matrix.""" return Rotation._ho2om(Rotation._cu2ho(cu)) @staticmethod - def _cu2eu(cu): + def _cu2eu(cu: np.ndarray) -> np.ndarray: """Cubochoric vector to Bunge Euler angles.""" return Rotation._ho2eu(Rotation._cu2ho(cu)) @staticmethod - def _cu2ax(cu): + def _cu2ax(cu: np.ndarray) -> np.ndarray: """Cubochoric vector to axis–angle pair.""" return Rotation._ho2ax(Rotation._cu2ho(cu)) @staticmethod - def _cu2ro(cu): + def _cu2ro(cu: np.ndarray) -> np.ndarray: """Cubochoric vector to Rodrigues–Frank vector.""" return Rotation._ho2ro(Rotation._cu2ho(cu)) @staticmethod - def _cu2ho(cu): + def _cu2ho(cu: np.ndarray) -> np.ndarray: """ Cubochoric vector to homochoric vector. @@ -1641,7 +1650,7 @@ class Rotation: @staticmethod - def _get_pyramid_order(xyz,direction=None): + def _get_pyramid_order(xyz: np.ndarray, direction: Literal['forward', 'backward']) -> np.ndarray: """ Get order of the coordinates. From 65633ee6b1f807d5d6b298ed188023eefea88590 Mon Sep 17 00:00:00 2001 From: Daniel Otto de Mentock Date: Tue, 14 Dec 2021 17:19:00 +0100 Subject: [PATCH 02/72] added typehints for rotation.average function [skip ci] --- python/damask/_rotation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index 0a4421090..bf210a852 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -426,7 +426,7 @@ class Rotation: shape+(4,))) - def average(self,weights = None): + def average(self, weights: np.ndarray = None) -> "Rotation": """ Average along last array dimension. From 5702614c4fdc8125dafe064407a774d2281d24ab Mon Sep 17 00:00:00 2001 From: Daniel Otto de Mentock Date: Mon, 3 Jan 2022 15:35:28 +0100 Subject: [PATCH 03/72] expanded rng_seed typehint to array_like type adjusted alpha and beta types for from_fiber_component to also accept lists removed superfluous kwargs argument in from_ODF and from_parallel functions --- python/damask/_rotation.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index bf210a852..aeac3c3e3 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -820,8 +820,7 @@ class Rotation: @staticmethod def from_parallel(a: np.ndarray, - b: np.ndarray, - **kwargs) -> "Rotation": + b: np.ndarray ) -> "Rotation": """ Initialize from pairs of two orthogonal lattice basis vectors. @@ -971,8 +970,7 @@ class Rotation: N: int = 500, degrees: bool = True, fractions: bool = True, - rng_seed: Union[None, int, Sequence[int], np.ndarray] = None, - **kwargs) -> "Rotation": + rng_seed: Union[None, int, Sequence[int], np.ndarray] = None) -> "Rotation": """ Sample discrete values from a binned orientation distribution function (ODF). @@ -1029,7 +1027,7 @@ class Rotation: sigma: float, N: int = 500, degrees: bool = True, - rng_seed: Union[None, int, Sequence[float], np.ndarray] = None) -> "Rotation": + rng_seed: Union[None, int, Sequence[int], np.ndarray] = None) -> "Rotation": """ Calculate set of rotations with Gaussian distribution around center. @@ -1060,12 +1058,12 @@ class Rotation: @staticmethod - def from_fiber_component(alpha: np.ndarray, - beta: np.ndarray, + def from_fiber_component(alpha: Union[Sequence[int], np.ndarray], + beta: Union[Sequence[int], np.ndarray], sigma: float = 0.0, N: int = 500, degrees: bool = True, - rng_seed: bool = None): + rng_seed: Union[None, int, Sequence[int], np.ndarray] = None): """ Calculate set of rotations with Gaussian distribution around direction. From 9a9ec11c29e681cd94f264e7e2a59c73f8bfe5d5 Mon Sep 17 00:00:00 2001 From: Daniel Otto de Mentock Date: Mon, 3 Jan 2022 16:44:27 +0100 Subject: [PATCH 04/72] added generator typehint to from_random function --- python/damask/_rotation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index aeac3c3e3..448917488 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -951,7 +951,7 @@ class Rotation: Defaults to None, i.e. unpredictable entropy will be pulled from the OS. """ - rng = np.random.default_rng(rng_seed) + rng: np.random.Generator = np.random.default_rng(rng_seed) r = rng.random(3 if shape is None else tuple(shape)+(3,) if hasattr(shape, '__iter__') else (shape,3)) A = np.sqrt(r[...,2]) From 0a31ff098050b08f4eb854a228913f1e2c5d0ba5 Mon Sep 17 00:00:00 2001 From: Daniel Otto de Mentock Date: Thu, 6 Jan 2022 14:33:41 +0100 Subject: [PATCH 05/72] added type:ignore statement to broken line --- python/damask/_rotation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index 448917488..d50b25c54 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -952,7 +952,7 @@ class Rotation: """ rng: np.random.Generator = np.random.default_rng(rng_seed) - r = rng.random(3 if shape is None else tuple(shape)+(3,) if hasattr(shape, '__iter__') else (shape,3)) + r = rng.random(3 if shape is None else tuple(shape)+(3,) if hasattr(shape, '__iter__') else (shape,3)) #type: ignore A = np.sqrt(r[...,2]) B = np.sqrt(1.0-r[...,2]) From aabeee9de1aa38ccfe85c3c86c2df778a27f9e2c Mon Sep 17 00:00:00 2001 From: Daniel Otto de Mentock Date: Fri, 14 Jan 2022 14:37:48 +0100 Subject: [PATCH 06/72] Replaced relevant Sequences with FloatSequence and IntSequence types --- python/damask/_orientation.py | 16 +++++++++------- python/damask/_rotation.py | 19 ++++++++++--------- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/python/damask/_orientation.py b/python/damask/_orientation.py index afe4e605d..61c63ed66 100644 --- a/python/damask/_orientation.py +++ b/python/damask/_orientation.py @@ -1,6 +1,5 @@ import inspect import copy -from typing import Union, Callable, Sequence, Dict, Any, Tuple, List import numpy as np @@ -9,6 +8,9 @@ from . import Crystal from . import util from . import tensor +from typing import Union, Callable, Sequence, Dict, Any, Tuple, List +from ._typehints import FloatSequence, IntSequence + _parameter_doc = \ """ @@ -94,7 +96,7 @@ class Orientation(Rotation,Crystal): @util.extend_docstring(_parameter_doc) def __init__(self, - rotation: Union[Sequence[float], np.ndarray, Rotation] = np.array([1.,0.,0.,0.]), *, + rotation: Union[FloatSequence, Rotation] = np.array([1.,0.,0.,0.]), *, family: str = None, lattice: str = None, a: float = None, b: float = None, c: float = None, @@ -121,7 +123,7 @@ class Orientation(Rotation,Crystal): return '\n'.join([Crystal.__repr__(self), Rotation.__repr__(self)]) - def __copy__(self,rotation: Union[Sequence[float], np.ndarray, Rotation] = None) -> "Orientation": + def __copy__(self,rotation: Union[FloatSequence, Rotation] = None) -> "Orientation": """Create deep copy.""" dup = copy.deepcopy(self) if rotation is not None: @@ -360,8 +362,8 @@ class Orientation(Rotation,Crystal): @classmethod @util.extend_docstring(_parameter_doc) def from_directions(cls, - uvw: Union[Sequence[float], np.ndarray], - hkl: Union[Sequence[float], np.ndarray], + uvw: FloatSequence, + hkl: FloatSequence, **kwargs) -> "Orientation": """ Initialize orientation object from two crystallographic directions. @@ -874,8 +876,8 @@ class Orientation(Rotation,Crystal): def Schmid(self, *, - N_slip: Sequence[int] = None, - N_twin: Sequence[int] = None) -> np.ndarray: + N_slip: IntSequence = None, + N_twin: IntSequence = None) -> np.ndarray: u""" Calculate Schmid matrix P = d ⨂ n in the lab frame for selected deformation systems. diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index a0bf15e88..fa4f2ec14 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -7,6 +7,7 @@ from . import util from . import grid_filters from typing import Union, Sequence, Tuple, Literal, List +from ._typehints import FloatSequence, IntSequence _P = -1 @@ -63,7 +64,7 @@ class Rotation: __slots__ = ['quaternion'] - def __init__(self, rotation: Union[Sequence[float], np.ndarray, "Rotation"] = np.array([1.0,0.0,0.0,0.0])): + def __init__(self, rotation: Union[FloatSequence, "Rotation"] = np.array([1.0,0.0,0.0,0.0])): """ New rotation. @@ -90,7 +91,7 @@ class Rotation: + str(self.quaternion) - def __copy__(self, rotation: Union[Sequence[float], np.ndarray, "Rotation"] = None) -> "Rotation": + def __copy__(self, rotation: Union[FloatSequence, "Rotation"] = None) -> "Rotation": """Create deep copy.""" dup = copy.deepcopy(self) if rotation is not None: @@ -668,7 +669,7 @@ class Rotation: # Static constructors. The input data needs to follow the conventions, options allow to # relax the conventions. @staticmethod - def from_quaternion(q: Union[Sequence[Sequence[float]], np.ndarray], + def from_quaternion(q: Union[Sequence[FloatSequence], np.ndarray], accept_homomorph: bool = False, P: Literal[1, -1] = -1) -> "Rotation": """ @@ -936,7 +937,7 @@ class Rotation: @staticmethod def from_random(shape: Tuple[int, ...] = None, - rng_seed: Union[None, int, Sequence[int], np.ndarray] = None) -> "Rotation": + rng_seed: Union[int, IntSequence] = None) -> "Rotation": """ Initialize with random rotation. @@ -970,7 +971,7 @@ class Rotation: N: int = 500, degrees: bool = True, fractions: bool = True, - rng_seed: Union[None, int, Sequence[int], np.ndarray] = None) -> "Rotation": + rng_seed: Union[None, int, IntSequence] = None) -> "Rotation": """ Sample discrete values from a binned orientation distribution function (ODF). @@ -1027,7 +1028,7 @@ class Rotation: sigma: float, N: int = 500, degrees: bool = True, - rng_seed: Union[None, int, Sequence[int], np.ndarray] = None) -> "Rotation": + rng_seed: Union[None, int, IntSequence] = None) -> "Rotation": """ Calculate set of rotations with Gaussian distribution around center. @@ -1058,12 +1059,12 @@ class Rotation: @staticmethod - def from_fiber_component(alpha: Union[Sequence[int], np.ndarray], - beta: Union[Sequence[int], np.ndarray], + def from_fiber_component(alpha: IntSequence, + beta: IntSequence, sigma: float = 0.0, N: int = 500, degrees: bool = True, - rng_seed: Union[None, int, Sequence[int], np.ndarray] = None): + rng_seed: Union[int, IntSequence] = None): """ Calculate set of rotations with Gaussian distribution around direction. From 25513d572bacc2d65073e0199a917f6769ccf99a Mon Sep 17 00:00:00 2001 From: Daniel Otto de Mentock Date: Fri, 14 Jan 2022 14:55:08 +0100 Subject: [PATCH 07/72] minor type adjustment to rotation module removed superfluous Sequence type from orientation module --- python/damask/_orientation.py | 2 +- python/damask/_rotation.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/python/damask/_orientation.py b/python/damask/_orientation.py index 61c63ed66..3a1154a64 100644 --- a/python/damask/_orientation.py +++ b/python/damask/_orientation.py @@ -8,7 +8,7 @@ from . import Crystal from . import util from . import tensor -from typing import Union, Callable, Sequence, Dict, Any, Tuple, List +from typing import Union, Callable, Dict, Any, Tuple, List from ._typehints import FloatSequence, IntSequence diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index fa4f2ec14..17369c36a 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -535,7 +535,7 @@ class Rotation: def as_axis_angle(self, degrees: bool = False, - pair: bool = False) -> Union[Tuple[float, ...], np.ndarray]: + pair: bool = False) -> Union[Tuple[np.ndarray, np.ndarray], np.ndarray]: """ Represent as axis–angle pair. From 0fe51f58a8686e6ab56d4297eda5a7e64971f229 Mon Sep 17 00:00:00 2001 From: Daniel Otto de Mentock Date: Wed, 26 Jan 2022 15:09:09 +0100 Subject: [PATCH 08/72] [skip ci] changed almost all function definition lines to multiline --- python/damask/_orientation.py | 35 ++++++++++++++++++------- python/damask/_rotation.py | 49 +++++++++++++++++++++++++---------- 2 files changed, 60 insertions(+), 24 deletions(-) diff --git a/python/damask/_orientation.py b/python/damask/_orientation.py index 3a1154a64..35de041f8 100644 --- a/python/damask/_orientation.py +++ b/python/damask/_orientation.py @@ -123,7 +123,8 @@ class Orientation(Rotation,Crystal): return '\n'.join([Crystal.__repr__(self), Rotation.__repr__(self)]) - def __copy__(self,rotation: Union[FloatSequence, Rotation] = None) -> "Orientation": + def __copy__(self, + rotation: Union[FloatSequence, Rotation] = None) -> "Orientation": """Create deep copy.""" dup = copy.deepcopy(self) if rotation is not None: @@ -134,7 +135,8 @@ class Orientation(Rotation,Crystal): - def __eq__(self, other: object) -> bool: + def __eq__(self, + other: object) -> bool: """ Equal to other. @@ -151,7 +153,8 @@ class Orientation(Rotation,Crystal): self.parameters == other.parameters return np.logical_and(matching_type,super(self.__class__,self.reduced).__eq__(other.reduced)) - def __ne__(self, other: object) -> bool: + def __ne__(self, + other: object) -> bool: """ Not equal to other. @@ -230,7 +233,8 @@ class Orientation(Rotation,Crystal): return np.all(self.isclose(other,rtol,atol,equal_nan)) - def __mul__(self, other: Union[Rotation, "Orientation"]) -> "Orientation": + def __mul__(self, + other: Union[Rotation, "Orientation"]) -> "Orientation": """ Compose this orientation with other. @@ -252,7 +256,8 @@ class Orientation(Rotation,Crystal): @staticmethod - def _split_kwargs(kwargs: Dict[str, Any], target: Callable) -> Tuple[Dict[str, Any], ...]: + def _split_kwargs(kwargs: Dict[str, Any], + target: Callable) -> Tuple[Dict[str, Any], ...]: """ Separate keyword arguments in 'kwargs' targeted at 'target' from general keyword arguments of Orientation objects. @@ -492,7 +497,9 @@ class Orientation(Rotation,Crystal): else: return np.ones_like(rho[...,0],dtype=bool) - def disorientation(self, other, return_operators = False): + def disorientation(self, + other, + return_operators = False): """ Calculate disorientation between myself and given other orientation. @@ -576,7 +583,9 @@ class Orientation(Rotation,Crystal): ) - def average(self, weights = None, return_cloud = False): + def average(self, + weights = None, + return_cloud = False): """ Return orientation average over last dimension. @@ -659,7 +668,9 @@ class Orientation(Rotation,Crystal): ) - def in_SST(self, vector: np.ndarray, proper: bool = False) -> Union[np.bool_, np.ndarray]: + def in_SST(self, + vector: np.ndarray, + proper: bool = False) -> Union[np.bool_, np.ndarray]: """ Check whether given crystal frame vector falls into standard stereographic triangle of own symmetry. @@ -700,7 +711,10 @@ class Orientation(Rotation,Crystal): return np.all(components >= 0.0,axis=-1) - def IPF_color(self, vector: np.ndarray, in_SST: bool = True, proper: bool = False) -> np.ndarray: + def IPF_color(self, + vector: np.ndarray, + in_SST: bool = True, + proper: bool = False) -> np.ndarray: """ Map vector to RGB color within standard stereographic triangle of own symmetry. @@ -925,7 +939,8 @@ class Orientation(Rotation,Crystal): @ np.broadcast_to(P.reshape(util.shapeshifter(P.shape,shape)),shape) - def related(self, model: str) -> "Orientation": + def related(self, + model: str) -> "Orientation": """ Orientations derived from the given relationship. diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index 17369c36a..3266f4f41 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -64,7 +64,8 @@ class Rotation: __slots__ = ['quaternion'] - def __init__(self, rotation: Union[FloatSequence, "Rotation"] = np.array([1.0,0.0,0.0,0.0])): + def __init__(self, + rotation: Union[FloatSequence, "Rotation"] = np.array([1.0,0.0,0.0,0.0])): """ New rotation. @@ -91,7 +92,8 @@ class Rotation: + str(self.quaternion) - def __copy__(self, rotation: Union[FloatSequence, "Rotation"] = None) -> "Rotation": + def __copy__(self, + rotation: Union[FloatSequence, "Rotation"] = None) -> "Rotation": """Create deep copy.""" dup = copy.deepcopy(self) if rotation is not None: @@ -101,7 +103,8 @@ class Rotation: copy = __copy__ - def __getitem__(self, item: Union[Tuple[int], int, bool, np.bool_, np.ndarray]): + def __getitem__(self, + item: Union[Tuple[int], int, bool, np.bool_, np.ndarray]): """Return slice according to item.""" return self.copy() \ if self.shape == () else \ @@ -139,7 +142,11 @@ class Rotation: return np.logical_not(self==other) - def isclose(self, other: "Rotation", rtol: float = 1e-5, atol: float = 1e-8, equal_nan: bool = True) -> bool: + def isclose(self, + other: "Rotation", + rtol: float = 1e-5, + atol: float = 1e-8, + equal_nan: bool = True) -> bool: """ Report where values are approximately equal to corresponding ones of other Rotation. @@ -166,7 +173,11 @@ class Rotation: np.all(np.isclose(s,-1.0*o,rtol,atol,equal_nan),axis=-1)) - def allclose(self, other: "Rotation", rtol: float = 1e-5, atol: float = 1e-8, equal_nan: bool = True) -> Union[np.bool_, bool]: + def allclose(self, + other: "Rotation", + rtol: float = 1e-5, + atol: float = 1e-8, + equal_nan: bool = True) -> Union[np.bool_, bool]: """ Test whether all values are approximately equal to corresponding ones of other Rotation. @@ -330,7 +341,7 @@ class Rotation: Rotated vector or tensor, i.e. transformed to frame defined by rotation. """ - if isinstance(other,np.ndarray): + if isinstance(other, np.ndarray): if self.shape + (3,) == other.shape: q_m = self.quaternion[...,0] p_m = self.quaternion[...,1:] @@ -350,7 +361,7 @@ class Rotation: return np.einsum('...im,...jn,...ko,...lp,...mnop',R,R,R,R,other) else: raise ValueError('Can only rotate vectors, 2nd order tensors, and 4th order tensors') - elif isinstance(other,Rotation): + elif isinstance(other, Rotation): raise TypeError('Use "R1*R2", i.e. multiplication, to compose rotations "R1" and "R2"') else: raise TypeError(f'Cannot rotate {type(other)}') @@ -364,7 +375,9 @@ class Rotation: return self - def append(self, other: Union["Rotation", List["Rotation"]]) -> "Rotation": + def append(self, + other: Union["Rotation", + List["Rotation"]]) -> "Rotation": """ Extend array along first dimension with other array(s). @@ -377,7 +390,8 @@ class Rotation: [self]+other if isinstance(other,list) else [self,other])))) - def flatten(self, order: Literal['C','F','A'] = 'C') -> "Rotation": + def flatten(self, + order: Literal['C','F','A'] = 'C') -> "Rotation": """ Flatten array. @@ -390,7 +404,9 @@ class Rotation: return self.copy(rotation=self.quaternion.reshape((-1,4),order=order)) - def reshape(self,shape: Union[int, Tuple[int, ...]], order: Literal['C','F','A'] = 'C') -> "Rotation": + def reshape(self, + shape: Union[int, Tuple[int, ...]], + order: Literal['C','F','A'] = 'C') -> "Rotation": """ Reshape array. @@ -404,7 +420,9 @@ class Rotation: return self.copy(rotation=self.quaternion.reshape(tuple(shape)+(4,),order=order)) - def broadcast_to(self, shape: Union[int, Tuple[int, ...]], mode: Literal["left", "right"] = 'right') -> "Rotation": + def broadcast_to(self, + shape: Union[int, Tuple[int, ...]], + mode: Literal["left", "right"] = 'right') -> "Rotation": """ Broadcast array. @@ -427,7 +445,8 @@ class Rotation: shape+(4,))) - def average(self, weights: np.ndarray = None) -> "Rotation": + def average(self, + weights: np.ndarray = None) -> "Rotation": """ Average along last array dimension. @@ -466,7 +485,8 @@ class Rotation: accept_homomorph = True) - def misorientation(self, other: "Rotation") -> "Rotation": + def misorientation(self, + other: "Rotation") -> "Rotation": """ Calculate misorientation to other Rotation. @@ -1649,7 +1669,8 @@ class Rotation: @staticmethod - def _get_pyramid_order(xyz: np.ndarray, direction: Literal['forward', 'backward']) -> np.ndarray: + def _get_pyramid_order(xyz: np.ndarray, + direction: Literal['forward', 'backward']) -> np.ndarray: """ Get order of the coordinates. From 81ef865525f12c57c3f8ec3e92cf67ef1d55b56a Mon Sep 17 00:00:00 2001 From: Daniel Otto de Mentock Date: Fri, 28 Jan 2022 10:11:34 +0100 Subject: [PATCH 09/72] [skip ci] moved asterisk to seperate line --- python/damask/_orientation.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/python/damask/_orientation.py b/python/damask/_orientation.py index 35de041f8..f84ca9952 100644 --- a/python/damask/_orientation.py +++ b/python/damask/_orientation.py @@ -96,7 +96,8 @@ class Orientation(Rotation,Crystal): @util.extend_docstring(_parameter_doc) def __init__(self, - rotation: Union[FloatSequence, Rotation] = np.array([1.,0.,0.,0.]), *, + rotation: Union[FloatSequence, Rotation] = np.array([1.,0.,0.,0.]), + *, family: str = None, lattice: str = None, a: float = None, b: float = None, c: float = None, From 92ac01848614450d80a1d0d8e8b262cdb5e96c99 Mon Sep 17 00:00:00 2001 From: Daniel Otto de Mentock Date: Fri, 28 Jan 2022 13:34:42 +0100 Subject: [PATCH 10/72] removed superfluous break in function definition in rotation --- python/damask/_rotation.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index 3266f4f41..676df5c03 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -376,8 +376,7 @@ class Rotation: def append(self, - other: Union["Rotation", - List["Rotation"]]) -> "Rotation": + other: Union["Rotation", List["Rotation"]]) -> "Rotation": """ Extend array along first dimension with other array(s). From 53a0de2271c2ea33618aa733b64e0118de4fc83c Mon Sep 17 00:00:00 2001 From: Daniel Otto de Mentock Date: Fri, 28 Jan 2022 13:40:37 +0100 Subject: [PATCH 11/72] Adjusted docstrings in rotation rewrote map(np.radians()) line to one line tuple --- python/damask/_rotation.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index 676df5c03..468fef2c5 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -382,7 +382,7 @@ class Rotation: Parameters ---------- - other : damask.Rotation + other : (list of) damask.Rotation """ return self.copy(rotation=np.vstack(tuple(map(lambda x:x.quaternion, @@ -427,7 +427,7 @@ class Rotation: Parameters ---------- - shape : tuple + shape : int, tuple Shape of broadcasted array. mode : str, optional Where to preferentially locate missing dimensions. @@ -451,7 +451,7 @@ class Rotation: Parameters ---------- - weights : list of floats, optional + weights : numpy.ndarray, optional Relative weight of each rotation. Returns @@ -1107,7 +1107,7 @@ class Rotation: """ rng = np.random.default_rng(rng_seed) sigma_: np.ndarray; alpha_: np.ndarray; beta_: np.ndarray - sigma_,alpha_,beta_ = map(np.radians,(sigma,alpha,beta)) if degrees else (sigma,alpha,beta) # type: ignore + sigma_,alpha_,beta_ = (np.radians(coordinate for coordinate in (sigma,alpha,beta))) if degrees else (sigma,alpha,beta) #type: ignore d_cr = np.array([np.sin(alpha_[0])*np.cos(alpha_[1]), np.sin(alpha_[0])*np.sin(alpha_[1]), np.cos(alpha_[0])]) d_lab = np.array([np.sin( beta_[0])*np.cos( beta_[1]), np.sin( beta_[0])*np.sin( beta_[1]), np.cos( beta_[0])]) From 33731e4948078e79f6710bdbc979730ecb3a7997 Mon Sep 17 00:00:00 2001 From: Daniel Otto de Mentock Date: Fri, 28 Jan 2022 15:15:20 +0100 Subject: [PATCH 12/72] adjusted bracket error in from_fiber_component --- python/damask/_rotation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index 468fef2c5..b55f178f7 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -1107,7 +1107,7 @@ class Rotation: """ rng = np.random.default_rng(rng_seed) sigma_: np.ndarray; alpha_: np.ndarray; beta_: np.ndarray - sigma_,alpha_,beta_ = (np.radians(coordinate for coordinate in (sigma,alpha,beta))) if degrees else (sigma,alpha,beta) #type: ignore + sigma_,alpha_,beta_ = (np.radians(coordinate) for coordinate in (sigma,alpha,beta)) if degrees else (sigma,alpha,beta) #type: ignore d_cr = np.array([np.sin(alpha_[0])*np.cos(alpha_[1]), np.sin(alpha_[0])*np.sin(alpha_[1]), np.cos(alpha_[0])]) d_lab = np.array([np.sin( beta_[0])*np.cos( beta_[1]), np.sin( beta_[0])*np.sin( beta_[1]), np.cos( beta_[0])]) From cb1143a47215d8327085cd975e45135b42fd9e57 Mon Sep 17 00:00:00 2001 From: Daniel Otto de Mentock Date: Tue, 1 Feb 2022 18:38:49 +0100 Subject: [PATCH 13/72] changed return type of util.shapeblender and util.shapeshifter from Sequence[SupportsIndex] to Tuple[SupportsIndex, ...] ignored lines in orientation module that attempt to pass objects of type Tuple[SupportsIndex, ...] to np.broadcast_to() --- python/damask/_orientation.py | 5 ++--- python/damask/util.py | 6 +++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/python/damask/_orientation.py b/python/damask/_orientation.py index f84ca9952..d1488c14e 100644 --- a/python/damask/_orientation.py +++ b/python/damask/_orientation.py @@ -657,7 +657,7 @@ class Orientation(Rotation,Crystal): """ eq = self.equivalent blend = util.shapeblender(eq.shape,np.array(vector).shape[:-1]) - poles = eq.broadcast_to(blend,mode='right') @ np.broadcast_to(np.array(vector),blend+(3,)) + poles = eq.broadcast_to(blend,mode='right') @ np.broadcast_to(np.array(vector),blend+(3,)) #type: ignore ok = self.in_SST(poles,proper=proper) ok &= np.cumsum(ok,axis=0) == 1 loc = np.where(ok) @@ -886,8 +886,7 @@ class Orientation(Rotation,Crystal): blend += sym_ops.shape v = sym_ops.broadcast_to(shape) \ @ np.broadcast_to(v.reshape(util.shapeshifter(v.shape,shape+(3,))),shape+(3,)) - return ~(self.broadcast_to(blend)) \ - @ np.broadcast_to(v,blend+(3,)) + return ~(self.broadcast_to(blend))@ np.broadcast_to(v,blend+(3,)) #type: ignore def Schmid(self, *, diff --git a/python/damask/util.py b/python/damask/util.py index b4c287884..3b0af7177 100644 --- a/python/damask/util.py +++ b/python/damask/util.py @@ -9,7 +9,7 @@ import re import fractions from collections import abc from functools import reduce -from typing import Union, Tuple, Iterable, Callable, Dict, List, Any, Literal, SupportsIndex, Sequence +from typing import Union, Tuple, Iterable, Callable, Dict, List, Any, Literal, SupportsIndex from pathlib import Path import numpy as np @@ -427,7 +427,7 @@ def hybrid_IA(dist: np.ndarray, def shapeshifter(fro: Tuple[int, ...], to: Tuple[int, ...], mode: Literal['left','right'] = 'left', - keep_ones: bool = False) -> Sequence[SupportsIndex]: + keep_ones: bool = False) -> Tuple[SupportsIndex, ...]: """ Return dimensions that reshape 'fro' to become broadcastable to 'to'. @@ -490,7 +490,7 @@ def shapeshifter(fro: Tuple[int, ...], def shapeblender(a: Tuple[int, ...], - b: Tuple[int, ...]) -> Sequence[SupportsIndex]: + b: Tuple[int, ...]) -> Tuple[SupportsIndex, ...]: """ Return a shape that overlaps the rightmost entries of 'a' with the leftmost of 'b'. From 71bc92fed054539fde49c6dee208f72a0d2bd0dc Mon Sep 17 00:00:00 2001 From: Daniel Otto de Mentock Date: Wed, 2 Feb 2022 11:11:59 +0100 Subject: [PATCH 14/72] changed quote layout to single quote Added NotImplemented returnvalue to __eq__ functions --- python/damask/_orientation.py | 36 +++++++++---------- python/damask/_rotation.py | 66 +++++++++++++++++------------------ 2 files changed, 51 insertions(+), 51 deletions(-) diff --git a/python/damask/_orientation.py b/python/damask/_orientation.py index d1488c14e..8a560e756 100644 --- a/python/damask/_orientation.py +++ b/python/damask/_orientation.py @@ -125,7 +125,7 @@ class Orientation(Rotation,Crystal): Rotation.__repr__(self)]) def __copy__(self, - rotation: Union[FloatSequence, Rotation] = None) -> "Orientation": + rotation: Union[FloatSequence, Rotation] = None) -> 'Orientation': """Create deep copy.""" dup = copy.deepcopy(self) if rotation is not None: @@ -148,7 +148,7 @@ class Orientation(Rotation,Crystal): """ if not isinstance(other, Orientation): - raise TypeError + raise NotImplemented matching_type = self.family == other.family and \ self.lattice == other.lattice and \ self.parameters == other.parameters @@ -235,7 +235,7 @@ class Orientation(Rotation,Crystal): def __mul__(self, - other: Union[Rotation, "Orientation"]) -> "Orientation": + other: Union[Rotation, 'Orientation']) -> 'Orientation': """ Compose this orientation with other. @@ -290,77 +290,77 @@ class Orientation(Rotation,Crystal): @classmethod @util.extended_docstring(Rotation.from_random, _parameter_doc) - def from_random(cls, **kwargs) -> "Orientation": + def from_random(cls, **kwargs) -> 'Orientation': kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_random) return cls(rotation=Rotation.from_random(**kwargs_rot),**kwargs_ori) @classmethod @util.extended_docstring(Rotation.from_quaternion,_parameter_doc) - def from_quaternion(cls, **kwargs) -> "Orientation": + def from_quaternion(cls, **kwargs) -> 'Orientation': kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_quaternion) return cls(rotation=Rotation.from_quaternion(**kwargs_rot),**kwargs_ori) @classmethod @util.extended_docstring(Rotation.from_Euler_angles,_parameter_doc) - def from_Euler_angles(cls, **kwargs) -> "Orientation": + def from_Euler_angles(cls, **kwargs) -> 'Orientation': kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_Euler_angles) return cls(rotation=Rotation.from_Euler_angles(**kwargs_rot),**kwargs_ori) @classmethod @util.extended_docstring(Rotation.from_axis_angle,_parameter_doc) - def from_axis_angle(cls, **kwargs) -> "Orientation": + def from_axis_angle(cls, **kwargs) -> 'Orientation': kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_axis_angle) return cls(rotation=Rotation.from_axis_angle(**kwargs_rot),**kwargs_ori) @classmethod @util.extended_docstring(Rotation.from_basis,_parameter_doc) - def from_basis(cls, **kwargs) -> "Orientation": + def from_basis(cls, **kwargs) -> 'Orientation': kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_basis) return cls(rotation=Rotation.from_basis(**kwargs_rot),**kwargs_ori) @classmethod @util.extended_docstring(Rotation.from_matrix,_parameter_doc) - def from_matrix(cls, **kwargs) -> "Orientation": + def from_matrix(cls, **kwargs) -> 'Orientation': kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_matrix) return cls(rotation=Rotation.from_matrix(**kwargs_rot),**kwargs_ori) @classmethod @util.extended_docstring(Rotation.from_Rodrigues_vector,_parameter_doc) - def from_Rodrigues_vector(cls, **kwargs) -> "Orientation": + def from_Rodrigues_vector(cls, **kwargs) -> 'Orientation': kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_Rodrigues_vector) return cls(rotation=Rotation.from_Rodrigues_vector(**kwargs_rot),**kwargs_ori) @classmethod @util.extended_docstring(Rotation.from_homochoric,_parameter_doc) - def from_homochoric(cls, **kwargs) -> "Orientation": + def from_homochoric(cls, **kwargs) -> 'Orientation': kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_homochoric) return cls(rotation=Rotation.from_homochoric(**kwargs_rot),**kwargs_ori) @classmethod @util.extended_docstring(Rotation.from_cubochoric,_parameter_doc) - def from_cubochoric(cls, **kwargs) -> "Orientation": + def from_cubochoric(cls, **kwargs) -> 'Orientation': kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_cubochoric) return cls(rotation=Rotation.from_cubochoric(**kwargs_rot),**kwargs_ori) @classmethod @util.extended_docstring(Rotation.from_spherical_component,_parameter_doc) - def from_spherical_component(cls, **kwargs) -> "Orientation": + def from_spherical_component(cls, **kwargs) -> 'Orientation': kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_spherical_component) return cls(rotation=Rotation.from_spherical_component(**kwargs_rot),**kwargs_ori) @classmethod @util.extended_docstring(Rotation.from_fiber_component,_parameter_doc) - def from_fiber_component(cls, **kwargs) -> "Orientation": + def from_fiber_component(cls, **kwargs) -> 'Orientation': kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_fiber_component) return cls(rotation=Rotation.from_fiber_component(**kwargs_rot),**kwargs_ori) @@ -370,7 +370,7 @@ class Orientation(Rotation,Crystal): def from_directions(cls, uvw: FloatSequence, hkl: FloatSequence, - **kwargs) -> "Orientation": + **kwargs) -> 'Orientation': """ Initialize orientation object from two crystallographic directions. @@ -390,7 +390,7 @@ class Orientation(Rotation,Crystal): @property - def equivalent(self) -> "Orientation": + def equivalent(self) -> 'Orientation': """ Orientations that are symmetrically equivalent. @@ -404,7 +404,7 @@ class Orientation(Rotation,Crystal): @property - def reduced(self) -> "Orientation": + def reduced(self) -> 'Orientation': """Select symmetrically equivalent orientation that falls into fundamental zone according to symmetry.""" eq = self.equivalent ok = eq.in_FZ @@ -940,7 +940,7 @@ class Orientation(Rotation,Crystal): def related(self, - model: str) -> "Orientation": + model: str) -> 'Orientation': """ Orientations derived from the given relationship. diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index b55f178f7..6e01cae65 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -65,7 +65,7 @@ class Rotation: __slots__ = ['quaternion'] def __init__(self, - rotation: Union[FloatSequence, "Rotation"] = np.array([1.0,0.0,0.0,0.0])): + rotation: Union[FloatSequence, 'Rotation'] = np.array([1.0,0.0,0.0,0.0])): """ New rotation. @@ -83,7 +83,7 @@ class Rotation: elif np.array(rotation).shape[-1] == 4: self.quaternion = np.array(rotation) else: - raise TypeError('"rotation" is neither a Rotation nor a quaternion') + raise TypeError('Rotation is neither a Rotation nor a quaternion') def __repr__(self) -> str: @@ -93,7 +93,7 @@ class Rotation: def __copy__(self, - rotation: Union[FloatSequence, "Rotation"] = None) -> "Rotation": + rotation: Union[FloatSequence, 'Rotation'] = None) -> 'Rotation': """Create deep copy.""" dup = copy.deepcopy(self) if rotation is not None: @@ -122,7 +122,7 @@ class Rotation: """ if not isinstance(other, Rotation): - raise TypeError + return NotImplemented return np.logical_or(np.all(self.quaternion == other.quaternion,axis=-1), np.all(self.quaternion == -1.0*other.quaternion,axis=-1)) @@ -143,7 +143,7 @@ class Rotation: def isclose(self, - other: "Rotation", + other: 'Rotation', rtol: float = 1e-5, atol: float = 1e-8, equal_nan: bool = True) -> bool: @@ -174,7 +174,7 @@ class Rotation: def allclose(self, - other: "Rotation", + other: 'Rotation', rtol: float = 1e-5, atol: float = 1e-8, equal_nan: bool = True) -> Union[np.bool_, bool]: @@ -220,14 +220,14 @@ class Rotation: return 0 if self.shape == () else self.shape[0] - def __invert__(self) -> "Rotation": + def __invert__(self) -> 'Rotation': """Inverse rotation (backward rotation).""" dup = self.copy() dup.quaternion[...,1:] *= -1 return dup - def __pow__(self, exp: int) -> "Rotation": + def __pow__(self, exp: int) -> 'Rotation': """ Perform the rotation 'exp' times. @@ -241,7 +241,7 @@ class Rotation: p = self.quaternion[...,1:]/np.linalg.norm(self.quaternion[...,1:],axis=-1,keepdims=True) return self.copy(rotation=Rotation(np.block([np.cos(exp*phi),np.sin(exp*phi)*p]))._standardize()) - def __ipow__(self, exp: int) -> "Rotation": + def __ipow__(self, exp: int) -> 'Rotation': """ Perform the rotation 'exp' times (in-place). @@ -254,7 +254,7 @@ class Rotation: return self**exp - def __mul__(self, other: "Rotation") -> "Rotation": + def __mul__(self, other: 'Rotation') -> 'Rotation': """ Compose with other. @@ -280,7 +280,7 @@ class Rotation: else: raise TypeError('Use "R@b", i.e. matmul, to apply rotation "R" to object "b"') - def __imul__(self, other: "Rotation") -> "Rotation": + def __imul__(self, other: 'Rotation') -> 'Rotation': """ Compose with other (in-place). @@ -293,7 +293,7 @@ class Rotation: return self*other - def __truediv__(self, other: "Rotation") -> "Rotation": + def __truediv__(self, other: 'Rotation') -> 'Rotation': """ Compose with inverse of other. @@ -313,7 +313,7 @@ class Rotation: else: raise TypeError('Use "R@b", i.e. matmul, to apply rotation "R" to object "b"') - def __itruediv__(self, other: "Rotation") -> "Rotation": + def __itruediv__(self, other: 'Rotation') -> 'Rotation': """ Compose with inverse of other (in-place). @@ -369,14 +369,14 @@ class Rotation: apply = __matmul__ - def _standardize(self) -> "Rotation": + def _standardize(self) -> 'Rotation': """Standardize quaternion (ensure positive real hemisphere).""" self.quaternion[self.quaternion[...,0] < 0.0] *= -1 return self def append(self, - other: Union["Rotation", List["Rotation"]]) -> "Rotation": + other: Union['Rotation', List['Rotation']]) -> 'Rotation': """ Extend array along first dimension with other array(s). @@ -390,7 +390,7 @@ class Rotation: def flatten(self, - order: Literal['C','F','A'] = 'C') -> "Rotation": + order: Literal['C','F','A'] = 'C') -> 'Rotation': """ Flatten array. @@ -405,7 +405,7 @@ class Rotation: def reshape(self, shape: Union[int, Tuple[int, ...]], - order: Literal['C','F','A'] = 'C') -> "Rotation": + order: Literal['C','F','A'] = 'C') -> 'Rotation': """ Reshape array. @@ -421,7 +421,7 @@ class Rotation: def broadcast_to(self, shape: Union[int, Tuple[int, ...]], - mode: Literal["left", "right"] = 'right') -> "Rotation": + mode: Literal['left', 'right'] = 'right') -> 'Rotation': """ Broadcast array. @@ -445,7 +445,7 @@ class Rotation: def average(self, - weights: np.ndarray = None) -> "Rotation": + weights: np.ndarray = None) -> 'Rotation': """ Average along last array dimension. @@ -485,7 +485,7 @@ class Rotation: def misorientation(self, - other: "Rotation") -> "Rotation": + other: 'Rotation') -> 'Rotation': """ Calculate misorientation to other Rotation. @@ -690,7 +690,7 @@ class Rotation: @staticmethod def from_quaternion(q: Union[Sequence[FloatSequence], np.ndarray], accept_homomorph: bool = False, - P: Literal[1, -1] = -1) -> "Rotation": + P: Literal[1, -1] = -1) -> 'Rotation': """ Initialize from quaternion. @@ -724,7 +724,7 @@ class Rotation: @staticmethod def from_Euler_angles(phi: np.ndarray, - degrees: bool = False) -> "Rotation": + degrees: bool = False) -> 'Rotation': """ Initialize from Bunge Euler angles. @@ -755,7 +755,7 @@ class Rotation: def from_axis_angle(axis_angle: np.ndarray, degrees:bool = False, normalize: bool = False, - P: Literal[1, -1] = -1) -> "Rotation": + P: Literal[1, -1] = -1) -> 'Rotation': """ Initialize from Axis angle pair. @@ -792,7 +792,7 @@ class Rotation: @staticmethod def from_basis(basis: np.ndarray, orthonormal: bool = True, - reciprocal: bool = False) -> "Rotation": + reciprocal: bool = False) -> 'Rotation': """ Initialize from lattice basis vectors. @@ -826,7 +826,7 @@ class Rotation: return Rotation(Rotation._om2qu(om)) @staticmethod - def from_matrix(R: np.ndarray) -> "Rotation": + def from_matrix(R: np.ndarray) -> 'Rotation': """ Initialize from rotation matrix. @@ -840,7 +840,7 @@ class Rotation: @staticmethod def from_parallel(a: np.ndarray, - b: np.ndarray ) -> "Rotation": + b: np.ndarray ) -> 'Rotation': """ Initialize from pairs of two orthogonal lattice basis vectors. @@ -870,7 +870,7 @@ class Rotation: @staticmethod def from_Rodrigues_vector(rho: np.ndarray, normalize: bool = False, - P: Literal[1, -1] = -1) -> "Rotation": + P: Literal[1, -1] = -1) -> 'Rotation': """ Initialize from Rodrigues–Frank vector (angle separated from axis). @@ -901,7 +901,7 @@ class Rotation: @staticmethod def from_homochoric(h: np.ndarray, - P: Literal[1, -1] = -1) -> "Rotation": + P: Literal[1, -1] = -1) -> 'Rotation': """ Initialize from homochoric vector. @@ -928,7 +928,7 @@ class Rotation: @staticmethod def from_cubochoric(x: np.ndarray, - P: Literal[1, -1] = -1) -> "Rotation": + P: Literal[1, -1] = -1) -> 'Rotation': """ Initialize from cubochoric vector. @@ -956,7 +956,7 @@ class Rotation: @staticmethod def from_random(shape: Tuple[int, ...] = None, - rng_seed: Union[int, IntSequence] = None) -> "Rotation": + rng_seed: Union[int, IntSequence] = None) -> 'Rotation': """ Initialize with random rotation. @@ -990,7 +990,7 @@ class Rotation: N: int = 500, degrees: bool = True, fractions: bool = True, - rng_seed: Union[None, int, IntSequence] = None) -> "Rotation": + rng_seed: Union[None, int, IntSequence] = None) -> 'Rotation': """ Sample discrete values from a binned orientation distribution function (ODF). @@ -1043,11 +1043,11 @@ class Rotation: @staticmethod - def from_spherical_component(center: "Rotation", + def from_spherical_component(center: 'Rotation', sigma: float, N: int = 500, degrees: bool = True, - rng_seed: Union[None, int, IntSequence] = None) -> "Rotation": + rng_seed: Union[None, int, IntSequence] = None) -> 'Rotation': """ Calculate set of rotations with Gaussian distribution around center. From 3df411469b5cf2a68a845e54bfa6affa1d45f7fb Mon Sep 17 00:00:00 2001 From: Daniel Otto de Mentock Date: Wed, 2 Feb 2022 12:14:00 +0100 Subject: [PATCH 15/72] Added generic type to rotation functions not overwritten by orientation --- python/damask/_rotation.py | 43 ++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index 6e01cae65..a04b20e62 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -6,7 +6,7 @@ from . import tensor from . import util from . import grid_filters -from typing import Union, Sequence, Tuple, Literal, List +from typing import Union, Sequence, Tuple, Literal, List, TypeVar from ._typehints import FloatSequence, IntSequence _P = -1 @@ -16,6 +16,8 @@ _sc = np.pi**(1./6.)/6.**(1./6.) _beta = np.pi**(5./6.)/6.**(1./6.)/2. _R1 = (3.*np.pi/4.)**(1./3.) +MyType = TypeVar('MyType', bound='Rotation') + class Rotation: u""" Rotation with functionality for conversion between different representations. @@ -92,8 +94,8 @@ class Rotation: + str(self.quaternion) - def __copy__(self, - rotation: Union[FloatSequence, 'Rotation'] = None) -> 'Rotation': + def __copy__(self: MyType, + rotation: Union[FloatSequence, 'Rotation'] = None) -> MyType: """Create deep copy.""" dup = copy.deepcopy(self) if rotation is not None: @@ -220,14 +222,15 @@ class Rotation: return 0 if self.shape == () else self.shape[0] - def __invert__(self) -> 'Rotation': + def __invert__(self: MyType) -> MyType: """Inverse rotation (backward rotation).""" dup = self.copy() dup.quaternion[...,1:] *= -1 return dup - def __pow__(self, exp: int) -> 'Rotation': + def __pow__(self: MyType, + exp: int) -> MyType: """ Perform the rotation 'exp' times. @@ -241,7 +244,8 @@ class Rotation: p = self.quaternion[...,1:]/np.linalg.norm(self.quaternion[...,1:],axis=-1,keepdims=True) return self.copy(rotation=Rotation(np.block([np.cos(exp*phi),np.sin(exp*phi)*p]))._standardize()) - def __ipow__(self, exp: int) -> 'Rotation': + def __ipow__(self: MyType, + exp: int) -> MyType: """ Perform the rotation 'exp' times (in-place). @@ -280,7 +284,8 @@ class Rotation: else: raise TypeError('Use "R@b", i.e. matmul, to apply rotation "R" to object "b"') - def __imul__(self, other: 'Rotation') -> 'Rotation': + def __imul__(self, + other: 'Rotation') -> 'Rotation': """ Compose with other (in-place). @@ -293,7 +298,8 @@ class Rotation: return self*other - def __truediv__(self, other: 'Rotation') -> 'Rotation': + def __truediv__(self: 'Rotation', + other: 'Rotation') -> 'Rotation': """ Compose with inverse of other. @@ -313,7 +319,8 @@ class Rotation: else: raise TypeError('Use "R@b", i.e. matmul, to apply rotation "R" to object "b"') - def __itruediv__(self, other: 'Rotation') -> 'Rotation': + def __itruediv__(self: 'Rotation', + other: 'Rotation') -> 'Rotation': """ Compose with inverse of other (in-place). @@ -369,14 +376,14 @@ class Rotation: apply = __matmul__ - def _standardize(self) -> 'Rotation': + def _standardize(self: MyType) -> MyType: """Standardize quaternion (ensure positive real hemisphere).""" self.quaternion[self.quaternion[...,0] < 0.0] *= -1 return self - def append(self, - other: Union['Rotation', List['Rotation']]) -> 'Rotation': + def append(self: MyType, + other: Union[MyType, List[MyType]]) -> MyType: """ Extend array along first dimension with other array(s). @@ -389,8 +396,8 @@ class Rotation: [self]+other if isinstance(other,list) else [self,other])))) - def flatten(self, - order: Literal['C','F','A'] = 'C') -> 'Rotation': + def flatten(self: MyType, + order: Literal['C','F','A'] = 'C') -> MyType: """ Flatten array. @@ -403,9 +410,9 @@ class Rotation: return self.copy(rotation=self.quaternion.reshape((-1,4),order=order)) - def reshape(self, + def reshape(self: MyType, shape: Union[int, Tuple[int, ...]], - order: Literal['C','F','A'] = 'C') -> 'Rotation': + order: Literal['C','F','A'] = 'C') -> MyType: """ Reshape array. @@ -419,9 +426,9 @@ class Rotation: return self.copy(rotation=self.quaternion.reshape(tuple(shape)+(4,),order=order)) - def broadcast_to(self, + def broadcast_to(self: MyType, shape: Union[int, Tuple[int, ...]], - mode: Literal['left', 'right'] = 'right') -> 'Rotation': + mode: Literal['left', 'right'] = 'right') -> MyType: """ Broadcast array. From fc8cd6322c52eebc13c1485aea64e79328e1b8e6 Mon Sep 17 00:00:00 2001 From: Daniel Otto de Mentock Date: Wed, 2 Feb 2022 12:16:57 +0100 Subject: [PATCH 16/72] adjusted rng_seed type in rotation adjusted NotImplemented error return in orientation --- python/damask/_orientation.py | 2 +- python/damask/_rotation.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/python/damask/_orientation.py b/python/damask/_orientation.py index 8a560e756..dff380dcf 100644 --- a/python/damask/_orientation.py +++ b/python/damask/_orientation.py @@ -148,7 +148,7 @@ class Orientation(Rotation,Crystal): """ if not isinstance(other, Orientation): - raise NotImplemented + return NotImplemented matching_type = self.family == other.family and \ self.lattice == other.lattice and \ self.parameters == other.parameters diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index a04b20e62..361dba7c1 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -997,7 +997,7 @@ class Rotation: N: int = 500, degrees: bool = True, fractions: bool = True, - rng_seed: Union[None, int, IntSequence] = None) -> 'Rotation': + rng_seed: Union[int, IntSequence] = None) -> 'Rotation': """ Sample discrete values from a binned orientation distribution function (ODF). @@ -1054,7 +1054,7 @@ class Rotation: sigma: float, N: int = 500, degrees: bool = True, - rng_seed: Union[None, int, IntSequence] = None) -> 'Rotation': + rng_seed: Union[int, IntSequence] = None) -> 'Rotation': """ Calculate set of rotations with Gaussian distribution around center. From f80de7d0b36b8dcd63e876a43763e4a897fdd01e Mon Sep 17 00:00:00 2001 From: Daniel Otto de Mentock Date: Thu, 3 Feb 2022 12:04:31 +0100 Subject: [PATCH 17/72] added NumpyRngSeed type to rotation rng_seed objects --- python/damask/_rotation.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index 361dba7c1..d919c9029 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -7,7 +7,7 @@ from . import util from . import grid_filters from typing import Union, Sequence, Tuple, Literal, List, TypeVar -from ._typehints import FloatSequence, IntSequence +from ._typehints import FloatSequence, IntSequence, NumpyRngSeed _P = -1 @@ -963,7 +963,7 @@ class Rotation: @staticmethod def from_random(shape: Tuple[int, ...] = None, - rng_seed: Union[int, IntSequence] = None) -> 'Rotation': + rng_seed: NumpyRngSeed = None) -> 'Rotation': """ Initialize with random rotation. @@ -997,7 +997,7 @@ class Rotation: N: int = 500, degrees: bool = True, fractions: bool = True, - rng_seed: Union[int, IntSequence] = None) -> 'Rotation': + rng_seed: NumpyRngSeed = None) -> 'Rotation': """ Sample discrete values from a binned orientation distribution function (ODF). @@ -1054,7 +1054,7 @@ class Rotation: sigma: float, N: int = 500, degrees: bool = True, - rng_seed: Union[int, IntSequence] = None) -> 'Rotation': + rng_seed: NumpyRngSeed = None) -> 'Rotation': """ Calculate set of rotations with Gaussian distribution around center. @@ -1090,7 +1090,7 @@ class Rotation: sigma: float = 0.0, N: int = 500, degrees: bool = True, - rng_seed: Union[int, IntSequence] = None): + rng_seed: NumpyRngSeed = None): """ Calculate set of rotations with Gaussian distribution around direction. From d1f9e98e3ce071c9e24488675bc6ed9b579fb524 Mon Sep 17 00:00:00 2001 From: Daniel Otto de Mentock Date: Thu, 3 Feb 2022 16:11:09 +0100 Subject: [PATCH 18/72] moved typecheck of __ne__ functions to __eq__ added initial empty runtimeerror to Schmid function minor corrections --- python/damask/_orientation.py | 13 ++++++++----- python/damask/_rotation.py | 7 ++++--- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/python/damask/_orientation.py b/python/damask/_orientation.py index dff380dcf..780a5929e 100644 --- a/python/damask/_orientation.py +++ b/python/damask/_orientation.py @@ -165,8 +165,10 @@ class Orientation(Rotation,Crystal): Orientation to check for equality. """ - if not isinstance(other, Orientation): - raise TypeError + + eq = self.__eq__(other) + if not isinstance(eq, bool): + return eq return np.logical_not(self==other) @@ -557,7 +559,7 @@ class Orientation(Rotation,Crystal): if self.family != other.family: raise NotImplementedError('disorientation between different crystal families') - blend: Tuple[int, ...] = util.shapeblender(self.shape,other.shape) + blend = util.shapeblender(self.shape,other.shape) s = self.equivalent o = other.equivalent @@ -764,7 +766,7 @@ class Orientation(Rotation,Crystal): np.broadcast_to(self.standard_triangle['improper'], vector_.shape+(3,)), vector_), 12) in_SST_ = np.all(components_proper >= 0.0,axis=-1) \ - | np.all(components_improper >= 0.0,axis=-1) + | np.all(components_improper >= 0.0,axis=-1) components = np.where((in_SST_ & np.all(components_proper >= 0.0,axis=-1))[...,np.newaxis], components_proper,components_improper) else: @@ -928,7 +930,8 @@ class Orientation(Rotation,Crystal): (self.kinematics('twin'),N_twin) if active == '*': active = [len(a) for a in kinematics['direction']] - assert active + if not active: + raise RuntimeError d = self.to_frame(uvw=np.vstack([kinematics['direction'][i][:n] for i,n in enumerate(active)])) p = self.to_frame(hkl=np.vstack([kinematics['plane'][i][:n] for i,n in enumerate(active)])) P = np.einsum('...i,...j',d/np.linalg.norm(d,axis=1,keepdims=True), diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index d919c9029..c3f6407f2 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -85,7 +85,7 @@ class Rotation: elif np.array(rotation).shape[-1] == 4: self.quaternion = np.array(rotation) else: - raise TypeError('Rotation is neither a Rotation nor a quaternion') + raise TypeError('"rotation" is neither a Rotation nor a quaternion') def __repr__(self) -> str: @@ -139,8 +139,9 @@ class Rotation: Rotation to check for inequality. """ - if not isinstance(other, Rotation): - raise TypeError + eq = self.__eq__(other) + if not isinstance(eq, bool): + return eq return np.logical_not(self==other) From c70e535da83d876d52b636149503a5d5f3365871 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 4 Feb 2022 00:11:08 +0100 Subject: [PATCH 19/72] avoid access by el/ip --- src/phase_mechanical_plastic_nonlocal.f90 | 36 ++++++++++++----------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/src/phase_mechanical_plastic_nonlocal.f90 b/src/phase_mechanical_plastic_nonlocal.f90 index a8f56b5c5..81ce4d08e 100644 --- a/src/phase_mechanical_plastic_nonlocal.f90 +++ b/src/phase_mechanical_plastic_nonlocal.f90 @@ -123,8 +123,10 @@ submodule(phase:plastic) nonlocal type :: tNonlocalDependentState real(pReal), allocatable, dimension(:,:) :: & - tau_pass, & - tau_Back + tau_pass, & + tau_Back + real(pReal), allocatable, dimension(:,:,:,:,:) :: & + compatibility end type tNonlocalDependentState type :: tNonlocalState @@ -160,7 +162,6 @@ submodule(phase:plastic) nonlocal state0 type(tParameters), dimension(:), allocatable :: param !< containers of constitutive parameters - type(tNonlocalDependentState), dimension(:), allocatable :: dependentState contains @@ -489,6 +490,7 @@ module function plastic_nonlocal_init() result(myPlasticity) allocate(dst%tau_pass(prm%sum_N_sl,Nmembers),source=0.0_pReal) allocate(dst%tau_back(prm%sum_N_sl,Nmembers),source=0.0_pReal) + allocate(dst%compatibility(2,maxval(param%sum_N_sl),maxval(param%sum_N_sl),nIPneighbors,Nmembers),source=0.0_pReal) end associate if (Nmembers > 0) call stateInit(ini,ph,Nmembers) @@ -669,7 +671,7 @@ module subroutine nonlocal_dependentState(ph, en, ip, el) - discretization_IPcoords(1:3,el+neighbor_ip-1)) normal_latticeConf = matmul(transpose(invFp), IPareaNormal(1:3,n,ip,el)) if (math_inner(normal_latticeConf,connection_latticeConf(1:3,n)) < 0.0_pReal) & ! neighboring connection points in opposite direction to face normal: must be periodic image - connection_latticeConf(1:3,n) = normal_latticeConf * IPvolume(ip,el)/IParea(n,ip,el) ! instead take the surface normal scaled with the diameter of the cell + connection_latticeConf(1:3,n) = normal_latticeConf * geom(ph)%V_0(en)/IParea(n,ip,el) ! instead take the surface normal scaled with the diameter of the cell else ! local neighbor or different lattice structure or different constitution instance -> use central values instead connection_latticeConf(1:3,n) = 0.0_pReal @@ -1110,7 +1112,7 @@ module subroutine nonlocal_dotState(Mp,timestep, & .or. any(rho(:,dip) + rhoDot(:,9:10) * timestep < -prm%atol_rho)) then #ifdef DEBUG if (debugConstitutive%extensive) then - print'(a,i5,a,i2)', '<< CONST >> evolution rate leads to negative density at el ',el,' ip ',ip + print'(a,i5,a,i2)', '<< CONST >> evolution rate leads to negative density at ph ',ph,' en ',en print'(a)', '<< CONST >> enforcing cutback !!!' end if #endif @@ -1215,14 +1217,14 @@ function rhoDotFlux(timestep,ph,en,ip,el) !*** check CFL (Courant-Friedrichs-Lewy) condition for flux if (any( abs(dot_gamma) > 0.0_pReal & ! any active slip system ... .and. prm%C_CFL * abs(v0) * timestep & - > IPvolume(ip,el) / maxval(IParea(:,ip,el)))) then ! ...with velocity above critical value (we use the reference volume and area for simplicity here) + > geom(ph)%V_0(en)/ maxval(IParea(:,ip,el)))) then ! ...with velocity above critical value (we use the reference volume and area for simplicity here) #ifdef DEBUG if (debugConstitutive%extensive) then - print'(a,i5,a,i2)', '<< CONST >> CFL condition not fullfilled at el ',el,' ip ',ip + print'(a,i5,a,i2)', '<< CONST >> CFL condition not fullfilled at ph ',ph,' en ',en print'(a,e10.3,a,e10.3)', '<< CONST >> velocity is at ', & maxval(abs(v0), abs(dot_gamma) > 0.0_pReal & .and. prm%C_CFL * abs(v0) * timestep & - > IPvolume(ip,el) / maxval(IParea(:,ip,el))), & + > geom(ph)%V_0(en) / maxval(IParea(:,ip,el))), & ' at a timestep of ',timestep print*, '<< CONST >> enforcing cutback !!!' end if @@ -1277,7 +1279,7 @@ function rhoDotFlux(timestep,ph,en,ip,el) !* compatibility if (neighbor_n > 0) then if (phase_plasticity(material_phaseAt(1,neighbor_el)) == PLASTIC_NONLOCAL_ID .and. & - any(compatibility(:,:,:,n,ip,el) > 0.0_pReal)) then + any(dependentState(ph)%compatibility(:,:,:,n,en) > 0.0_pReal)) then forall (s = 1:ns, t = 1:4) neighbor_v0(s,t) = plasticState(np)%state0(iV (s,t,neighbor_ph),no) @@ -1301,12 +1303,12 @@ function rhoDotFlux(timestep,ph,en,ip,el) .and. v0(s,t) * neighbor_v0(s,t) >= 0.0_pReal ) then ! ... only if no sign change in flux density lineLength = neighbor_rhoSgl0(s,t) * neighbor_v0(s,t) & * math_inner(m(1:3,s,t), normal_neighbor2me) * area ! positive line length that wants to enter through this interface - where (compatibility(c,:,s,n,ip,el) > 0.0_pReal) & + where (dependentState(ph)%compatibility(c,:,s,n,en) > 0.0_pReal) & rhoDotFlux(:,t) = rhoDotFlux(1:ns,t) & - + lineLength/IPvolume(ip,el)*compatibility(c,:,s,n,ip,el)**2 ! transferring to equally signed mobile dislocation type - where (compatibility(c,:,s,n,ip,el) < 0.0_pReal) & + + lineLength/geom(ph)%V_0(en)*dependentState(ph)%compatibility(c,:,s,n,en)**2 ! transferring to equally signed mobile dislocation type + where (dependentState(ph)%compatibility(c,:,s,n,en) < 0.0_pReal) & rhoDotFlux(:,topp) = rhoDotFlux(:,topp) & - + lineLength/IPvolume(ip,el)*compatibility(c,:,s,n,ip,el)**2 ! transferring to opposite signed mobile dislocation type + + lineLength/geom(ph)%V_0(en)*dependentState(ph)%compatibility(c,:,s,n,en)**2 ! transferring to opposite signed mobile dislocation type end if end do @@ -1335,15 +1337,15 @@ function rhoDotFlux(timestep,ph,en,ip,el) c = (t + 1) / 2 if (v0(s,t) * math_inner(m(1:3,s,t), normal_me2neighbor) > 0.0_pReal ) then ! flux from en to my neighbor == leaving flux for en (might also be a pure flux from my mobile density to dead density if interface not at all transmissive) if (v0(s,t) * neighbor_v0(s,t) >= 0.0_pReal) then ! no sign change in flux density - transmissivity = sum(compatibility(c,:,s,n,ip,el)**2) ! overall transmissivity from this slip system to my neighbor + transmissivity = sum(dependentState(ph)%compatibility(c,:,s,n,en)**2) ! overall transmissivity from this slip system to my neighbor else ! sign change in flux density means sign change in stress which does not allow for dislocations to arive at the neighbor transmissivity = 0.0_pReal end if lineLength = my_rhoSgl0(s,t) * v0(s,t) & * math_inner(m(1:3,s,t), normal_me2neighbor) * area ! positive line length of mobiles that wants to leave through this interface - rhoDotFlux(s,t) = rhoDotFlux(s,t) - lineLength / IPvolume(ip,el) ! subtract dislocation flux from current type + rhoDotFlux(s,t) = rhoDotFlux(s,t) - lineLength / geom(ph)%V_0(en) ! subtract dislocation flux from current type rhoDotFlux(s,t+4) = rhoDotFlux(s,t+4) & - + lineLength / IPvolume(ip,el) * (1.0_pReal - transmissivity) & + + lineLength / geom(ph)%V_0(en) * (1.0_pReal - transmissivity) & * sign(1.0_pReal, v0(s,t)) ! dislocation flux that is not able to leave through interface (because of low transmissivity) will remain as immobile single density at the material point end if end do @@ -1465,7 +1467,7 @@ module subroutine plastic_nonlocal_updateCompatibility(orientation,ph,i,e) end do neighbors - compatibility(:,:,:,:,i,e) = my_compatibility + dependentState(ph)%compatibility(:,:,:,:,material_phaseEntry(1,(e-1)*discretization_nIPs + i)) = my_compatibility end associate From 8b12814eec5678221d7b0e2535a9d5f53a105266 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 4 Feb 2022 06:42:14 +0100 Subject: [PATCH 20/72] common variable names --- src/phase.f90 | 6 +++--- src/phase_mechanical_plastic_nonlocal.f90 | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/phase.f90 b/src/phase.f90 index b7bace81a..82bc44bfd 100644 --- a/src/phase.f90 +++ b/src/phase.f90 @@ -264,11 +264,11 @@ module phase real(pReal) :: f end function phase_f_T - module subroutine plastic_nonlocal_updateCompatibility(orientation,ph,i,e) + module subroutine plastic_nonlocal_updateCompatibility(orientation,ph,ip,el) integer, intent(in) :: & ph, & - i, & - e + ip, & + el type(tRotationContainer), dimension(:), intent(in) :: orientation end subroutine plastic_nonlocal_updateCompatibility diff --git a/src/phase_mechanical_plastic_nonlocal.f90 b/src/phase_mechanical_plastic_nonlocal.f90 index 81ce4d08e..bb36aee06 100644 --- a/src/phase_mechanical_plastic_nonlocal.f90 +++ b/src/phase_mechanical_plastic_nonlocal.f90 @@ -1366,14 +1366,14 @@ end function rhoDotFlux ! plane normals and signed cosine of the angle between the slip directions. Only the largest values ! that sum up to a total of 1 are considered, all others are set to zero. !-------------------------------------------------------------------------------------------------- -module subroutine plastic_nonlocal_updateCompatibility(orientation,ph,i,e) +module subroutine plastic_nonlocal_updateCompatibility(orientation,ph,ip,el) type(tRotationContainer), dimension(:), intent(in) :: & orientation ! crystal orientation integer, intent(in) :: & ph, & - i, & - e + ip, & + el integer :: & n, & ! neighbor index @@ -1399,14 +1399,14 @@ module subroutine plastic_nonlocal_updateCompatibility(orientation,ph,i,e) associate(prm => param(ph)) ns = prm%sum_N_sl - en = material_phaseMemberAt(1,i,e) + en = material_phaseMemberAt(1,ip,el) !*** start out fully compatible my_compatibility = 0.0_pReal forall(s1 = 1:ns) my_compatibility(:,s1,s1,:) = 1.0_pReal neighbors: do n = 1,nIPneighbors - neighbor_e = IPneighborhood(1,n,i,e) - neighbor_i = IPneighborhood(2,n,i,e) + neighbor_e = IPneighborhood(1,n,ip,el) + neighbor_i = IPneighborhood(2,n,ip,el) neighbor_me = material_phaseMemberAt(1,neighbor_i,neighbor_e) neighbor_phase = material_phaseAt(1,neighbor_e) @@ -1467,7 +1467,7 @@ module subroutine plastic_nonlocal_updateCompatibility(orientation,ph,i,e) end do neighbors - dependentState(ph)%compatibility(:,:,:,:,material_phaseEntry(1,(e-1)*discretization_nIPs + i)) = my_compatibility + dependentState(ph)%compatibility(:,:,:,:,material_phaseEntry(1,(el-1)*discretization_nIPs + ip)) = my_compatibility end associate From 900ef0a2c96544d5d72246e86f0f00e3ee6ad93f Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 4 Feb 2022 07:33:12 +0100 Subject: [PATCH 21/72] store IP neighborhood for ph/en access --- src/phase_mechanical_plastic_nonlocal.f90 | 63 ++++++++++++++--------- 1 file changed, 40 insertions(+), 23 deletions(-) diff --git a/src/phase_mechanical_plastic_nonlocal.f90 b/src/phase_mechanical_plastic_nonlocal.f90 index bb36aee06..78271b92f 100644 --- a/src/phase_mechanical_plastic_nonlocal.f90 +++ b/src/phase_mechanical_plastic_nonlocal.f90 @@ -15,6 +15,9 @@ submodule(phase:plastic) nonlocal type :: tGeometry real(pReal), dimension(:), allocatable :: V_0 + integer, dimension(:,:,:), allocatable :: IPneighborhood + real(pReal), dimension(:,:), allocatable :: IParea + real(pReal), dimension(:,:,:), allocatable :: IPareaNormal end type tGeometry type(tGeometry), dimension(:), allocatable :: geom @@ -407,6 +410,9 @@ module function plastic_nonlocal_init() result(myPlasticity) call phase_allocateState(plasticState(ph),Nmembers,sizeState,sizeDotState,sizeDeltaState,0) ! ToDo: state structure does not follow convention allocate(geom(ph)%V_0(Nmembers)) + allocate(geom(ph)%IPneighborhood(3,nIPneighbors,Nmembers)) + allocate(geom(ph)%IPareaNormal(3,nIPneighbors,Nmembers)) + allocate(geom(ph)%IParea(nIPneighbors,Nmembers)) call storeGeometry(ph) if(plasticState(ph)%nonlocal .and. .not. allocated(IPneighborhood)) & @@ -652,8 +658,8 @@ module subroutine nonlocal_dependentState(ph, en, ip, el) nRealNeighbors = 0.0_pReal neighbor_rhoTotal = 0.0_pReal do n = 1,nIPneighbors - neighbor_el = IPneighborhood(1,n,ip,el) - neighbor_ip = IPneighborhood(2,n,ip,el) + neighbor_el = geom(ph)%IPneighborhood(1,n,en) + neighbor_ip = geom(ph)%IPneighborhood(2,n,en) no = material_phasememberAt(1,neighbor_ip,neighbor_el) if (neighbor_el > 0 .and. neighbor_ip > 0) then if (material_phaseAt(1,neighbor_el) == ph) then @@ -669,9 +675,9 @@ module subroutine nonlocal_dependentState(ph, en, ip, el) connection_latticeConf(1:3,n) = matmul(invFe, discretization_IPcoords(1:3,neighbor_el+neighbor_ip-1) & - discretization_IPcoords(1:3,el+neighbor_ip-1)) - normal_latticeConf = matmul(transpose(invFp), IPareaNormal(1:3,n,ip,el)) + normal_latticeConf = matmul(transpose(invFp), geom(ph)%IPareaNormal(1:3,n,en)) if (math_inner(normal_latticeConf,connection_latticeConf(1:3,n)) < 0.0_pReal) & ! neighboring connection points in opposite direction to face normal: must be periodic image - connection_latticeConf(1:3,n) = normal_latticeConf * geom(ph)%V_0(en)/IParea(n,ip,el) ! instead take the surface normal scaled with the diameter of the cell + connection_latticeConf(1:3,n) = normal_latticeConf * geom(ph)%V_0(en)/geom(ph)%IParea(n,en) ! instead take the surface normal scaled with the diameter of the cell else ! local neighbor or different lattice structure or different constitution instance -> use central values instead connection_latticeConf(1:3,n) = 0.0_pReal @@ -1101,7 +1107,7 @@ module subroutine nonlocal_dotState(Mp,timestep, & - rhoDip(s,1) / timestep - rhoDotAthermalAnnihilation(s,9) & - rhoDotSingle2DipoleGlide(s,9)) ! make sure that we do not annihilate more dipoles than we have - rhoDot = rhoDotFlux(timestep, ph,en,ip,el) & + rhoDot = rhoDotFlux(timestep, ph,en) & + rhoDotMultiplication & + rhoDotSingle2DipoleGlide & + rhoDotAthermalAnnihilation & @@ -1131,17 +1137,15 @@ end subroutine nonlocal_dotState !> @brief calculates the rate of change of microstructure !--------------------------------------------------------------------------------------------------- #if __INTEL_COMPILER >= 2020 -non_recursive function rhoDotFlux(timestep,ph,en,ip,el) +non_recursive function rhoDotFlux(timestep,ph,en) #else -function rhoDotFlux(timestep,ph,en,ip,el) +function rhoDotFlux(timestep,ph,en) #endif real(pReal), intent(in) :: & timestep !< substepped crystallite time increment integer, intent(in) :: & ph, & - en, & - ip, & !< current integration point - el !< current element number + en integer :: & neighbor_ph, & !< phase of my neighbor's plasticity @@ -1217,14 +1221,14 @@ function rhoDotFlux(timestep,ph,en,ip,el) !*** check CFL (Courant-Friedrichs-Lewy) condition for flux if (any( abs(dot_gamma) > 0.0_pReal & ! any active slip system ... .and. prm%C_CFL * abs(v0) * timestep & - > geom(ph)%V_0(en)/ maxval(IParea(:,ip,el)))) then ! ...with velocity above critical value (we use the reference volume and area for simplicity here) + > geom(ph)%V_0(en)/ maxval(geom(ph)%IParea(:,en)))) then ! ...with velocity above critical value (we use the reference volume and area for simplicity here) #ifdef DEBUG if (debugConstitutive%extensive) then print'(a,i5,a,i2)', '<< CONST >> CFL condition not fullfilled at ph ',ph,' en ',en print'(a,e10.3,a,e10.3)', '<< CONST >> velocity is at ', & maxval(abs(v0), abs(dot_gamma) > 0.0_pReal & .and. prm%C_CFL * abs(v0) * timestep & - > geom(ph)%V_0(en) / maxval(IParea(:,ip,el))), & + > geom(ph)%V_0(en) / maxval(geom(ph)%IParea(:,en))), & ' at a timestep of ',timestep print*, '<< CONST >> enforcing cutback !!!' end if @@ -1247,16 +1251,16 @@ function rhoDotFlux(timestep,ph,en,ip,el) neighbors: do n = 1,nIPneighbors - neighbor_el = IPneighborhood(1,n,ip,el) - neighbor_ip = IPneighborhood(2,n,ip,el) - neighbor_n = IPneighborhood(3,n,ip,el) + neighbor_el = geom(ph)%IPneighborhood(1,n,en) + neighbor_ip = geom(ph)%IPneighborhood(2,n,en) + neighbor_n = geom(ph)%IPneighborhood(3,n,en) np = material_phaseAt(1,neighbor_el) no = material_phasememberAt(1,neighbor_ip,neighbor_el) opposite_neighbor = n + mod(n,2) - mod(n+1,2) - opposite_el = IPneighborhood(1,opposite_neighbor,ip,el) - opposite_ip = IPneighborhood(2,opposite_neighbor,ip,el) - opposite_n = IPneighborhood(3,opposite_neighbor,ip,el) + opposite_el = geom(ph)%IPneighborhood(1,opposite_neighbor,en) + opposite_ip = geom(ph)%IPneighborhood(2,opposite_neighbor,en) + opposite_n = geom(ph)%IPneighborhood(3,opposite_neighbor,en) if (neighbor_n > 0) then ! if neighbor exists, average deformation gradient neighbor_ph = material_phaseAt(1,neighbor_el) @@ -1327,10 +1331,10 @@ function rhoDotFlux(timestep,ph,en,ip,el) if (phase_plasticity(material_phaseAt(1,opposite_el)) == PLASTIC_NONLOCAL_ID) then normal_me2neighbor_defConf = math_det33(Favg) & - * matmul(math_inv33(transpose(Favg)),IPareaNormal(1:3,n,ip,el)) ! normal of the interface in (average) deformed configuration (pointing en => neighbor) + * matmul(math_inv33(transpose(Favg)),geom(ph)%IPareaNormal(1:3,n,en)) ! normal of the interface in (average) deformed configuration (pointing en => neighbor) normal_me2neighbor = matmul(transpose(my_Fe), normal_me2neighbor_defConf) & / math_det33(my_Fe) ! interface normal in my lattice configuration - area = IParea(n,ip,el) * norm2(normal_me2neighbor) + area = geom(ph)%IParea(n,en) * norm2(normal_me2neighbor) normal_me2neighbor = normal_me2neighbor / norm2(normal_me2neighbor) ! normalize the surface normal to unit length do s = 1,ns do t = 1,4 @@ -1758,14 +1762,27 @@ subroutine storeGeometry(ph) integer, intent(in) :: ph - integer :: ce, co + integer :: ce, co, nCell real(pReal), dimension(:), allocatable :: V + integer, dimension(:,:,:), allocatable :: neighborhood + real(pReal), dimension(:,:), allocatable :: area + real(pReal), dimension(:,:,:), allocatable :: areaNormal + nCell = product(shape(IPvolume)) + + V = reshape(IPvolume,[nCell]) + neighborhood = reshape(IPneighborhood,[3,nIPneighbors,nCell]) + area = reshape(IParea,[nIPneighbors,nCell]) + areaNormal = reshape(IPareaNormal,[3,nIPneighbors,nCell]) - V = reshape(IPvolume,[product(shape(IPvolume))]) do ce = 1, size(material_homogenizationEntry,1) do co = 1, homogenization_maxNconstituents - if (material_phaseID(co,ce) == ph) geom(ph)%V_0(material_phaseEntry(co,ce)) = V(ce) + if (material_phaseID(co,ce) == ph) then + geom(ph)%V_0(material_phaseEntry(co,ce)) = V(ce) + geom(ph)%IPneighborhood(:,:,material_phaseEntry(co,ce)) = neighborhood(:,:,ce) + geom(ph)%IParea(:,material_phaseEntry(co,ce)) = area(:,ce) + geom(ph)%IPareaNormal(:,:,material_phaseEntry(co,ce)) = areaNormal(:,:,ce) + end if end do end do From 2bd10a126178a540b7c85e8f72e08fe80c674537 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 4 Feb 2022 08:25:51 +0100 Subject: [PATCH 22/72] avoid use of IP/el --- src/phase_mechanical_plastic.f90 | 16 ++++++---------- src/phase_mechanical_plastic_nonlocal.f90 | 23 +++++++++++------------ 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/src/phase_mechanical_plastic.f90 b/src/phase_mechanical_plastic.f90 index 912aadc03..9378edfdc 100644 --- a/src/phase_mechanical_plastic.f90 +++ b/src/phase_mechanical_plastic.f90 @@ -154,16 +154,14 @@ submodule(phase:mechanical) plastic en end subroutine dislotungsten_dotState - module subroutine nonlocal_dotState(Mp,timestep,ph,en,ip,el) + module subroutine nonlocal_dotState(Mp,timestep,ph,en) real(pReal), dimension(3,3), intent(in) :: & Mp !< MandelStress real(pReal), intent(in) :: & timestep !< substepped crystallite time increment integer, intent(in) :: & ph, & - en, & - ip, & !< current integration point - el !< current element number + en end subroutine nonlocal_dotState module subroutine dislotwin_dependentState(T,ph,en) @@ -180,12 +178,10 @@ submodule(phase:mechanical) plastic en end subroutine dislotungsten_dependentState - module subroutine nonlocal_dependentState(ph, en, ip, el) + module subroutine nonlocal_dependentState(ph, en) integer, intent(in) :: & ph, & - en, & - ip, & !< current integration point - el !< current element number + en end subroutine nonlocal_dependentState module subroutine plastic_kinehardening_deltaState(Mp,ph,en) @@ -333,7 +329,7 @@ module function plastic_dotState(subdt,co,ip,el,ph,en) result(dotState) call dislotungsten_dotState(Mp,thermal_T(ph,en),ph,en) case (PLASTIC_NONLOCAL_ID) plasticType - call nonlocal_dotState(Mp,subdt,ph,en,ip,el) + call nonlocal_dotState(Mp,subdt,ph,en) end select plasticType end if @@ -369,7 +365,7 @@ module subroutine plastic_dependentState(co, ip, el) call dislotungsten_dependentState(ph,en) case (PLASTIC_NONLOCAL_ID) plasticType - call nonlocal_dependentState(ph,en,ip,el) + call nonlocal_dependentState(ph,en) end select plasticType diff --git a/src/phase_mechanical_plastic_nonlocal.f90 b/src/phase_mechanical_plastic_nonlocal.f90 index 78271b92f..9c901f6b0 100644 --- a/src/phase_mechanical_plastic_nonlocal.f90 +++ b/src/phase_mechanical_plastic_nonlocal.f90 @@ -16,7 +16,7 @@ submodule(phase:plastic) nonlocal type :: tGeometry real(pReal), dimension(:), allocatable :: V_0 integer, dimension(:,:,:), allocatable :: IPneighborhood - real(pReal), dimension(:,:), allocatable :: IParea + real(pReal), dimension(:,:), allocatable :: IParea, IPcoordinates real(pReal), dimension(:,:,:), allocatable :: IPareaNormal end type tGeometry @@ -413,6 +413,7 @@ module function plastic_nonlocal_init() result(myPlasticity) allocate(geom(ph)%IPneighborhood(3,nIPneighbors,Nmembers)) allocate(geom(ph)%IPareaNormal(3,nIPneighbors,Nmembers)) allocate(geom(ph)%IParea(nIPneighbors,Nmembers)) + allocate(geom(ph)%IPcoordinates(3,Nmembers)) call storeGeometry(ph) if(plasticState(ph)%nonlocal .and. .not. allocated(IPneighborhood)) & @@ -551,13 +552,11 @@ end function plastic_nonlocal_init !-------------------------------------------------------------------------------------------------- !> @brief calculates quantities characterizing the microstructure !-------------------------------------------------------------------------------------------------- -module subroutine nonlocal_dependentState(ph, en, ip, el) +module subroutine nonlocal_dependentState(ph, en) integer, intent(in) :: & ph, & - en, & - ip, & - el + en integer :: & no, & !< neighbor offset @@ -673,8 +672,8 @@ module subroutine nonlocal_dependentState(ph, en, ip, el) neighbor_rhoTotal(1,:,n) = sum(abs(rho_neighbor0(:,edg)),2) neighbor_rhoTotal(2,:,n) = sum(abs(rho_neighbor0(:,scr)),2) - connection_latticeConf(1:3,n) = matmul(invFe, discretization_IPcoords(1:3,neighbor_el+neighbor_ip-1) & - - discretization_IPcoords(1:3,el+neighbor_ip-1)) + connection_latticeConf(1:3,n) = matmul(invFe, geom(ph)%IPcoordinates(1:3,en) & + - geom(ph)%IPcoordinates(1:3,en-1)) ! ToDo: broken for different materials normal_latticeConf = matmul(transpose(invFp), geom(ph)%IPareaNormal(1:3,n,en)) if (math_inner(normal_latticeConf,connection_latticeConf(1:3,n)) < 0.0_pReal) & ! neighboring connection points in opposite direction to face normal: must be periodic image connection_latticeConf(1:3,n) = normal_latticeConf * geom(ph)%V_0(en)/geom(ph)%IParea(n,en) ! instead take the surface normal scaled with the diameter of the cell @@ -947,7 +946,7 @@ end subroutine plastic_nonlocal_deltaState !> @brief calculates the rate of change of microstructure !--------------------------------------------------------------------------------------------------- module subroutine nonlocal_dotState(Mp,timestep, & - ph,en,ip,el) + ph,en) real(pReal), dimension(3,3), intent(in) :: & Mp !< MandelStress @@ -955,9 +954,7 @@ module subroutine nonlocal_dotState(Mp,timestep, & timestep !< substepped crystallite time increment integer, intent(in) :: & ph, & - en, & - ip, & !< current integration point - el !< current element number + en integer :: & c, & !< character of dislocation @@ -1765,7 +1762,7 @@ subroutine storeGeometry(ph) integer :: ce, co, nCell real(pReal), dimension(:), allocatable :: V integer, dimension(:,:,:), allocatable :: neighborhood - real(pReal), dimension(:,:), allocatable :: area + real(pReal), dimension(:,:), allocatable :: area, coords real(pReal), dimension(:,:,:), allocatable :: areaNormal nCell = product(shape(IPvolume)) @@ -1774,6 +1771,7 @@ subroutine storeGeometry(ph) neighborhood = reshape(IPneighborhood,[3,nIPneighbors,nCell]) area = reshape(IParea,[nIPneighbors,nCell]) areaNormal = reshape(IPareaNormal,[3,nIPneighbors,nCell]) + coords = reshape(discretization_IPcoords,[3,nCell]) do ce = 1, size(material_homogenizationEntry,1) do co = 1, homogenization_maxNconstituents @@ -1782,6 +1780,7 @@ subroutine storeGeometry(ph) geom(ph)%IPneighborhood(:,:,material_phaseEntry(co,ce)) = neighborhood(:,:,ce) geom(ph)%IParea(:,material_phaseEntry(co,ce)) = area(:,ce) geom(ph)%IPareaNormal(:,:,material_phaseEntry(co,ce)) = areaNormal(:,:,ce) + geom(ph)%IPcoordinates(:,material_phaseEntry(co,ce)) = coords(:,ce) end if end do end do From 3a0596a274f673a3bf93b308c6b4cf2b41c4835f Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 4 Feb 2022 08:49:00 +0100 Subject: [PATCH 23/72] use en/ph access --- src/phase.f90 | 15 ++++++++------- src/phase_mechanical.f90 | 2 +- src/phase_mechanical_plastic.f90 | 14 +++----------- src/phase_mechanical_plastic_nonlocal.f90 | 4 ++-- 4 files changed, 14 insertions(+), 21 deletions(-) diff --git a/src/phase.f90 b/src/phase.f90 index 82bc44bfd..4d180d439 100644 --- a/src/phase.f90 +++ b/src/phase.f90 @@ -272,14 +272,12 @@ module phase type(tRotationContainer), dimension(:), intent(in) :: orientation end subroutine plastic_nonlocal_updateCompatibility - module subroutine plastic_dependentState(co,ip,el) + module subroutine plastic_dependentState(en,ph) integer, intent(in) :: & - co, & !< component-ID of integration point - ip, & !< integration point - el !< element + en, & + ph end subroutine plastic_dependentState - module subroutine damage_anisobrittle_LiAndItsTangent(Ld, dLd_dTstar, S, ph,en) integer, intent(in) :: ph, en real(pReal), intent(in), dimension(3,3) :: & @@ -503,7 +501,8 @@ subroutine crystallite_init() el, & !< counter in element loop cMax, & !< maximum number of integration point components iMax, & !< maximum number of integration points - eMax !< maximum number of elements + eMax, & !< maximum number of elements + en, ph class(tNode), pointer :: & num_crystallite, & @@ -560,8 +559,10 @@ subroutine crystallite_init() do ip = 1, iMax ce = (el-1)*discretization_nIPs + ip do co = 1,homogenization_Nconstituents(material_homogenizationID(ce)) + en = material_phaseEntry(co,ce) + ph = material_phaseID(co,ce) call crystallite_orientations(co,ip,el) - call plastic_dependentState(co,ip,el) ! update dependent state variables to be consistent with basic states + call plastic_dependentState(en,ph) ! update dependent state variables to be consistent with basic states end do end do end do diff --git a/src/phase_mechanical.f90 b/src/phase_mechanical.f90 index 04cc4b946..c97e4a13b 100644 --- a/src/phase_mechanical.f90 +++ b/src/phase_mechanical.f90 @@ -431,7 +431,7 @@ function integrateStress(F,subFp0,subFi0,Delta_t,co,ip,el) result(broken) ph = material_phaseID(co,(el-1)*discretization_nIPs + ip) en = material_phaseEntry(co,(el-1)*discretization_nIPs + ip) - call plastic_dependentState(co,ip,el) + call plastic_dependentState(en,ph) Lpguess = phase_mechanical_Lp(ph)%data(1:3,1:3,en) ! take as first guess Liguess = phase_mechanical_Li(ph)%data(1:3,1:3,en) ! take as first guess diff --git a/src/phase_mechanical_plastic.f90 b/src/phase_mechanical_plastic.f90 index 9378edfdc..a5f40a2df 100644 --- a/src/phase_mechanical_plastic.f90 +++ b/src/phase_mechanical_plastic.f90 @@ -341,20 +341,12 @@ end function plastic_dotState !-------------------------------------------------------------------------------------------------- !> @brief calls microstructure function of the different plasticity constitutive models !-------------------------------------------------------------------------------------------------- -module subroutine plastic_dependentState(co, ip, el) +module subroutine plastic_dependentState(en,ph) integer, intent(in) :: & - co, & !< component-ID of integration point - ip, & !< integration point - el !< element + en, & + ph - integer :: & - ph, & - en - - - ph = material_phaseID(co,(el-1)*discretization_nIPs + ip) - en = material_phaseEntry(co,(el-1)*discretization_nIPs + ip) plasticType: select case (phase_plasticity(ph)) diff --git a/src/phase_mechanical_plastic_nonlocal.f90 b/src/phase_mechanical_plastic_nonlocal.f90 index 9c901f6b0..dec7ea8e7 100644 --- a/src/phase_mechanical_plastic_nonlocal.f90 +++ b/src/phase_mechanical_plastic_nonlocal.f90 @@ -672,8 +672,8 @@ module subroutine nonlocal_dependentState(ph, en) neighbor_rhoTotal(1,:,n) = sum(abs(rho_neighbor0(:,edg)),2) neighbor_rhoTotal(2,:,n) = sum(abs(rho_neighbor0(:,scr)),2) - connection_latticeConf(1:3,n) = matmul(invFe, geom(ph)%IPcoordinates(1:3,en) & - - geom(ph)%IPcoordinates(1:3,en-1)) ! ToDo: broken for different materials + connection_latticeConf(1:3,n) = matmul(invFe, geom(ph)%IPcoordinates(1:3,no) & + - geom(ph)%IPcoordinates(1:3,en)) normal_latticeConf = matmul(transpose(invFp), geom(ph)%IPareaNormal(1:3,n,en)) if (math_inner(normal_latticeConf,connection_latticeConf(1:3,n)) < 0.0_pReal) & ! neighboring connection points in opposite direction to face normal: must be periodic image connection_latticeConf(1:3,n) = normal_latticeConf * geom(ph)%V_0(en)/geom(ph)%IParea(n,en) ! instead take the surface normal scaled with the diameter of the cell From 9dad54304c8886596bd84bac5722466d5c923eb8 Mon Sep 17 00:00:00 2001 From: Daniel Otto de Mentock Date: Fri, 4 Feb 2022 09:57:42 +0100 Subject: [PATCH 24/72] added generic types to remaining non-overwritten rotation functions (exception __mul__) --- python/damask/_orientation.py | 11 +++++------ python/damask/_rotation.py | 20 ++++++++++---------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/python/damask/_orientation.py b/python/damask/_orientation.py index 780a5929e..2dedc13e4 100644 --- a/python/damask/_orientation.py +++ b/python/damask/_orientation.py @@ -165,7 +165,6 @@ class Orientation(Rotation,Crystal): Orientation to check for equality. """ - eq = self.__eq__(other) if not isinstance(eq, bool): return eq @@ -501,8 +500,8 @@ class Orientation(Rotation,Crystal): return np.ones_like(rho[...,0],dtype=bool) def disorientation(self, - other, - return_operators = False): + other: "Orientation", + return_operators: bool = False) -> object: """ Calculate disorientation between myself and given other orientation. @@ -575,9 +574,9 @@ class Orientation(Rotation,Crystal): r = np.where(np.any(forward[...,np.newaxis],axis=(0,1),keepdims=True), r_.quaternion, _r.quaternion) - loc: Tuple[float] = np.where(ok) - sort: np.ndarray = 0 if len(loc) == 2 else np.lexsort(loc[:1:-1]) - quat: np.ndarray = r[ok][sort].reshape(blend+(4,)) + loc = np.where(ok) + sort = 0 if len(loc) == 2 else np.lexsort(loc[:1:-1]) + quat = r[ok][sort].reshape(blend+(4,)) return ( (self.copy(rotation=quat), (np.vstack(loc[:2]).T)[sort].reshape(blend+(2,))) diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index c3f6407f2..d40b48669 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -259,7 +259,7 @@ class Rotation: return self**exp - def __mul__(self, other: 'Rotation') -> 'Rotation': + def __mul__(self: MyType, other: MyType) -> MyType: """ Compose with other. @@ -281,12 +281,12 @@ class Rotation: p_o = other.quaternion[...,1:] q = (q_m*q_o - np.einsum('...i,...i',p_m,p_o).reshape(self.shape+(1,))) p = q_m*p_o + q_o*p_m + _P * np.cross(p_m,p_o) - return Rotation(np.block([q,p]))._standardize() + return Rotation(np.block([q,p]))._standardize() #type: ignore else: raise TypeError('Use "R@b", i.e. matmul, to apply rotation "R" to object "b"') - def __imul__(self, - other: 'Rotation') -> 'Rotation': + def __imul__(self: MyType, + other: MyType) -> MyType: """ Compose with other (in-place). @@ -299,8 +299,8 @@ class Rotation: return self*other - def __truediv__(self: 'Rotation', - other: 'Rotation') -> 'Rotation': + def __truediv__(self: MyType, + other: MyType) -> MyType: """ Compose with inverse of other. @@ -320,8 +320,8 @@ class Rotation: else: raise TypeError('Use "R@b", i.e. matmul, to apply rotation "R" to object "b"') - def __itruediv__(self: 'Rotation', - other: 'Rotation') -> 'Rotation': + def __itruediv__(self: MyType, + other: MyType) -> MyType: """ Compose with inverse of other (in-place). @@ -492,8 +492,8 @@ class Rotation: accept_homomorph = True) - def misorientation(self, - other: 'Rotation') -> 'Rotation': + def misorientation(self: MyType, + other: MyType) -> MyType: """ Calculate misorientation to other Rotation. From 7a405125daa7f29b3b9d13d7b5c1fdb59d435bfd Mon Sep 17 00:00:00 2001 From: Daniel Otto de Mentock Date: Fri, 4 Feb 2022 10:57:24 +0100 Subject: [PATCH 25/72] added type:ignore statements to Tuple Supportsindex addition in Orientation.disorientation function --- python/damask/_orientation.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/damask/_orientation.py b/python/damask/_orientation.py index 2dedc13e4..4817ddb6f 100644 --- a/python/damask/_orientation.py +++ b/python/damask/_orientation.py @@ -562,8 +562,8 @@ class Orientation(Rotation,Crystal): s = self.equivalent o = other.equivalent - s_ = s.reshape((s.shape[0],1)+ self.shape).broadcast_to((s.shape[0],o.shape[0])+blend,mode='right') - o_ = o.reshape((1,o.shape[0])+other.shape).broadcast_to((s.shape[0],o.shape[0])+blend,mode='right') + s_ = s.reshape((s.shape[0],1)+ self.shape).broadcast_to((s.shape[0],o.shape[0])+blend,mode='right') #type: ignore + o_ = o.reshape((1,o.shape[0])+other.shape).broadcast_to((s.shape[0],o.shape[0])+blend,mode='right') #type: ignore r_ = s_.misorientation(o_) _r = ~r_ From 8aed927989ee5edec91f03479bb110e660c3d4c6 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 4 Feb 2022 11:28:54 +0100 Subject: [PATCH 26/72] avoid use of co/ip/el at the phase level --- src/phase_mechanical.f90 | 105 ++++++++++++------------------- src/phase_mechanical_plastic.f90 | 5 +- 2 files changed, 42 insertions(+), 68 deletions(-) diff --git a/src/phase_mechanical.f90 b/src/phase_mechanical.f90 index c97e4a13b..88e98cc2e 100644 --- a/src/phase_mechanical.f90 +++ b/src/phase_mechanical.f90 @@ -79,15 +79,12 @@ submodule(phase) mechanical en end subroutine plastic_isotropic_LiAndItsTangent - module function plastic_dotState(subdt,co,ip,el,ph,en) result(dotState) + module function plastic_dotState(subdt,ph,en) result(dotState) integer, intent(in) :: & - co, & !< component-ID of integration point - ip, & !< integration point - el, & !< element ph, & en real(pReal), intent(in) :: & - subdt !< timestep + subdt !< timestep real(pReal), dimension(plasticState(ph)%sizeDotState) :: & dotState end function plastic_dotState @@ -365,13 +362,11 @@ end subroutine mechanical_results !> @brief calculation of stress (P) with time integration based on a residuum in Lp and !> intermediate acceleration of the Newton-Raphson correction !-------------------------------------------------------------------------------------------------- -function integrateStress(F,subFp0,subFi0,Delta_t,co,ip,el) result(broken) +function integrateStress(F,subFp0,subFi0,Delta_t,en,ph) result(broken) real(pReal), dimension(3,3), intent(in) :: F,subFp0,subFi0 real(pReal), intent(in) :: Delta_t - integer, intent(in):: el, & ! element index - ip, & ! integration point index - co ! grain index + integer, intent(in) :: en, ph real(pReal), dimension(3,3):: Fp_new, & ! plastic deformation gradient at end of timestep invFp_new, & ! inverse of Fp_new @@ -427,10 +422,6 @@ function integrateStress(F,subFp0,subFi0,Delta_t,co,ip,el) result(broken) broken = .true. - - ph = material_phaseID(co,(el-1)*discretization_nIPs + ip) - en = material_phaseEntry(co,(el-1)*discretization_nIPs + ip) - call plastic_dependentState(en,ph) Lpguess = phase_mechanical_Lp(ph)%data(1:3,1:3,en) ! take as first guess @@ -579,15 +570,14 @@ end function integrateStress !> @brief integrate stress, state with adaptive 1st order explicit Euler method !> using Fixed Point Iteration to adapt the stepsize !-------------------------------------------------------------------------------------------------- -function integrateStateFPI(F_0,F,subFp0,subFi0,subState0,Delta_t,co,ip,el) result(broken) +function integrateStateFPI(F_0,F,subFp0,subFi0,subState0,Delta_t,en,ph) result(broken) real(pReal), intent(in),dimension(3,3) :: F_0,F,subFp0,subFi0 real(pReal), intent(in),dimension(:) :: subState0 real(pReal), intent(in) :: Delta_t integer, intent(in) :: & - el, & !< element index in element loop - ip, & !< integration point index in ip loop - co !< grain index in grain loop + en, & + ph logical :: & broken @@ -598,18 +588,16 @@ function integrateStateFPI(F_0,F,subFp0,subFi0,subState0,Delta_t,co,ip,el) resul sizeDotState real(pReal) :: & zeta - real(pReal), dimension(plasticState(material_phaseID(co,(el-1)*discretization_nIPs+ip))%sizeDotState) :: & + real(pReal), dimension(plasticState(ph)%sizeDotState) :: & r, & ! state residuum dotState - real(pReal), dimension(plasticState(material_phaseID(co,(el-1)*discretization_nIPs+ip))%sizeDotState,2) :: & + real(pReal), dimension(plasticState(ph)%sizeDotState,2) :: & dotState_last - ph = material_phaseID(co,(el-1)*discretization_nIPs + ip) - en = material_phaseEntry(co,(el-1)*discretization_nIPs + ip) broken = .true. - dotState = plastic_dotState(Delta_t, co,ip,el,ph,en) + dotState = plastic_dotState(Delta_t,ph,en) if (any(IEEE_is_NaN(dotState))) return sizeDotState = plasticState(ph)%sizeDotState @@ -620,10 +608,10 @@ function integrateStateFPI(F_0,F,subFp0,subFi0,subState0,Delta_t,co,ip,el) resul dotState_last(1:sizeDotState,2) = merge(dotState_last(1:sizeDotState,1),0.0, nIterationState > 1) dotState_last(1:sizeDotState,1) = dotState - broken = integrateStress(F,subFp0,subFi0,Delta_t,co,ip,el) + broken = integrateStress(F,subFp0,subFi0,Delta_t,en,ph) if(broken) exit iteration - dotState = plastic_dotState(Delta_t, co,ip,el,ph,en) + dotState = plastic_dotState(Delta_t,ph,en) if (any(IEEE_is_NaN(dotState))) exit iteration zeta = damper(dotState,dotState_last(1:sizeDotState,1),dotState_last(1:sizeDotState,2)) @@ -672,19 +660,18 @@ end function integrateStateFPI !-------------------------------------------------------------------------------------------------- !> @brief integrate state with 1st order explicit Euler method !-------------------------------------------------------------------------------------------------- -function integrateStateEuler(F_0,F,subFp0,subFi0,subState0,Delta_t,co,ip,el) result(broken) +function integrateStateEuler(F_0,F,subFp0,subFi0,subState0,Delta_t,en,ph) result(broken) real(pReal), intent(in),dimension(3,3) :: F_0,F,subFp0,subFi0 real(pReal), intent(in),dimension(:) :: subState0 real(pReal), intent(in) :: Delta_t integer, intent(in) :: & - el, & !< element index in element loop - ip, & !< integration point index in ip loop - co !< grain index in grain loop + en, & + ph !< grain index in grain loop logical :: & broken - real(pReal), dimension(plasticState(material_phaseID(co,(el-1)*discretization_nIPs+ip))%sizeDotState) :: & + real(pReal), dimension(plasticState(ph)%sizeDotState) :: & dotState integer :: & ph, & @@ -692,11 +679,9 @@ function integrateStateEuler(F_0,F,subFp0,subFi0,subState0,Delta_t,co,ip,el) res sizeDotState - ph = material_phaseID(co,(el-1)*discretization_nIPs + ip) - en = material_phaseEntry(co,(el-1)*discretization_nIPs + ip) broken = .true. - dotState = plastic_dotState(Delta_t, co,ip,el,ph,en) + dotState = plastic_dotState(Delta_t,ph,en) if (any(IEEE_is_NaN(dotState))) return sizeDotState = plasticState(ph)%sizeDotState @@ -706,7 +691,7 @@ function integrateStateEuler(F_0,F,subFp0,subFi0,subState0,Delta_t,co,ip,el) res broken = plastic_deltaState(ph,en) if(broken) return - broken = integrateStress(F,subFp0,subFi0,Delta_t,co,ip,el) + broken = integrateStress(F,subFp0,subFi0,Delta_t,en,ph) end function integrateStateEuler @@ -714,15 +699,14 @@ end function integrateStateEuler !-------------------------------------------------------------------------------------------------- !> @brief integrate stress, state with 1st order Euler method with adaptive step size !-------------------------------------------------------------------------------------------------- -function integrateStateAdaptiveEuler(F_0,F,subFp0,subFi0,subState0,Delta_t,co,ip,el) result(broken) +function integrateStateAdaptiveEuler(F_0,F,subFp0,subFi0,subState0,Delta_t,en,ph) result(broken) real(pReal), intent(in),dimension(3,3) :: F_0,F,subFp0,subFi0 real(pReal), intent(in),dimension(:) :: subState0 real(pReal), intent(in) :: Delta_t integer, intent(in) :: & - el, & !< element index in element loop - ip, & !< integration point index in ip loop - co !< grain index in grain loop + en, & + ph logical :: & broken @@ -730,16 +714,14 @@ function integrateStateAdaptiveEuler(F_0,F,subFp0,subFi0,subState0,Delta_t,co,ip ph, & en, & sizeDotState - real(pReal), dimension(plasticState(material_phaseID(co,(el-1)*discretization_nIPs+ip))%sizeDotState) :: & + real(pReal), dimension(plasticState(ph)%sizeDotState) :: & r, & dotState - ph = material_phaseID(co,(el-1)*discretization_nIPs + ip) - en = material_phaseEntry(co,(el-1)*discretization_nIPs + ip) broken = .true. - dotState = plastic_dotState(Delta_t, co,ip,el,ph,en) + dotState = plastic_dotState(Delta_t,ph,en) if (any(IEEE_is_NaN(dotState))) return sizeDotState = plasticState(ph)%sizeDotState @@ -751,10 +733,10 @@ function integrateStateAdaptiveEuler(F_0,F,subFp0,subFi0,subState0,Delta_t,co,ip broken = plastic_deltaState(ph,en) if(broken) return - broken = integrateStress(F,subFp0,subFi0,Delta_t,co,ip,el) + broken = integrateStress(F,subFp0,subFi0,Delta_t,en,ph) if(broken) return - dotState = plastic_dotState(Delta_t, co,ip,el,ph,en) + dotState = plastic_dotState(Delta_t,ph,en) if (any(IEEE_is_NaN(dotState))) return broken = .not. converged(r + 0.5_pReal * dotState * Delta_t, & @@ -767,12 +749,12 @@ end function integrateStateAdaptiveEuler !--------------------------------------------------------------------------------------------------- !> @brief Integrate state (including stress integration) with the classic Runge Kutta method !--------------------------------------------------------------------------------------------------- -function integrateStateRK4(F_0,F,subFp0,subFi0,subState0,Delta_t,co,ip,el) result(broken) +function integrateStateRK4(F_0,F,subFp0,subFi0,subState0,Delta_t,en,ph) result(broken) real(pReal), intent(in),dimension(3,3) :: F_0,F,subFp0,subFi0 real(pReal), intent(in),dimension(:) :: subState0 real(pReal), intent(in) :: Delta_t - integer, intent(in) :: co,ip,el + integer, intent(in) :: en, ph logical :: broken real(pReal), dimension(3,3), parameter :: & @@ -787,7 +769,7 @@ function integrateStateRK4(F_0,F,subFp0,subFi0,subState0,Delta_t,co,ip,el) resul B = [1.0_pReal/6.0_pReal, 1.0_pReal/3.0_pReal, 1.0_pReal/3.0_pReal, 1.0_pReal/6.0_pReal] - broken = integrateStateRK(F_0,F,subFp0,subFi0,subState0,Delta_t,co,ip,el,A,B,C) + broken = integrateStateRK(F_0,F,subFp0,subFi0,subState0,Delta_t,en,ph,A,B,C) end function integrateStateRK4 @@ -795,12 +777,12 @@ end function integrateStateRK4 !--------------------------------------------------------------------------------------------------- !> @brief Integrate state (including stress integration) with the Cash-Carp method !--------------------------------------------------------------------------------------------------- -function integrateStateRKCK45(F_0,F,subFp0,subFi0,subState0,Delta_t,co,ip,el) result(broken) +function integrateStateRKCK45(F_0,F,subFp0,subFi0,subState0,Delta_t,en,ph) result(broken) real(pReal), intent(in),dimension(3,3) :: F_0,F,subFp0,subFi0 real(pReal), intent(in),dimension(:) :: subState0 real(pReal), intent(in) :: Delta_t - integer, intent(in) :: co,ip,el + integer, intent(in) :: en, ph logical :: broken real(pReal), dimension(5,5), parameter :: & @@ -822,7 +804,7 @@ function integrateStateRKCK45(F_0,F,subFp0,subFi0,subState0,Delta_t,co,ip,el) re 13525.0_pReal/55296.0_pReal, 277.0_pReal/14336.0_pReal, 1._pReal/4._pReal] - broken = integrateStateRK(F_0,F,subFp0,subFi0,subState0,Delta_t,co,ip,el,A,B,C,DB) + broken = integrateStateRK(F_0,F,subFp0,subFi0,subState0,Delta_t,en,ph,A,B,C,DB) end function integrateStateRKCK45 @@ -831,7 +813,7 @@ end function integrateStateRKCK45 !> @brief Integrate state (including stress integration) with an explicit Runge-Kutta method or an !! embedded explicit Runge-Kutta method !-------------------------------------------------------------------------------------------------- -function integrateStateRK(F_0,F,subFp0,subFi0,subState0,Delta_t,co,ip,el,A,B,C,DB) result(broken) +function integrateStateRK(F_0,F,subFp0,subFi0,subState0,Delta_t,en,ph,A,B,C,DB) result(broken) real(pReal), intent(in),dimension(3,3) :: F_0,F,subFp0,subFi0 real(pReal), intent(in),dimension(:) :: subState0 @@ -840,9 +822,8 @@ function integrateStateRK(F_0,F,subFp0,subFi0,subState0,Delta_t,co,ip,el,A,B,C,D real(pReal), dimension(:), intent(in) :: B, C real(pReal), dimension(:), intent(in), optional :: DB integer, intent(in) :: & - el, & !< element index in element loop - ip, & !< integration point index in ip loop - co !< grain index in grain loop + en, & + ph logical :: broken integer :: & @@ -851,17 +832,15 @@ function integrateStateRK(F_0,F,subFp0,subFi0,subState0,Delta_t,co,ip,el,A,B,C,D ph, & en, & sizeDotState - real(pReal), dimension(plasticState(material_phaseID(co,(el-1)*discretization_nIPs+ip))%sizeDotState) :: & + real(pReal), dimension(plasticState(ph)%sizeDotState) :: & dotState - real(pReal), dimension(plasticState(material_phaseID(co,(el-1)*discretization_nIPs+ip))%sizeDotState,size(B)) :: & + real(pReal), dimension(plasticState(ph)%sizeDotState,size(B)) :: & plastic_RKdotState - ph = material_phaseID(co,(el-1)*discretization_nIPs + ip) - en = material_phaseEntry(co,(el-1)*discretization_nIPs + ip) broken = .true. - dotState = plastic_dotState(Delta_t, co,ip,el,ph,en) + dotState = plastic_dotState(Delta_t,ph,en) if (any(IEEE_is_NaN(dotState))) return sizeDotState = plasticState(ph)%sizeDotState @@ -879,10 +858,10 @@ function integrateStateRK(F_0,F,subFp0,subFi0,subState0,Delta_t,co,ip,el,A,B,C,D plasticState(ph)%state(1:sizeDotState,en) = subState0 & + dotState * Delta_t - broken = integrateStress(F_0 + (F - F_0) * Delta_t * C(stage),subFp0,subFi0,Delta_t * C(stage),co,ip,el) + broken = integrateStress(F_0 + (F - F_0) * Delta_t * C(stage),subFp0,subFi0,Delta_t * C(stage),en,ph) if(broken) exit - dotState = plastic_dotState(Delta_t, co,ip,el,ph,en) + dotState = plastic_dotState(Delta_t,ph,en) if (any(IEEE_is_NaN(dotState))) exit enddo @@ -904,7 +883,7 @@ function integrateStateRK(F_0,F,subFp0,subFi0,subState0,Delta_t,co,ip,el,A,B,C,D broken = plastic_deltaState(ph,en) if(broken) return - broken = integrateStress(F,subFp0,subFi0,Delta_t,co,ip,el) + broken = integrateStress(F,subFp0,subFi0,Delta_t,en,ph) end function integrateStateRK @@ -1031,8 +1010,6 @@ module function phase_mechanical_constitutive(Delta_t,co,ip,el) result(converged real(pReal), dimension(:), allocatable :: subState0 - ph = material_phaseID(co,(el-1)*discretization_nIPs + ip) - en = material_phaseEntry(co,(el-1)*discretization_nIPs + ip) sizeDotState = plasticState(ph)%sizeDotState subLi0 = phase_mechanical_Li0(ph)%data(1:3,1:3,en) @@ -1084,7 +1061,7 @@ module function phase_mechanical_constitutive(Delta_t,co,ip,el) result(converged if (todo) then subF = subF0 & + subStep * (phase_mechanical_F(ph)%data(1:3,1:3,en) - phase_mechanical_F0(ph)%data(1:3,1:3,en)) - converged_ = .not. integrateState(subF0,subF,subFp0,subFi0,subState0(1:sizeDotState),subStep * Delta_t,co,ip,el) + converged_ = .not. integrateState(subF0,subF,subFp0,subFi0,subState0(1:sizeDotState),subStep * Delta_t,en,ph) endif enddo cutbackLooping diff --git a/src/phase_mechanical_plastic.f90 b/src/phase_mechanical_plastic.f90 index a5f40a2df..13f14717e 100644 --- a/src/phase_mechanical_plastic.f90 +++ b/src/phase_mechanical_plastic.f90 @@ -291,12 +291,9 @@ end subroutine plastic_LpAndItsTangents !-------------------------------------------------------------------------------------------------- !> @brief contains the constitutive equation for calculating the rate of change of microstructure !-------------------------------------------------------------------------------------------------- -module function plastic_dotState(subdt,co,ip,el,ph,en) result(dotState) +module function plastic_dotState(subdt,ph,en) result(dotState) integer, intent(in) :: & - co, & !< component-ID of integration point - ip, & !< integration point - el, & !< element ph, & en real(pReal), intent(in) :: & From 019ae1c536c26c5ed6662dbddad4d12736c7f5be Mon Sep 17 00:00:00 2001 From: Daniel Otto de Mentock Date: Fri, 4 Feb 2022 11:43:35 +0100 Subject: [PATCH 27/72] adjusted typecheck in __eq__ and __ne__ functions --- python/damask/_orientation.py | 6 ++---- python/damask/_rotation.py | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/python/damask/_orientation.py b/python/damask/_orientation.py index 4817ddb6f..2221af8a4 100644 --- a/python/damask/_orientation.py +++ b/python/damask/_orientation.py @@ -148,7 +148,7 @@ class Orientation(Rotation,Crystal): """ if not isinstance(other, Orientation): - return NotImplemented + raise NotImplementedError matching_type = self.family == other.family and \ self.lattice == other.lattice and \ self.parameters == other.parameters @@ -165,9 +165,7 @@ class Orientation(Rotation,Crystal): Orientation to check for equality. """ - eq = self.__eq__(other) - if not isinstance(eq, bool): - return eq + self.__eq__(other) return np.logical_not(self==other) diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index d40b48669..5efaf9d9e 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -124,7 +124,7 @@ class Rotation: """ if not isinstance(other, Rotation): - return NotImplemented + raise NotImplementedError return np.logical_or(np.all(self.quaternion == other.quaternion,axis=-1), np.all(self.quaternion == -1.0*other.quaternion,axis=-1)) @@ -139,9 +139,7 @@ class Rotation: Rotation to check for inequality. """ - eq = self.__eq__(other) - if not isinstance(eq, bool): - return eq + self.__eq__(other) return np.logical_not(self==other) From afed13e2ca5d6c33bc5b85e339512b99e29eca03 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 4 Feb 2022 12:25:11 +0100 Subject: [PATCH 28/72] ip/el not of interest --- src/homogenization.f90 | 4 ++-- src/phase.f90 | 8 ++++---- src/phase_damage.f90 | 9 ++++----- src/phase_mechanical.f90 | 17 ++++------------- 4 files changed, 14 insertions(+), 24 deletions(-) diff --git a/src/homogenization.f90 b/src/homogenization.f90 index 3d96b007f..1f9fb2221 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -259,7 +259,7 @@ subroutine homogenization_mechanical_response(Delta_t,FEsolving_execIP,FEsolving NiterationMPstate = NiterationMPstate + 1 call mechanical_partition(homogenization_F(1:3,1:3,ce),ce) - converged = all([(phase_mechanical_constitutive(Delta_t,co,ip,el),co=1,homogenization_Nconstituents(ho))]) + converged = all([(phase_mechanical_constitutive(Delta_t,co,ce),co=1,homogenization_Nconstituents(ho))]) if (converged) then doneAndHappy = mechanical_updateState(Delta_t,homogenization_F(1:3,1:3,ce),ce) converged = all(doneAndHappy) @@ -268,7 +268,7 @@ subroutine homogenization_mechanical_response(Delta_t,FEsolving_execIP,FEsolving endif enddo convergenceLooping - converged = converged .and. all([(phase_damage_constitutive(Delta_t,co,ip,el),co=1,homogenization_Nconstituents(ho))]) + converged = converged .and. all([(phase_damage_constitutive(Delta_t,co,ce),co=1,homogenization_Nconstituents(ho))]) if (.not. converged) then if (.not. terminallyIll) print*, ' Cell ', ce, ' terminally ill' diff --git a/src/phase.f90 b/src/phase.f90 index 4d180d439..8bc797e85 100644 --- a/src/phase.f90 +++ b/src/phase.f90 @@ -228,15 +228,15 @@ module phase end function phase_thermal_constitutive - module function phase_damage_constitutive(Delta_t,co,ip,el) result(converged_) + module function phase_damage_constitutive(Delta_t,co,ce) result(converged_) real(pReal), intent(in) :: Delta_t - integer, intent(in) :: co, ip, el + integer, intent(in) :: co, ce logical :: converged_ end function phase_damage_constitutive - module function phase_mechanical_constitutive(Delta_t,co,ip,el) result(converged_) + module function phase_mechanical_constitutive(Delta_t,co,ce) result(converged_) real(pReal), intent(in) :: Delta_t - integer, intent(in) :: co, ip, el + integer, intent(in) :: co, ce logical :: converged_ end function phase_mechanical_constitutive diff --git a/src/phase_damage.f90 b/src/phase_damage.f90 index 2fa5ab9ea..e4700938f 100644 --- a/src/phase_damage.f90 +++ b/src/phase_damage.f90 @@ -127,21 +127,20 @@ end subroutine damage_init !-------------------------------------------------------------------------------------------------- !> @brief calculate stress (P) !-------------------------------------------------------------------------------------------------- -module function phase_damage_constitutive(Delta_t,co,ip,el) result(converged_) +module function phase_damage_constitutive(Delta_t,co,ce) result(converged_) real(pReal), intent(in) :: Delta_t integer, intent(in) :: & co, & - ip, & - el + ce logical :: converged_ integer :: & ph, en - ph = material_phaseID(co,(el-1)*discretization_nIPs + ip) - en = material_phaseEntry(co,(el-1)*discretization_nIPs + ip) + ph = material_phaseID(co,ce) + en = material_phaseEntry(co,ce) converged_ = .not. integrateDamageState(Delta_t,ph,en) diff --git a/src/phase_mechanical.f90 b/src/phase_mechanical.f90 index 88e98cc2e..655f53ad8 100644 --- a/src/phase_mechanical.f90 +++ b/src/phase_mechanical.f90 @@ -414,8 +414,6 @@ function integrateStress(F,subFp0,subFi0,Delta_t,en,ph) result(broken) ierr, & ! error indicator for LAPACK o, & p, & - ph, & - en, & jacoCounterLp, & jacoCounterLi ! counters to check for Jacobian update logical :: error,broken @@ -583,8 +581,6 @@ function integrateStateFPI(F_0,F,subFp0,subFi0,subState0,Delta_t,en,ph) result(b integer :: & NiterationState, & !< number of iterations in state loop - ph, & - en, & sizeDotState real(pReal) :: & zeta @@ -674,8 +670,6 @@ function integrateStateEuler(F_0,F,subFp0,subFi0,subState0,Delta_t,en,ph) result real(pReal), dimension(plasticState(ph)%sizeDotState) :: & dotState integer :: & - ph, & - en, & sizeDotState @@ -711,8 +705,6 @@ function integrateStateAdaptiveEuler(F_0,F,subFp0,subFi0,subState0,Delta_t,en,ph broken integer :: & - ph, & - en, & sizeDotState real(pReal), dimension(plasticState(ph)%sizeDotState) :: & r, & @@ -829,8 +821,6 @@ function integrateStateRK(F_0,F,subFp0,subFi0,subState0,Delta_t,en,ph,A,B,C,DB) integer :: & stage, & ! stage index in integration stage loop n, & - ph, & - en, & sizeDotState real(pReal), dimension(plasticState(ph)%sizeDotState) :: & dotState @@ -985,13 +975,12 @@ end subroutine mechanical_forward !-------------------------------------------------------------------------------------------------- !> @brief calculate stress (P) !-------------------------------------------------------------------------------------------------- -module function phase_mechanical_constitutive(Delta_t,co,ip,el) result(converged_) +module function phase_mechanical_constitutive(Delta_t,co,ce) result(converged_) real(pReal), intent(in) :: Delta_t integer, intent(in) :: & co, & - ip, & - el + ce logical :: converged_ real(pReal) :: & @@ -1010,6 +999,8 @@ module function phase_mechanical_constitutive(Delta_t,co,ip,el) result(converged real(pReal), dimension(:), allocatable :: subState0 + ph = material_phaseID(co,ce) + en = material_phaseEntry(co,ce) sizeDotState = plasticState(ph)%sizeDotState subLi0 = phase_mechanical_Li0(ph)%data(1:3,1:3,en) From c1c23366383f96182fee8ff8411d83ab58b94b79 Mon Sep 17 00:00:00 2001 From: Daniel Otto de Mentock Date: Fri, 4 Feb 2022 16:57:25 +0100 Subject: [PATCH 29/72] reverted __eq__ and __ne type verification to return NotImplemented constant changed rotation.average input type to FloatSequence minor adjustments --- python/damask/_orientation.py | 10 ++++------ python/damask/_rotation.py | 24 ++++++++++++------------ 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/python/damask/_orientation.py b/python/damask/_orientation.py index 2221af8a4..d90cc70e6 100644 --- a/python/damask/_orientation.py +++ b/python/damask/_orientation.py @@ -148,7 +148,7 @@ class Orientation(Rotation,Crystal): """ if not isinstance(other, Orientation): - raise NotImplementedError + return NotImplemented matching_type = self.family == other.family and \ self.lattice == other.lattice and \ self.parameters == other.parameters @@ -165,8 +165,7 @@ class Orientation(Rotation,Crystal): Orientation to check for equality. """ - self.__eq__(other) - return np.logical_not(self==other) + return np.logical_not(self==other) if isinstance(other, Orientation) else NotImplemented def isclose(self, @@ -498,7 +497,7 @@ class Orientation(Rotation,Crystal): return np.ones_like(rho[...,0],dtype=bool) def disorientation(self, - other: "Orientation", + other: 'Orientation', return_operators: bool = False) -> object: """ Calculate disorientation between myself and given other orientation. @@ -612,8 +611,7 @@ class Orientation(Rotation,Crystal): """ eq = self.equivalent m = eq.misorientation(self[...,0].reshape((1,)+self.shape[:-1]+(1,)) - .broadcast_to(eq.shape))\ - .as_axis_angle()[...,3] + .broadcast_to(eq.shape)).as_axis_angle()[...,3] r = Rotation(np.squeeze(np.take_along_axis(eq.quaternion, np.argmin(m,axis=0)[np.newaxis,...,np.newaxis], axis=0), diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index 5efaf9d9e..53902def7 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -124,12 +124,13 @@ class Rotation: """ if not isinstance(other, Rotation): - raise NotImplementedError + return NotImplemented return np.logical_or(np.all(self.quaternion == other.quaternion,axis=-1), np.all(self.quaternion == -1.0*other.quaternion,axis=-1)) - def __ne__(self, other: object) -> bool: + def __ne__(self, + other: object) -> bool: """ Not equal to other. @@ -139,9 +140,7 @@ class Rotation: Rotation to check for inequality. """ - self.__eq__(other) - return np.logical_not(self==other) - + return np.logical_not(self==other) if isinstance(other, Rotation) else NotImplemented def isclose(self, other: 'Rotation', @@ -257,7 +256,8 @@ class Rotation: return self**exp - def __mul__(self: MyType, other: MyType) -> MyType: + def __mul__(self: MyType, + other: MyType) -> MyType: """ Compose with other. @@ -332,7 +332,8 @@ class Rotation: return self/other - def __matmul__(self, other: np.ndarray) -> np.ndarray: + def __matmul__(self, + other: np.ndarray) -> np.ndarray: """ Rotate vector, second order tensor, or fourth order tensor. @@ -451,7 +452,7 @@ class Rotation: def average(self, - weights: np.ndarray = None) -> 'Rotation': + weights: FloatSequence = None) -> 'Rotation': """ Average along last array dimension. @@ -475,11 +476,10 @@ class Rotation: """Intermediate representation supporting quaternion averaging.""" return np.einsum('...i,...j',quat,quat) - if weights is None: - weights = np.ones(self.shape,dtype=float) + weights_ = np.ones(self.shape,dtype=float) if weights is None else np.array(weights,float) - eig, vec = np.linalg.eig(np.sum(_M(self.quaternion) * weights[...,np.newaxis,np.newaxis],axis=-3) \ - /np.sum( weights[...,np.newaxis,np.newaxis],axis=-3)) + eig, vec = np.linalg.eig(np.sum(_M(self.quaternion) * weights_[...,np.newaxis,np.newaxis],axis=-3) \ + /np.sum( weights_[...,np.newaxis,np.newaxis],axis=-3)) return Rotation.from_quaternion(np.real( np.squeeze( From 72978df099a7c86958d4c315facbfe1c90c91e69 Mon Sep 17 00:00:00 2001 From: Daniel Otto de Mentock Date: Fri, 4 Feb 2022 17:41:29 +0100 Subject: [PATCH 30/72] minor correction --- python/damask/_rotation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index 53902def7..226d66f69 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -458,7 +458,7 @@ class Rotation: Parameters ---------- - weights : numpy.ndarray, optional + weights : FloatSequence, optional Relative weight of each rotation. Returns From 3990536f1ca90d6e2f9709bd8b9b2f54732819e8 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 4 Feb 2022 17:42:05 +0100 Subject: [PATCH 31/72] consistent order of arguments --- src/phase.f90 | 8 ++--- src/phase_mechanical.f90 | 54 ++++++++++++++++---------------- src/phase_mechanical_plastic.f90 | 8 ++--- 3 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/phase.f90 b/src/phase.f90 index 8bc797e85..c4e7142f8 100644 --- a/src/phase.f90 +++ b/src/phase.f90 @@ -272,10 +272,10 @@ module phase type(tRotationContainer), dimension(:), intent(in) :: orientation end subroutine plastic_nonlocal_updateCompatibility - module subroutine plastic_dependentState(en,ph) + module subroutine plastic_dependentState(ph,en) integer, intent(in) :: & - en, & - ph + ph, & + en end subroutine plastic_dependentState module subroutine damage_anisobrittle_LiAndItsTangent(Ld, dLd_dTstar, S, ph,en) @@ -562,7 +562,7 @@ subroutine crystallite_init() en = material_phaseEntry(co,ce) ph = material_phaseID(co,ce) call crystallite_orientations(co,ip,el) - call plastic_dependentState(en,ph) ! update dependent state variables to be consistent with basic states + call plastic_dependentState(ph,en) ! update dependent state variables to be consistent with basic states end do end do end do diff --git a/src/phase_mechanical.f90 b/src/phase_mechanical.f90 index 655f53ad8..de9c2bea2 100644 --- a/src/phase_mechanical.f90 +++ b/src/phase_mechanical.f90 @@ -362,11 +362,11 @@ end subroutine mechanical_results !> @brief calculation of stress (P) with time integration based on a residuum in Lp and !> intermediate acceleration of the Newton-Raphson correction !-------------------------------------------------------------------------------------------------- -function integrateStress(F,subFp0,subFi0,Delta_t,en,ph) result(broken) +function integrateStress(F,subFp0,subFi0,Delta_t,ph,en) result(broken) real(pReal), dimension(3,3), intent(in) :: F,subFp0,subFi0 real(pReal), intent(in) :: Delta_t - integer, intent(in) :: en, ph + integer, intent(in) :: ph, en real(pReal), dimension(3,3):: Fp_new, & ! plastic deformation gradient at end of timestep invFp_new, & ! inverse of Fp_new @@ -420,7 +420,7 @@ function integrateStress(F,subFp0,subFi0,Delta_t,en,ph) result(broken) broken = .true. - call plastic_dependentState(en,ph) + call plastic_dependentState(ph,en) Lpguess = phase_mechanical_Lp(ph)%data(1:3,1:3,en) ! take as first guess Liguess = phase_mechanical_Li(ph)%data(1:3,1:3,en) ! take as first guess @@ -568,14 +568,14 @@ end function integrateStress !> @brief integrate stress, state with adaptive 1st order explicit Euler method !> using Fixed Point Iteration to adapt the stepsize !-------------------------------------------------------------------------------------------------- -function integrateStateFPI(F_0,F,subFp0,subFi0,subState0,Delta_t,en,ph) result(broken) +function integrateStateFPI(F_0,F,subFp0,subFi0,subState0,Delta_t,ph,en) result(broken) real(pReal), intent(in),dimension(3,3) :: F_0,F,subFp0,subFi0 real(pReal), intent(in),dimension(:) :: subState0 real(pReal), intent(in) :: Delta_t integer, intent(in) :: & - en, & - ph + ph, & + en logical :: & broken @@ -604,7 +604,7 @@ function integrateStateFPI(F_0,F,subFp0,subFi0,subState0,Delta_t,en,ph) result(b dotState_last(1:sizeDotState,2) = merge(dotState_last(1:sizeDotState,1),0.0, nIterationState > 1) dotState_last(1:sizeDotState,1) = dotState - broken = integrateStress(F,subFp0,subFi0,Delta_t,en,ph) + broken = integrateStress(F,subFp0,subFi0,Delta_t,ph,en) if(broken) exit iteration dotState = plastic_dotState(Delta_t,ph,en) @@ -656,14 +656,14 @@ end function integrateStateFPI !-------------------------------------------------------------------------------------------------- !> @brief integrate state with 1st order explicit Euler method !-------------------------------------------------------------------------------------------------- -function integrateStateEuler(F_0,F,subFp0,subFi0,subState0,Delta_t,en,ph) result(broken) +function integrateStateEuler(F_0,F,subFp0,subFi0,subState0,Delta_t,ph,en) result(broken) real(pReal), intent(in),dimension(3,3) :: F_0,F,subFp0,subFi0 real(pReal), intent(in),dimension(:) :: subState0 real(pReal), intent(in) :: Delta_t integer, intent(in) :: & - en, & - ph !< grain index in grain loop + ph, & + en !< grain index in grain loop logical :: & broken @@ -685,7 +685,7 @@ function integrateStateEuler(F_0,F,subFp0,subFi0,subState0,Delta_t,en,ph) result broken = plastic_deltaState(ph,en) if(broken) return - broken = integrateStress(F,subFp0,subFi0,Delta_t,en,ph) + broken = integrateStress(F,subFp0,subFi0,Delta_t,ph,en) end function integrateStateEuler @@ -693,14 +693,14 @@ end function integrateStateEuler !-------------------------------------------------------------------------------------------------- !> @brief integrate stress, state with 1st order Euler method with adaptive step size !-------------------------------------------------------------------------------------------------- -function integrateStateAdaptiveEuler(F_0,F,subFp0,subFi0,subState0,Delta_t,en,ph) result(broken) +function integrateStateAdaptiveEuler(F_0,F,subFp0,subFi0,subState0,Delta_t,ph,en) result(broken) real(pReal), intent(in),dimension(3,3) :: F_0,F,subFp0,subFi0 real(pReal), intent(in),dimension(:) :: subState0 real(pReal), intent(in) :: Delta_t integer, intent(in) :: & - en, & - ph + ph, & + en logical :: & broken @@ -725,7 +725,7 @@ function integrateStateAdaptiveEuler(F_0,F,subFp0,subFi0,subState0,Delta_t,en,ph broken = plastic_deltaState(ph,en) if(broken) return - broken = integrateStress(F,subFp0,subFi0,Delta_t,en,ph) + broken = integrateStress(F,subFp0,subFi0,Delta_t,ph,en) if(broken) return dotState = plastic_dotState(Delta_t,ph,en) @@ -741,12 +741,12 @@ end function integrateStateAdaptiveEuler !--------------------------------------------------------------------------------------------------- !> @brief Integrate state (including stress integration) with the classic Runge Kutta method !--------------------------------------------------------------------------------------------------- -function integrateStateRK4(F_0,F,subFp0,subFi0,subState0,Delta_t,en,ph) result(broken) +function integrateStateRK4(F_0,F,subFp0,subFi0,subState0,Delta_t,ph,en) result(broken) real(pReal), intent(in),dimension(3,3) :: F_0,F,subFp0,subFi0 real(pReal), intent(in),dimension(:) :: subState0 real(pReal), intent(in) :: Delta_t - integer, intent(in) :: en, ph + integer, intent(in) :: ph, en logical :: broken real(pReal), dimension(3,3), parameter :: & @@ -761,7 +761,7 @@ function integrateStateRK4(F_0,F,subFp0,subFi0,subState0,Delta_t,en,ph) result(b B = [1.0_pReal/6.0_pReal, 1.0_pReal/3.0_pReal, 1.0_pReal/3.0_pReal, 1.0_pReal/6.0_pReal] - broken = integrateStateRK(F_0,F,subFp0,subFi0,subState0,Delta_t,en,ph,A,B,C) + broken = integrateStateRK(F_0,F,subFp0,subFi0,subState0,Delta_t,ph,en,A,B,C) end function integrateStateRK4 @@ -769,12 +769,12 @@ end function integrateStateRK4 !--------------------------------------------------------------------------------------------------- !> @brief Integrate state (including stress integration) with the Cash-Carp method !--------------------------------------------------------------------------------------------------- -function integrateStateRKCK45(F_0,F,subFp0,subFi0,subState0,Delta_t,en,ph) result(broken) +function integrateStateRKCK45(F_0,F,subFp0,subFi0,subState0,Delta_t,ph,en) result(broken) real(pReal), intent(in),dimension(3,3) :: F_0,F,subFp0,subFi0 real(pReal), intent(in),dimension(:) :: subState0 real(pReal), intent(in) :: Delta_t - integer, intent(in) :: en, ph + integer, intent(in) :: ph, en logical :: broken real(pReal), dimension(5,5), parameter :: & @@ -796,7 +796,7 @@ function integrateStateRKCK45(F_0,F,subFp0,subFi0,subState0,Delta_t,en,ph) resul 13525.0_pReal/55296.0_pReal, 277.0_pReal/14336.0_pReal, 1._pReal/4._pReal] - broken = integrateStateRK(F_0,F,subFp0,subFi0,subState0,Delta_t,en,ph,A,B,C,DB) + broken = integrateStateRK(F_0,F,subFp0,subFi0,subState0,Delta_t,ph,en,A,B,C,DB) end function integrateStateRKCK45 @@ -805,7 +805,7 @@ end function integrateStateRKCK45 !> @brief Integrate state (including stress integration) with an explicit Runge-Kutta method or an !! embedded explicit Runge-Kutta method !-------------------------------------------------------------------------------------------------- -function integrateStateRK(F_0,F,subFp0,subFi0,subState0,Delta_t,en,ph,A,B,C,DB) result(broken) +function integrateStateRK(F_0,F,subFp0,subFi0,subState0,Delta_t,ph,en,A,B,C,DB) result(broken) real(pReal), intent(in),dimension(3,3) :: F_0,F,subFp0,subFi0 real(pReal), intent(in),dimension(:) :: subState0 @@ -814,8 +814,8 @@ function integrateStateRK(F_0,F,subFp0,subFi0,subState0,Delta_t,en,ph,A,B,C,DB) real(pReal), dimension(:), intent(in) :: B, C real(pReal), dimension(:), intent(in), optional :: DB integer, intent(in) :: & - en, & - ph + ph, & + en logical :: broken integer :: & @@ -848,7 +848,7 @@ function integrateStateRK(F_0,F,subFp0,subFi0,subState0,Delta_t,en,ph,A,B,C,DB) plasticState(ph)%state(1:sizeDotState,en) = subState0 & + dotState * Delta_t - broken = integrateStress(F_0 + (F - F_0) * Delta_t * C(stage),subFp0,subFi0,Delta_t * C(stage),en,ph) + broken = integrateStress(F_0 + (F - F_0) * Delta_t * C(stage),subFp0,subFi0,Delta_t * C(stage),ph,en) if(broken) exit dotState = plastic_dotState(Delta_t,ph,en) @@ -873,7 +873,7 @@ function integrateStateRK(F_0,F,subFp0,subFi0,subState0,Delta_t,en,ph,A,B,C,DB) broken = plastic_deltaState(ph,en) if(broken) return - broken = integrateStress(F,subFp0,subFi0,Delta_t,en,ph) + broken = integrateStress(F,subFp0,subFi0,Delta_t,ph,en) end function integrateStateRK @@ -1052,7 +1052,7 @@ module function phase_mechanical_constitutive(Delta_t,co,ce) result(converged_) if (todo) then subF = subF0 & + subStep * (phase_mechanical_F(ph)%data(1:3,1:3,en) - phase_mechanical_F0(ph)%data(1:3,1:3,en)) - converged_ = .not. integrateState(subF0,subF,subFp0,subFi0,subState0(1:sizeDotState),subStep * Delta_t,en,ph) + converged_ = .not. integrateState(subF0,subF,subFp0,subFi0,subState0(1:sizeDotState),subStep * Delta_t,ph,en) endif enddo cutbackLooping diff --git a/src/phase_mechanical_plastic.f90 b/src/phase_mechanical_plastic.f90 index 13f14717e..973f0ddbf 100644 --- a/src/phase_mechanical_plastic.f90 +++ b/src/phase_mechanical_plastic.f90 @@ -178,7 +178,7 @@ submodule(phase:mechanical) plastic en end subroutine dislotungsten_dependentState - module subroutine nonlocal_dependentState(ph, en) + module subroutine nonlocal_dependentState(ph,en) integer, intent(in) :: & ph, & en @@ -338,11 +338,11 @@ end function plastic_dotState !-------------------------------------------------------------------------------------------------- !> @brief calls microstructure function of the different plasticity constitutive models !-------------------------------------------------------------------------------------------------- -module subroutine plastic_dependentState(en,ph) +module subroutine plastic_dependentState(ph,en) integer, intent(in) :: & - en, & - ph + ph, & + en plasticType: select case (phase_plasticity(ph)) From 3c148b5b0e0e4229cafe97adea42d5731ab9056d Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 4 Feb 2022 18:55:59 +0100 Subject: [PATCH 32/72] bugfix: openMP variable was not protected --- src/homogenization.f90 | 2 +- src/phase.f90 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/homogenization.f90 b/src/homogenization.f90 index 1f9fb2221..8c9ecaecb 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -237,7 +237,7 @@ subroutine homogenization_mechanical_response(Delta_t,FEsolving_execIP,FEsolving doneAndHappy - !$OMP PARALLEL DO PRIVATE(ce,en,ho,NiterationMPstate,converged,doneAndHappy) + !$OMP PARALLEL DO PRIVATE(ce,co,en,ho,NiterationMPstate,converged,doneAndHappy) do el = FEsolving_execElem(1),FEsolving_execElem(2) do ip = FEsolving_execIP(1),FEsolving_execIP(2) diff --git a/src/phase.f90 b/src/phase.f90 index c4e7142f8..9943c777a 100644 --- a/src/phase.f90 +++ b/src/phase.f90 @@ -554,7 +554,7 @@ subroutine crystallite_init() flush(IO_STDOUT) - !$OMP PARALLEL DO PRIVATE(ce) + !$OMP PARALLEL DO PRIVATE(ce,ph,en) do el = 1, eMax do ip = 1, iMax ce = (el-1)*discretization_nIPs + ip From 6d78400f875b7642baf9d3ad5ad86111c403ea5e Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 5 Feb 2022 07:29:00 +0100 Subject: [PATCH 33/72] the concept of IP/element_ID should not be used at the DAMASK core --- src/CPFEM.f90 | 3 +- src/grid/spectral_utilities.f90 | 4 +- src/homogenization.f90 | 106 +++++++++++++++----------------- src/mesh/FEM_utilities.f90 | 2 +- 4 files changed, 53 insertions(+), 62 deletions(-) diff --git a/src/CPFEM.f90 b/src/CPFEM.f90 index 0f7590782..8f10d39b2 100644 --- a/src/CPFEM.f90 +++ b/src/CPFEM.f90 @@ -193,11 +193,10 @@ subroutine CPFEM_general(mode, ffn, ffn1, temperature_inp, dt, elFE, ip, cauchyS else validCalculation if (debugCPFEM%extensive) print'(a,i8,1x,i2)', '<< CPFEM >> calculation for elFE ip ',elFE,ip - call homogenization_mechanical_response(dt,[ip,ip],[elCP,elCP]) + call homogenization_mechanical_response(dt,(elCP-1)*discretization_nIPs + ip,(elCP-1)*discretization_nIPs + ip) if (.not. terminallyIll) & call homogenization_mechanical_response2(dt,[ip,ip],[elCP,elCP]) - terminalIllness: if (terminallyIll) then call random_number(rnd) diff --git a/src/grid/spectral_utilities.f90 b/src/grid/spectral_utilities.f90 index d95580145..34a976644 100644 --- a/src/grid/spectral_utilities.f90 +++ b/src/grid/spectral_utilities.f90 @@ -812,9 +812,9 @@ subroutine utilities_constitutiveResponse(P,P_av,C_volAvg,C_minmaxAvg,& homogenization_F = reshape(F,[3,3,product(cells(1:2))*cells3]) ! set materialpoint target F to estimated field - call homogenization_mechanical_response(Delta_t,[1,1],[1,product(cells(1:2))*cells3]) ! calculate P field + call homogenization_mechanical_response(Delta_t,1,product(cells(1:2))*cells3) ! calculate P field if (.not. terminallyIll) & - call homogenization_thermal_response(Delta_t,[1,1],[1,product(cells(1:2))*cells3]) + call homogenization_thermal_response(Delta_t,1,product(cells(1:2))*cells3) if (.not. terminallyIll) & call homogenization_mechanical_response2(Delta_t,[1,1],[1,product(cells(1:2))*cells3]) diff --git a/src/homogenization.f90 b/src/homogenization.f90 index 8c9ecaecb..8539df994 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -222,14 +222,13 @@ end subroutine homogenization_init !-------------------------------------------------------------------------------------------------- !> @brief !-------------------------------------------------------------------------------------------------- -subroutine homogenization_mechanical_response(Delta_t,FEsolving_execIP,FEsolving_execElem) +subroutine homogenization_mechanical_response(Delta_t,cell_start,cell_end) real(pReal), intent(in) :: Delta_t !< time increment - integer, dimension(2), intent(in) :: FEsolving_execElem, FEsolving_execIP + integer, intent(in) :: & + cell_start, cell_end integer :: & NiterationMPstate, & - ip, & !< integration point number - el, & !< element number co, ce, ho, en logical :: & converged @@ -237,45 +236,42 @@ subroutine homogenization_mechanical_response(Delta_t,FEsolving_execIP,FEsolving doneAndHappy - !$OMP PARALLEL DO PRIVATE(ce,co,en,ho,NiterationMPstate,converged,doneAndHappy) - do el = FEsolving_execElem(1),FEsolving_execElem(2) + !$OMP PARALLEL DO PRIVATE(en,ho,co,NiterationMPstate,converged,doneAndHappy) + do ce = cell_start, cell_end - do ip = FEsolving_execIP(1),FEsolving_execIP(2) - ce = (el-1)*discretization_nIPs + ip - en = material_homogenizationEntry(ce) - ho = material_homogenizationID(ce) + en = material_homogenizationEntry(ce) + ho = material_homogenizationID(ce) - call phase_restore(ce,.false.) ! wrong name (is more a forward function) + call phase_restore(ce,.false.) ! wrong name (is more a forward function) - if(homogState(ho)%sizeState > 0) homogState(ho)%state(:,en) = homogState(ho)%state0(:,en) - if(damageState_h(ho)%sizeState > 0) damageState_h(ho)%state(:,en) = damageState_h(ho)%state0(:,en) - call damage_partition(ce) + if(homogState(ho)%sizeState > 0) homogState(ho)%state(:,en) = homogState(ho)%state0(:,en) + if(damageState_h(ho)%sizeState > 0) damageState_h(ho)%state(:,en) = damageState_h(ho)%state0(:,en) + call damage_partition(ce) - doneAndHappy = [.false.,.true.] + doneAndHappy = [.false.,.true.] - NiterationMPstate = 0 - convergenceLooping: do while (.not. (terminallyIll .or. doneAndHappy(1)) & - .and. NiterationMPstate < num%nMPstate) - NiterationMPstate = NiterationMPstate + 1 + NiterationMPstate = 0 + convergenceLooping: do while (.not. (terminallyIll .or. doneAndHappy(1)) & + .and. NiterationMPstate < num%nMPstate) + NiterationMPstate = NiterationMPstate + 1 - call mechanical_partition(homogenization_F(1:3,1:3,ce),ce) - converged = all([(phase_mechanical_constitutive(Delta_t,co,ce),co=1,homogenization_Nconstituents(ho))]) - if (converged) then - doneAndHappy = mechanical_updateState(Delta_t,homogenization_F(1:3,1:3,ce),ce) - converged = all(doneAndHappy) - else - doneAndHappy = [.true.,.false.] - endif - enddo convergenceLooping + call mechanical_partition(homogenization_F(1:3,1:3,ce),ce) + converged = all([(phase_mechanical_constitutive(Delta_t,co,ce),co=1,homogenization_Nconstituents(ho))]) + if (converged) then + doneAndHappy = mechanical_updateState(Delta_t,homogenization_F(1:3,1:3,ce),ce) + converged = all(doneAndHappy) + else + doneAndHappy = [.true.,.false.] + end if + end do convergenceLooping - converged = converged .and. all([(phase_damage_constitutive(Delta_t,co,ce),co=1,homogenization_Nconstituents(ho))]) + converged = converged .and. all([(phase_damage_constitutive(Delta_t,co,ce),co=1,homogenization_Nconstituents(ho))]) - if (.not. converged) then - if (.not. terminallyIll) print*, ' Cell ', ce, ' terminally ill' - terminallyIll = .true. - endif - enddo - enddo + if (.not. converged) then + if (.not. terminallyIll) print*, ' Cell ', ce, ' terminally ill' + terminallyIll = .true. + end if + end do !$OMP END PARALLEL DO end subroutine homogenization_mechanical_response @@ -284,31 +280,27 @@ end subroutine homogenization_mechanical_response !-------------------------------------------------------------------------------------------------- !> @brief !-------------------------------------------------------------------------------------------------- -subroutine homogenization_thermal_response(Delta_t,FEsolving_execIP,FEsolving_execElem) +subroutine homogenization_thermal_response(Delta_t,cell_start,cell_end) real(pReal), intent(in) :: Delta_t !< time increment - integer, dimension(2), intent(in) :: FEsolving_execElem, FEsolving_execIP + integer, intent(in) :: & + cell_start, cell_end integer :: & - ip, & !< integration point number - el, & !< element number co, ce, ho - !$OMP PARALLEL DO PRIVATE(ho,ce) - do el = FEsolving_execElem(1),FEsolving_execElem(2) + !$OMP PARALLEL DO PRIVATE(ho) + do ce = cell_start, cell_end if (terminallyIll) continue - do ip = FEsolving_execIP(1),FEsolving_execIP(2) - ce = (el-1)*discretization_nIPs + ip - ho = material_homogenizationID(ce) - call thermal_partition(ce) - do co = 1, homogenization_Nconstituents(ho) - if (.not. phase_thermal_constitutive(Delta_t,material_phaseID(co,ce),material_phaseEntry(co,ce))) then - if (.not. terminallyIll) print*, ' Cell ', ce, ' terminally ill' - terminallyIll = .true. - endif - enddo - enddo - enddo + ho = material_homogenizationID(ce) + call thermal_partition(ce) + do co = 1, homogenization_Nconstituents(ho) + if (.not. phase_thermal_constitutive(Delta_t,material_phaseID(co,ce),material_phaseEntry(co,ce))) then + if (.not. terminallyIll) print*, ' Cell ', ce, ' terminally ill' + terminallyIll = .true. + end if + end do + end do !$OMP END PARALLEL DO end subroutine homogenization_thermal_response @@ -331,11 +323,11 @@ subroutine homogenization_mechanical_response2(Delta_t,FEsolving_execIP,FEsolvin elementLooping3: do el = FEsolving_execElem(1),FEsolving_execElem(2) IpLooping3: do ip = FEsolving_execIP(1),FEsolving_execIP(2) ce = (el-1)*discretization_nIPs + ip - ho = material_homogenizationID(ce) - do co = 1, homogenization_Nconstituents(ho) - call crystallite_orientations(co,ip,el) + ho = material_homogenizationID(ce) + do co = 1, homogenization_Nconstituents(ho) + call crystallite_orientations(co,ip,el) enddo - call mechanical_homogenize(Delta_t,ce) + call mechanical_homogenize(Delta_t,ce) enddo IpLooping3 enddo elementLooping3 !$OMP END PARALLEL DO diff --git a/src/mesh/FEM_utilities.f90 b/src/mesh/FEM_utilities.f90 index 703c6c818..4e31a0475 100644 --- a/src/mesh/FEM_utilities.f90 +++ b/src/mesh/FEM_utilities.f90 @@ -150,7 +150,7 @@ subroutine utilities_constitutiveResponse(timeinc,P_av,forwardData) print'(/,1x,a)', '... evaluating constitutive response ......................................' - call homogenization_mechanical_response(timeinc,[1,mesh_maxNips],[1,mesh_NcpElems]) ! calculate P field + call homogenization_mechanical_response(timeinc,1,mesh_maxNips*mesh_NcpElems) ! calculate P field if (.not. terminallyIll) & call homogenization_mechanical_response2(timeinc,[1,mesh_maxNips],[1,mesh_NcpElems]) cutBack = .false. From 5f0a630fa6000a236bb359c83603cd74966b6d52 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 5 Feb 2022 08:12:35 +0100 Subject: [PATCH 34/72] remove deprecated phaseAt/phaseMemberAt --- src/phase_mechanical_plastic_nonlocal.f90 | 26 +++++++++++------------ 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/phase_mechanical_plastic_nonlocal.f90 b/src/phase_mechanical_plastic_nonlocal.f90 index dec7ea8e7..9d809e0dc 100644 --- a/src/phase_mechanical_plastic_nonlocal.f90 +++ b/src/phase_mechanical_plastic_nonlocal.f90 @@ -659,10 +659,10 @@ module subroutine nonlocal_dependentState(ph, en) do n = 1,nIPneighbors neighbor_el = geom(ph)%IPneighborhood(1,n,en) neighbor_ip = geom(ph)%IPneighborhood(2,n,en) - no = material_phasememberAt(1,neighbor_ip,neighbor_el) - if (neighbor_el > 0 .and. neighbor_ip > 0) then - if (material_phaseAt(1,neighbor_el) == ph) then + if (neighbor_el > 0 .and. neighbor_ip > 0) then + if (material_phaseID(1,(neighbor_el-1)*discretization_nIPs + neighbor_ip) == ph) then + no = material_phaseEntry(1,(neighbor_el-1)*discretization_nIPs + neighbor_ip) nRealNeighbors = nRealNeighbors + 1.0_pReal rho_neighbor0 = getRho0(ph,no) @@ -1145,7 +1145,6 @@ function rhoDotFlux(timestep,ph,en) en integer :: & - neighbor_ph, & !< phase of my neighbor's plasticity ns, & !< short notation for the total number of active slip systems c, & !< character of dislocation n, & !< index of my current neighbor @@ -1251,8 +1250,8 @@ function rhoDotFlux(timestep,ph,en) neighbor_el = geom(ph)%IPneighborhood(1,n,en) neighbor_ip = geom(ph)%IPneighborhood(2,n,en) neighbor_n = geom(ph)%IPneighborhood(3,n,en) - np = material_phaseAt(1,neighbor_el) - no = material_phasememberAt(1,neighbor_ip,neighbor_el) + np = material_phaseID(1,(neighbor_el-1)*discretization_nIPs + neighbor_ip) + no = material_phaseEntry(1,(neighbor_el-1)*discretization_nIPs + neighbor_ip) opposite_neighbor = n + mod(n,2) - mod(n+1,2) opposite_el = geom(ph)%IPneighborhood(1,opposite_neighbor,en) @@ -1260,7 +1259,6 @@ function rhoDotFlux(timestep,ph,en) opposite_n = geom(ph)%IPneighborhood(3,opposite_neighbor,en) if (neighbor_n > 0) then ! if neighbor exists, average deformation gradient - neighbor_ph = material_phaseAt(1,neighbor_el) neighbor_F = phase_mechanical_F(np)%data(1:3,1:3,no) neighbor_Fe = matmul(neighbor_F, math_inv33(phase_mechanical_Fp(np)%data(1:3,1:3,no))) Favg = 0.5_pReal * (my_F + neighbor_F) @@ -1279,12 +1277,12 @@ function rhoDotFlux(timestep,ph,en) !* The entering flux from my neighbor will be distributed on my slip systems according to the !* compatibility if (neighbor_n > 0) then - if (phase_plasticity(material_phaseAt(1,neighbor_el)) == PLASTIC_NONLOCAL_ID .and. & + if (phase_plasticity(np) == PLASTIC_NONLOCAL_ID .and. & any(dependentState(ph)%compatibility(:,:,:,n,en) > 0.0_pReal)) then forall (s = 1:ns, t = 1:4) - neighbor_v0(s,t) = plasticState(np)%state0(iV (s,t,neighbor_ph),no) - neighbor_rhoSgl0(s,t) = max(plasticState(np)%state0(iRhoU(s,t,neighbor_ph),no),0.0_pReal) + neighbor_v0(s,t) = plasticState(np)%state0(iV (s,t,np),no) + neighbor_rhoSgl0(s,t) = max(plasticState(np)%state0(iRhoU(s,t,np),no),0.0_pReal) endforall where (neighbor_rhoSgl0 * IPvolume(neighbor_ip,neighbor_el) ** 0.667_pReal < prm%rho_min & @@ -1325,7 +1323,7 @@ function rhoDotFlux(timestep,ph,en) !* In case of reduced transmissivity, part of the leaving flux is stored as dead dislocation density. !* That means for an interface of zero transmissivity the leaving flux is fully converted to dead dislocations. if (opposite_n > 0) then - if (phase_plasticity(material_phaseAt(1,opposite_el)) == PLASTIC_NONLOCAL_ID) then + if (phase_plasticity(np) == PLASTIC_NONLOCAL_ID) then normal_me2neighbor_defConf = math_det33(Favg) & * matmul(math_inv33(transpose(Favg)),geom(ph)%IPareaNormal(1:3,n,en)) ! normal of the interface in (average) deformed configuration (pointing en => neighbor) @@ -1400,7 +1398,7 @@ module subroutine plastic_nonlocal_updateCompatibility(orientation,ph,ip,el) associate(prm => param(ph)) ns = prm%sum_N_sl - en = material_phaseMemberAt(1,ip,el) + en = material_phaseEntry(1,(el-1)*discretization_nIPs + ip) !*** start out fully compatible my_compatibility = 0.0_pReal forall(s1 = 1:ns) my_compatibility(:,s1,s1,:) = 1.0_pReal @@ -1408,8 +1406,8 @@ module subroutine plastic_nonlocal_updateCompatibility(orientation,ph,ip,el) neighbors: do n = 1,nIPneighbors neighbor_e = IPneighborhood(1,n,ip,el) neighbor_i = IPneighborhood(2,n,ip,el) - neighbor_me = material_phaseMemberAt(1,neighbor_i,neighbor_e) - neighbor_phase = material_phaseAt(1,neighbor_e) + neighbor_me = material_phaseEntry(1,(neighbor_e-1)*discretization_nIPs + neighbor_i) + neighbor_phase = material_phaseID(1,(neighbor_e-1)*discretization_nIPs + neighbor_i) if (neighbor_e <= 0 .or. neighbor_i <= 0) then !* FREE SURFACE From 6c032e3ce6f01f93d15c7a643b17c117ca54bebf Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 5 Feb 2022 09:03:10 +0100 Subject: [PATCH 35/72] remove deprecated mappings almost done with having a consistent access pattern solver ====== grid: x,y,z; mesh: el,ip homogenization ============== interface to solver: ce internal: ho,en phase ===== interface to homogenization: co,ce internal: ph,en --- src/material.f90 | 81 ++++++++++++++++++++++-------------------------- src/phase.f90 | 4 +-- 2 files changed, 39 insertions(+), 46 deletions(-) diff --git a/src/material.f90 b/src/material.f90 index fd1531964..bf78a77a6 100644 --- a/src/material.f90 +++ b/src/material.f90 @@ -17,16 +17,17 @@ module material implicit none private - type :: tRotationContainer - type(tRotation), dimension(:), allocatable :: data - end type - type :: tTensorContainer + type, public :: tRotationContainer + type(tRotation), dimension(:), allocatable :: data + end type tRotationContainer + + type, public :: tTensorContainer real(pReal), dimension(:,:,:), allocatable :: data - end type + end type tTensorContainer - type(tRotationContainer), dimension(:), allocatable :: material_O_0 - type(tTensorContainer), dimension(:), allocatable :: material_F_i_0 + type(tRotationContainer), dimension(:), allocatable, public, protected :: material_O_0 + type(tTensorContainer), dimension(:), allocatable, public, protected :: material_F_i_0 integer, dimension(:), allocatable, public, protected :: & homogenization_Nconstituents !< number of grains in each homogenization @@ -37,20 +38,14 @@ module material material_name_phase, & !< name of each phase material_name_homogenization !< name of each homogenization - integer, dimension(:), allocatable, public, protected :: & ! (elem) - material_homogenizationID, & !< per cell TODO: material_ID_homogenization - material_homogenizationEntry !< per cell TODO: material_entry_homogenization - integer, dimension(:,:), allocatable, public, protected :: & ! (constituent,elem) - material_phaseAt, & !< phase ID of each element TODO: remove - material_phaseID, & !< per (constituent,cell) TODO: material_ID_phase - material_phaseEntry !< per (constituent,cell) TODO: material_entry_phase - integer, dimension(:,:,:), allocatable, public, protected :: & ! (constituent,IP,elem) - material_phaseMemberAt !TODO: remove + integer, dimension(:), allocatable, public, protected :: & ! (cell) + material_homogenizationID, & ! TODO: rename to material_ID_homogenization + material_homogenizationEntry ! TODO: rename to material_entry_homogenization + integer, dimension(:,:), allocatable, public, protected :: & ! (constituent,cell) + material_phaseID, & ! TODO: rename to material_ID_phase + material_phaseEntry ! TODO: rename to material_entry_phase + public :: & - tTensorContainer, & - tRotationContainer, & - material_F_i_0, & - material_O_0, & material_init contains @@ -97,11 +92,12 @@ subroutine parse() counterPhase, & counterHomogenization - real(pReal) :: & - frac + real(pReal) :: v integer :: & - el, ip, co, ma, & - h, ce + el, ip, & + ho, ph, & + co, ce, & + ma materials => config_material%get('material') phases => config_material%get('phase') @@ -118,51 +114,48 @@ subroutine parse() #endif allocate(homogenization_Nconstituents(homogenizations%length)) - do h=1, homogenizations%length - homogenization => homogenizations%get(h) - homogenization_Nconstituents(h) = homogenization%get_asInt('N_constituents') + do ho=1, homogenizations%length + homogenization => homogenizations%get(ho) + homogenization_Nconstituents(ho) = homogenization%get_asInt('N_constituents') end do homogenization_maxNconstituents = maxval(homogenization_Nconstituents) allocate(counterPhase(phases%length),source=0) allocate(counterHomogenization(homogenizations%length),source=0) - allocate(material_phaseAt(homogenization_maxNconstituents,discretization_Nelems),source=0) - allocate(material_phaseMemberAt(homogenization_maxNconstituents,discretization_nIPs,discretization_Nelems),source=0) - - allocate(material_homogenizationID(discretization_nIPs*discretization_Nelems),source=0) allocate(material_homogenizationEntry(discretization_nIPs*discretization_Nelems),source=0) + allocate(material_phaseID(homogenization_maxNconstituents,discretization_nIPs*discretization_Nelems),source=0) allocate(material_phaseEntry(homogenization_maxNconstituents,discretization_nIPs*discretization_Nelems),source=0) do el = 1, discretization_Nelems - material => materials%get(discretization_materialAt(el)) - constituents => material%get('constituents') + material => materials%get(discretization_materialAt(el)) + ho = homogenizations%getIndex(material%get_asString('homogenization')) do ip = 1, discretization_nIPs ce = (el-1)*discretization_nIPs + ip - material_homogenizationID(ce) = homogenizations%getIndex(material%get_asString('homogenization')) - counterHomogenization(material_homogenizationID(ce)) = counterHomogenization(material_homogenizationID(ce)) + 1 - material_homogenizationEntry(ce) = counterHomogenization(material_homogenizationID(ce)) + material_homogenizationID(ce) = ho + counterHomogenization(ho) = counterHomogenization(ho) + 1 + material_homogenizationEntry(ce) = counterHomogenization(ho) end do - frac = 0.0_pReal + v = 0.0_pReal + constituents => material%get('constituents') do co = 1, constituents%length constituent => constituents%get(co) - frac = frac + constituent%get_asFloat('v') + v = v + constituent%get_asFloat('v') - material_phaseAt(co,el) = phases%getIndex(constituent%get_asString('phase')) + ph = phases%getIndex(constituent%get_asString('phase')) do ip = 1, discretization_nIPs ce = (el-1)*discretization_nIPs + ip - counterPhase(material_phaseAt(co,el)) = counterPhase(material_phaseAt(co,el)) + 1 - material_phaseMemberAt(co,ip,el) = counterPhase(material_phaseAt(co,el)) - material_phaseEntry(co,ce) = counterPhase(material_phaseAt(co,el)) - material_phaseID(co,ce) = material_phaseAt(co,el) + material_phaseID(co,ce) = ph + counterPhase(ph) = counterPhase(ph) + 1 + material_phaseEntry(co,ce) = counterPhase(ph) end do end do - if (dNeq(frac,1.0_pReal,1.e-12_pReal)) call IO_error(153,ext_msg='constituent') + if (dNeq(v,1.0_pReal,1.e-12_pReal)) call IO_error(153,ext_msg='constituent') end do diff --git a/src/phase.f90 b/src/phase.f90 index 9943c777a..354c738f1 100644 --- a/src/phase.f90 +++ b/src/phase.f90 @@ -590,8 +590,8 @@ subroutine crystallite_orientations(co,ip,el) call phase_O(ph)%data(en)%fromMatrix(transpose(math_rotationalPart(mechanical_F_e(ph,en)))) - if (plasticState(material_phaseAt(1,el))%nonlocal) & - call plastic_nonlocal_updateCompatibility(phase_O,material_phaseAt(1,el),ip,el) + if (plasticState(material_phaseID(1,(el-1)*discretization_nIPs + ip))%nonlocal) & + call plastic_nonlocal_updateCompatibility(phase_O,material_phaseID(1,(el-1)*discretization_nIPs + ip),ip,el) end subroutine crystallite_orientations From 9386ba5ef5a453e338d4f1f5c189025bee042f64 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 6 Feb 2022 12:59:41 +0100 Subject: [PATCH 36/72] allocate not needed --- src/phase_mechanical.f90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/phase_mechanical.f90 b/src/phase_mechanical.f90 index de9c2bea2..fe62e16f5 100644 --- a/src/phase_mechanical.f90 +++ b/src/phase_mechanical.f90 @@ -996,16 +996,15 @@ module function phase_mechanical_constitutive(Delta_t,co,ce) result(converged_) subLi0, & subF0, & subF - real(pReal), dimension(:), allocatable :: subState0 + real(pReal), dimension(plasticState(material_phaseID(co,ce))%sizeState) :: subState0 ph = material_phaseID(co,ce) en = material_phaseEntry(co,ce) - sizeDotState = plasticState(ph)%sizeDotState + subState0 = plasticState(ph)%state0(:,en) subLi0 = phase_mechanical_Li0(ph)%data(1:3,1:3,en) subLp0 = phase_mechanical_Lp0(ph)%data(1:3,1:3,en) - allocate(subState0,source=plasticState(ph)%State0(:,en)) subFp0 = phase_mechanical_Fp0(ph)%data(1:3,1:3,en) subFi0 = phase_mechanical_Fi0(ph)%data(1:3,1:3,en) subF0 = phase_mechanical_F0(ph)%data(1:3,1:3,en) @@ -1038,7 +1037,7 @@ module function phase_mechanical_constitutive(Delta_t,co,ce) result(converged_) subStep = num%subStepSizeCryst * subStep phase_mechanical_Fp(ph)%data(1:3,1:3,en) = subFp0 phase_mechanical_Fi(ph)%data(1:3,1:3,en) = subFi0 - phase_mechanical_S(ph)%data(1:3,1:3,en) = phase_mechanical_S0(ph)%data(1:3,1:3,en) ! why no subS0 ? is S0 of any use? + phase_mechanical_S(ph)%data(1:3,1:3,en) = phase_mechanical_S0(ph)%data(1:3,1:3,en) if (subStep < 1.0_pReal) then ! actual (not initial) cutback phase_mechanical_Lp(ph)%data(1:3,1:3,en) = subLp0 phase_mechanical_Li(ph)%data(1:3,1:3,en) = subLi0 @@ -1050,6 +1049,7 @@ module function phase_mechanical_constitutive(Delta_t,co,ce) result(converged_) !-------------------------------------------------------------------------------------------------- ! prepare for integration if (todo) then + sizeDotState = plasticState(ph)%sizeDotState subF = subF0 & + subStep * (phase_mechanical_F(ph)%data(1:3,1:3,en) - phase_mechanical_F0(ph)%data(1:3,1:3,en)) converged_ = .not. integrateState(subF0,subF,subFp0,subFi0,subState0(1:sizeDotState),subStep * Delta_t,ph,en) From a6e83c70ece1de13e989b49419daa62c6459d075 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 6 Feb 2022 17:11:18 +0100 Subject: [PATCH 37/72] adjustments to follow de-facto standard in other parts of the python library --- python/damask/_crystal.py | 5 +++-- python/damask/_orientation.py | 22 +++++++++++----------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/python/damask/_crystal.py b/python/damask/_crystal.py index 0b1c00458..ad5b9ed31 100644 --- a/python/damask/_crystal.py +++ b/python/damask/_crystal.py @@ -2,6 +2,7 @@ from typing import Union, Dict, List, Tuple import numpy as np +from ._typehints import FloatSequence from . import util from . import Rotation @@ -341,8 +342,8 @@ class Crystal(): def to_frame(self, *, - uvw: np.ndarray = None, - hkl: np.ndarray = None) -> np.ndarray: + uvw: FloatSequence = None, + hkl: FloatSequence = None) -> np.ndarray: """ Calculate crystal frame vector along lattice direction [uvw] or plane normal (hkl). diff --git a/python/damask/_orientation.py b/python/damask/_orientation.py index d90cc70e6..c28332012 100644 --- a/python/damask/_orientation.py +++ b/python/damask/_orientation.py @@ -1,15 +1,15 @@ import inspect import copy +from typing import Union, Callable, Dict, Any, Tuple import numpy as np +from ._typehints import FloatSequence, IntSequence from . import Rotation from . import Crystal from . import util from . import tensor -from typing import Union, Callable, Dict, Any, Tuple, List -from ._typehints import FloatSequence, IntSequence _parameter_doc = \ @@ -165,7 +165,7 @@ class Orientation(Rotation,Crystal): Orientation to check for equality. """ - return np.logical_not(self==other) if isinstance(other, Orientation) else NotImplemented + return np.logical_not(self==other) def isclose(self, @@ -206,7 +206,7 @@ class Orientation(Rotation,Crystal): other: object, rtol: float = 1e-5, atol: float = 1e-8, - equal_nan: bool = True) -> Union[bool, np.bool_]: + equal_nan: bool = True) -> bool: """ Test whether all values are approximately equal to corresponding ones of other Orientation. @@ -227,9 +227,7 @@ class Orientation(Rotation,Crystal): Whether all values are close between both orientations. """ - if not isinstance(other, Orientation): - raise TypeError - return np.all(self.isclose(other,rtol,atol,equal_nan)) + return bool(np.all(self.isclose(other,rtol,atol,equal_nan))) def __mul__(self, @@ -411,6 +409,7 @@ class Orientation(Rotation,Crystal): sort = 0 if len(loc) == 1 else np.lexsort(loc[:0:-1]) return eq[ok][sort].reshape(self.shape) + @property def in_FZ(self) -> Union[np.bool_, np.ndarray]: """ @@ -574,6 +573,7 @@ class Orientation(Rotation,Crystal): loc = np.where(ok) sort = 0 if len(loc) == 2 else np.lexsort(loc[:1:-1]) quat = r[ok][sort].reshape(blend+(4,)) + return ( (self.copy(rotation=quat), (np.vstack(loc[:2]).T)[sort].reshape(blend+(2,))) @@ -783,7 +783,7 @@ class Orientation(Rotation,Crystal): @property def symmetry_operations(self) -> Rotation: """Symmetry operations as Rotations.""" - _symmetry_operations: Dict[str, List[List]] = { + _symmetry_operations = { 'cubic': [ [ 1.0, 0.0, 0.0, 0.0 ], [ 0.0, 1.0, 0.0, 0.0 ], @@ -854,8 +854,8 @@ class Orientation(Rotation,Crystal): # functions that require lattice, not just family def to_pole(self, *, - uvw: np.ndarray = None, - hkl: np.ndarray = None, + uvw: FloatSequence = None, + hkl: FloatSequence = None, with_symmetry: bool = False) -> np.ndarray: """ Calculate lab frame vector along lattice direction [uvw] or plane normal (hkl). @@ -926,7 +926,7 @@ class Orientation(Rotation,Crystal): if active == '*': active = [len(a) for a in kinematics['direction']] if not active: - raise RuntimeError + raise RuntimeError # ToDo d = self.to_frame(uvw=np.vstack([kinematics['direction'][i][:n] for i,n in enumerate(active)])) p = self.to_frame(hkl=np.vstack([kinematics['plane'][i][:n] for i,n in enumerate(active)])) P = np.einsum('...i,...j',d/np.linalg.norm(d,axis=1,keepdims=True), From 739a4b7a26022c1a0d5c40d561a54d1a83917d79 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 7 Feb 2022 14:25:03 +0100 Subject: [PATCH 38/72] need to store fraction for proper homogenization --- src/discretization.f90 | 4 +++- src/material.f90 | 17 ++++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/discretization.f90 b/src/discretization.f90 index c79c72b5e..5f4d1c5a6 100644 --- a/src/discretization.f90 +++ b/src/discretization.f90 @@ -12,7 +12,8 @@ module discretization integer, public, protected :: & discretization_nIPs, & - discretization_Nelems + discretization_Nelems, & + discretization_Ncells integer, public, protected, dimension(:), allocatable :: & discretization_materialAt !ToDo: discretization_ID_material @@ -53,6 +54,7 @@ subroutine discretization_init(materialAt,& discretization_Nelems = size(materialAt,1) discretization_nIPs = size(IPcoords0,2)/discretization_Nelems + discretization_Ncells = discretization_Nelems*discretization_nIPs discretization_materialAt = materialAt diff --git a/src/material.f90 b/src/material.f90 index bf78a77a6..10cf2aa7e 100644 --- a/src/material.f90 +++ b/src/material.f90 @@ -45,6 +45,9 @@ module material material_phaseID, & ! TODO: rename to material_ID_phase material_phaseEntry ! TODO: rename to material_entry_phase + real(pReal), dimension(:,:), allocatable, public, protected :: & + material_v ! fraction + public :: & material_init @@ -123,11 +126,13 @@ subroutine parse() allocate(counterPhase(phases%length),source=0) allocate(counterHomogenization(homogenizations%length),source=0) - allocate(material_homogenizationID(discretization_nIPs*discretization_Nelems),source=0) - allocate(material_homogenizationEntry(discretization_nIPs*discretization_Nelems),source=0) + allocate(material_homogenizationID(discretization_Ncells),source=0) + allocate(material_homogenizationEntry(discretization_Ncells),source=0) - allocate(material_phaseID(homogenization_maxNconstituents,discretization_nIPs*discretization_Nelems),source=0) - allocate(material_phaseEntry(homogenization_maxNconstituents,discretization_nIPs*discretization_Nelems),source=0) + allocate(material_phaseID(homogenization_maxNconstituents,discretization_Ncells),source=0) + allocate(material_phaseEntry(homogenization_maxNconstituents,discretization_Ncells),source=0) + + allocate(material_v(homogenization_maxNconstituents,discretization_Ncells),source=0.0_pReal) do el = 1, discretization_Nelems material => materials%get(discretization_materialAt(el)) @@ -144,7 +149,9 @@ subroutine parse() constituents => material%get('constituents') do co = 1, constituents%length constituent => constituents%get(co) - v = v + constituent%get_asFloat('v') + + material_v(co,ce) = constituent%get_asFloat('v') + v = v + material_v(co,ce) ph = phases%getIndex(constituent%get_asString('phase')) do ip = 1, discretization_nIPs From 28eda648937b287435df9b2a7aa75b58d3302032 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 7 Feb 2022 14:43:32 +0100 Subject: [PATCH 39/72] bugfix: change of behavior fraction needed for calculation of homogenized response --- src/homogenization_mechanical.f90 | 13 ++++--------- src/homogenization_thermal.f90 | 18 ++++++------------ src/material.f90 | 8 ++++---- 3 files changed, 14 insertions(+), 25 deletions(-) diff --git a/src/homogenization_mechanical.f90 b/src/homogenization_mechanical.f90 index d2ec08394..1280a9cf3 100644 --- a/src/homogenization_mechanical.f90 +++ b/src/homogenization_mechanical.f90 @@ -131,20 +131,15 @@ module subroutine mechanical_homogenize(Delta_t,ce) integer :: co - homogenization_P(1:3,1:3,ce) = phase_P(1,ce) - homogenization_dPdF(1:3,1:3,1:3,1:3,ce) = phase_mechanical_dPdF(Delta_t,1,ce) + homogenization_P(1:3,1:3,ce) = phase_P(1,ce)*material_v(1,ce) + homogenization_dPdF(1:3,1:3,1:3,1:3,ce) = phase_mechanical_dPdF(Delta_t,1,ce)*material_v(1,ce) do co = 2, homogenization_Nconstituents(material_homogenizationID(ce)) homogenization_P(1:3,1:3,ce) = homogenization_P(1:3,1:3,ce) & - + phase_P(co,ce) + + phase_P(co,ce)*material_v(co,ce) homogenization_dPdF(1:3,1:3,1:3,1:3,ce) = homogenization_dPdF(1:3,1:3,1:3,1:3,ce) & - + phase_mechanical_dPdF(Delta_t,co,ce) + + phase_mechanical_dPdF(Delta_t,co,ce)*material_v(co,ce) end do - homogenization_P(1:3,1:3,ce) = homogenization_P(1:3,1:3,ce) & - / real(homogenization_Nconstituents(material_homogenizationID(ce)),pReal) - homogenization_dPdF(1:3,1:3,1:3,1:3,ce) = homogenization_dPdF(1:3,1:3,1:3,1:3,ce) & - / real(homogenization_Nconstituents(material_homogenizationID(ce)),pReal) - end subroutine mechanical_homogenize diff --git a/src/homogenization_thermal.f90 b/src/homogenization_thermal.f90 index c5490d869..9aa727041 100644 --- a/src/homogenization_thermal.f90 +++ b/src/homogenization_thermal.f90 @@ -105,13 +105,11 @@ module function homogenization_mu_T(ce) result(mu) integer :: co - mu = phase_mu_T(1,ce) + mu = phase_mu_T(1,ce)*material_v(1,ce) do co = 2, homogenization_Nconstituents(material_homogenizationID(ce)) - mu = mu + phase_mu_T(co,ce) + mu = mu + phase_mu_T(co,ce)*material_v(co,ce) end do - mu = mu / real(homogenization_Nconstituents(material_homogenizationID(ce)),pReal) - end function homogenization_mu_T @@ -126,13 +124,11 @@ module function homogenization_K_T(ce) result(K) integer :: co - K = phase_K_T(1,ce) + K = phase_K_T(1,ce)*material_v(1,ce) do co = 2, homogenization_Nconstituents(material_homogenizationID(ce)) - K = K + phase_K_T(co,ce) + K = K + phase_K_T(co,ce)*material_v(co,ce) end do - K = K / real(homogenization_Nconstituents(material_homogenizationID(ce)),pReal) - end function homogenization_K_T @@ -147,13 +143,11 @@ module function homogenization_f_T(ce) result(f) integer :: co - f = phase_f_T(material_phaseID(1,ce),material_phaseEntry(1,ce)) + f = phase_f_T(material_phaseID(1,ce),material_phaseEntry(1,ce))*material_v(1,ce) do co = 2, homogenization_Nconstituents(material_homogenizationID(ce)) - f = f + phase_f_T(material_phaseID(co,ce),material_phaseEntry(co,ce)) + f = f + phase_f_T(material_phaseID(co,ce),material_phaseEntry(co,ce))*material_v(co,ce) end do - f = f/real(homogenization_Nconstituents(material_homogenizationID(ce)),pReal) - end function homogenization_f_T diff --git a/src/material.f90 b/src/material.f90 index 10cf2aa7e..3ff280b0d 100644 --- a/src/material.f90 +++ b/src/material.f90 @@ -145,13 +145,11 @@ subroutine parse() material_homogenizationEntry(ce) = counterHomogenization(ho) end do - v = 0.0_pReal constituents => material%get('constituents') do co = 1, constituents%length constituent => constituents%get(co) - material_v(co,ce) = constituent%get_asFloat('v') - v = v + material_v(co,ce) + v = constituent%get_asFloat('v') ph = phases%getIndex(constituent%get_asString('phase')) do ip = 1, discretization_nIPs @@ -159,10 +157,12 @@ subroutine parse() material_phaseID(co,ce) = ph counterPhase(ph) = counterPhase(ph) + 1 material_phaseEntry(co,ce) = counterPhase(ph) + material_v(co,ce) = v end do end do - if (dNeq(v,1.0_pReal,1.e-12_pReal)) call IO_error(153,ext_msg='constituent') + if (dNeq(sum(material_v(1:constituents%length,ce)),1.0_pReal,1.e-9_pReal)) & + call IO_error(153,ext_msg='constituent') end do From 8c6225794d3953a22f7828c9354b6a8489e73de3 Mon Sep 17 00:00:00 2001 From: Daniel Otto de Mentock Date: Tue, 8 Feb 2022 14:47:23 +0100 Subject: [PATCH 40/72] adjusted return of Orientation.__ne__ function to return NotImplemented in case of wrong input type --- python/damask/_orientation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/damask/_orientation.py b/python/damask/_orientation.py index c28332012..06caf9b4c 100644 --- a/python/damask/_orientation.py +++ b/python/damask/_orientation.py @@ -165,7 +165,7 @@ class Orientation(Rotation,Crystal): Orientation to check for equality. """ - return np.logical_not(self==other) + return np.logical_not(self==other) if isinstance(other, Orientation) else NotImplemented def isclose(self, From 0a52ae3b6f3e338ffedff35deaff4bab578f115b Mon Sep 17 00:00:00 2001 From: Philip Eisenlohr Date: Fri, 11 Feb 2022 12:10:29 -0500 Subject: [PATCH 41/72] polishing of help and style; relax to FloatSequence type where appropriate but keep doc at np.ndarray --- python/damask/_crystal.py | 9 ++- python/damask/_orientation.py | 84 +++++++++++++------------- python/damask/_rotation.py | 109 ++++++++++++++++++++-------------- python/damask/_table.py | 2 +- 4 files changed, 113 insertions(+), 91 deletions(-) diff --git a/python/damask/_crystal.py b/python/damask/_crystal.py index ad5b9ed31..a63cb0c81 100644 --- a/python/damask/_crystal.py +++ b/python/damask/_crystal.py @@ -131,9 +131,8 @@ class Crystal(): Crystal to check for equality. """ - if not isinstance(other, Crystal): - return NotImplemented - return self.lattice == other.lattice and \ + return NotImplemented if not isinstance(other, Crystal) else \ + self.lattice == other.lattice and \ self.parameters == other.parameters and \ self.family == other.family @@ -316,8 +315,8 @@ class Crystal(): self.lattice[-1],None),dtype=float) def to_lattice(self, *, - direction: np.ndarray = None, - plane: np.ndarray = None) -> np.ndarray: + direction: FloatSequence = None, + plane: FloatSequence = None) -> np.ndarray: """ Calculate lattice vector corresponding to crystal frame direction or plane normal. diff --git a/python/damask/_orientation.py b/python/damask/_orientation.py index 06caf9b4c..5a9b7b141 100644 --- a/python/damask/_orientation.py +++ b/python/damask/_orientation.py @@ -189,7 +189,7 @@ class Orientation(Rotation,Crystal): Returns ------- - mask : numpy.ndarray bool + mask : numpy.ndarray of bool Mask indicating where corresponding orientations are close. """ @@ -372,10 +372,10 @@ class Orientation(Rotation,Crystal): Parameters ---------- - uvw : list, numpy.ndarray of shape (...,3) - lattice direction aligned with lab frame x-direction. - hkl : list, numpy.ndarray of shape (...,3) - lattice plane normal aligned with lab frame z-direction. + uvw : numpy.ndarray, shape (...,3) + Lattice direction aligned with lab frame x-direction. + hkl : numpy.ndarray, shape (...,3) + Lattice plane normal aligned with lab frame z-direction. """ o = cls(**kwargs) @@ -417,7 +417,7 @@ class Orientation(Rotation,Crystal): Returns ------- - in : numpy.ndarray of bool, quaternion.shape + in : numpy.ndarray of bool, shape (self.shape) Whether Rodrigues-Frank vector falls into fundamental zone. Notes @@ -461,7 +461,7 @@ class Orientation(Rotation,Crystal): Returns ------- - in : numpy.ndarray of bool, quaternion.shape + in : numpy.ndarray of bool, shape (self.shape) Whether Rodrigues-Frank vector falls into disorientation FZ. References @@ -515,7 +515,7 @@ class Orientation(Rotation,Crystal): ------- disorientation : Orientation Disorientation between self and other. - operators : numpy.ndarray int of shape (...,2), conditional + operators : numpy.ndarray of int, shape (...,2), conditional Index of symmetrically equivalent orientation that rotated vector to the SST. Notes @@ -583,14 +583,14 @@ class Orientation(Rotation,Crystal): def average(self, - weights = None, - return_cloud = False): + weights: FloatSequence = None, + return_cloud: bool = False): """ Return orientation average over last dimension. Parameters ---------- - weights : numpy.ndarray, optional + weights : numpy.ndarray, shape (self.shape), optional Relative weights of orientations. return_cloud : bool, optional Return the set of symmetrically equivalent orientations that was used in averaging. @@ -610,8 +610,8 @@ class Orientation(Rotation,Crystal): """ eq = self.equivalent - m = eq.misorientation(self[...,0].reshape((1,)+self.shape[:-1]+(1,)) - .broadcast_to(eq.shape)).as_axis_angle()[...,3] + m = eq.misorientation(self[...,0].reshape((1,)+self.shape[:-1]+(1,)) # type: ignore + .broadcast_to(eq.shape)).as_axis_angle()[...,3] # type: ignore r = Rotation(np.squeeze(np.take_along_axis(eq.quaternion, np.argmin(m,axis=0)[np.newaxis,...,np.newaxis], axis=0), @@ -625,7 +625,7 @@ class Orientation(Rotation,Crystal): def to_SST(self, - vector: np.ndarray, + vector: FloatSequence, proper: bool = False, return_operators: bool = False) -> np.ndarray: """ @@ -633,10 +633,10 @@ class Orientation(Rotation,Crystal): Parameters ---------- - vector : numpy.ndarray of shape (...,3) + vector : numpy.ndarray, shape (...,3) Lab frame vector to align with crystal frame direction. Shape of vector blends with shape of own rotation array. - For example, a rotation array of shape (3,2) and a (2,4) vector array result in (3,2,4) outputs. + For example, a rotation array of shape (3,2) and a vector array of shape (2,4) result in (3,2,4) outputs. proper : bool, optional Consider only vectors with z >= 0, hence combine two neighboring SSTs. Defaults to False. @@ -646,15 +646,18 @@ class Orientation(Rotation,Crystal): Returns ------- - vector_SST : numpy.ndarray of shape (...,3) + vector_SST : numpy.ndarray, shape (...,3) Rotated vector falling into SST. - operators : numpy.ndarray int of shape (...), conditional + operators : numpy.ndarray of int, shape (...), conditional Index of symmetrically equivalent orientation that rotated vector to SST. """ + vector_ = np.array(vector,float) + if vector_.shape[-1] != 3: + raise ValueError('input is not a field of three-dimensional vectors') eq = self.equivalent - blend = util.shapeblender(eq.shape,np.array(vector).shape[:-1]) - poles = eq.broadcast_to(blend,mode='right') @ np.broadcast_to(np.array(vector),blend+(3,)) #type: ignore + blend = util.shapeblender(eq.shape,vector_.shape[:-1]) + poles = eq.broadcast_to(blend,mode='right') @ np.broadcast_to(vector_,blend+(3,)) #type: ignore ok = self.in_SST(poles,proper=proper) ok &= np.cumsum(ok,axis=0) == 1 loc = np.where(ok) @@ -667,14 +670,14 @@ class Orientation(Rotation,Crystal): def in_SST(self, - vector: np.ndarray, + vector: FloatSequence, proper: bool = False) -> Union[np.bool_, np.ndarray]: """ Check whether given crystal frame vector falls into standard stereographic triangle of own symmetry. Parameters ---------- - vector : numpy.ndarray of shape (...,3) + vector : numpy.ndarray, shape (...,3) Vector to check. proper : bool, optional Consider only vectors with z >= 0, hence combine two neighboring SSTs. @@ -686,31 +689,32 @@ class Orientation(Rotation,Crystal): Whether vector falls into SST. """ - if not isinstance(vector,np.ndarray) or vector.shape[-1] != 3: + vector_ = np.array(vector,float) + if vector_.shape[-1] != 3: raise ValueError('input is not a field of three-dimensional vectors') if self.standard_triangle is None: # direct exit for no symmetry - return np.ones_like(vector[...,0],bool) + return np.ones_like(vector_[...,0],bool) if proper: components_proper = np.around(np.einsum('...ji,...i', - np.broadcast_to(self.standard_triangle['proper'], vector.shape+(3,)), - vector), 12) + np.broadcast_to(self.standard_triangle['proper'], vector_.shape+(3,)), + vector_), 12) components_improper = np.around(np.einsum('...ji,...i', - np.broadcast_to(self.standard_triangle['improper'], vector.shape+(3,)), - vector), 12) + np.broadcast_to(self.standard_triangle['improper'], vector_.shape+(3,)), + vector_), 12) return np.all(components_proper >= 0.0,axis=-1) \ | np.all(components_improper >= 0.0,axis=-1) else: components = np.around(np.einsum('...ji,...i', - np.broadcast_to(self.standard_triangle['improper'], vector.shape+(3,)), - np.block([vector[...,:2],np.abs(vector[...,2:3])])), 12) + np.broadcast_to(self.standard_triangle['improper'], vector_.shape+(3,)), + np.block([vector_[...,:2],np.abs(vector_[...,2:3])])), 12) return np.all(components >= 0.0,axis=-1) def IPF_color(self, - vector: np.ndarray, + vector: FloatSequence, in_SST: bool = True, proper: bool = False) -> np.ndarray: """ @@ -718,10 +722,10 @@ class Orientation(Rotation,Crystal): Parameters ---------- - vector : numpy.ndarray of shape (...,3) + vector : numpy.ndarray, shape (...,3) Vector to colorize. Shape of vector blends with shape of own rotation array. - For example, a rotation array of shape (3,2) and a (2,4) vector array result in (3,2,4) outputs. + For example, a rotation array of shape (3,2) and a vector array of shape (2,4) result in (3,2,4) outputs. in_SST : bool, optional Consider symmetrically equivalent orientations such that poles are located in SST. Defaults to True. @@ -731,7 +735,7 @@ class Orientation(Rotation,Crystal): Returns ------- - rgb : numpy.ndarray of shape (...,3) + rgb : numpy.ndarray, shape (...,3) RGB array of IPF colors. Examples @@ -755,7 +759,7 @@ class Orientation(Rotation,Crystal): if proper: components_proper = np.around(np.einsum('...ji,...i', - np.broadcast_to(self.standard_triangle['proper'], vector_.shape+(3,)), + np.broadcast_to(self.standard_triangle['proper'], vector_.shape+(3,)), vector_), 12) components_improper = np.around(np.einsum('...ji,...i', np.broadcast_to(self.standard_triangle['improper'], vector_.shape+(3,)), @@ -862,16 +866,16 @@ class Orientation(Rotation,Crystal): Parameters ---------- - uvw|hkl : numpy.ndarray of shape (...,3) + uvw|hkl : numpy.ndarray, shape (...,3) Miller indices of crystallographic direction or plane normal. Shape of vector blends with shape of own rotation array. - For example, a rotation array of shape (3,2) and a (2,4) vector array result in (3,2,4) outputs. + For example, a rotation array, shape (3,2) and a vector array of shape (2,4) result in (3,2,4) outputs. with_symmetry : bool, optional Calculate all N symmetrically equivalent vectors. Returns ------- - vector : numpy.ndarray of shape (...,3) or (...,N,3) + vector : numpy.ndarray, shape (...,3) or (...,N,3) Lab frame vector (or vectors if with_symmetry) along [uvw] direction or (hkl) plane normal. """ @@ -894,13 +898,13 @@ class Orientation(Rotation,Crystal): Parameters ---------- - N_slip|N_twin : iterable of int + N_slip|N_twin : '*' or iterable of int Number of deformation systems per family of the deformation system. Use '*' to select all. Returns ------- - P : numpy.ndarray of shape (N,...,3,3) + P : numpy.ndarray, shape (N,...,3,3) Schmid matrix for each of the N deformation systems. Examples diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index 226d66f69..273cf8e92 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -108,12 +108,12 @@ class Rotation: def __getitem__(self, item: Union[Tuple[int], int, bool, np.bool_, np.ndarray]): """Return slice according to item.""" - return self.copy() \ - if self.shape == () else \ + return self.copy() if self.shape == () else \ self.copy(rotation=self.quaternion[item+(slice(None),)] if isinstance(item,tuple) else self.quaternion[item]) - def __eq__(self, other: object) -> bool: + def __eq__(self, + other: object) -> bool: """ Equal to other. @@ -123,9 +123,8 @@ class Rotation: Rotation to check for equality. """ - if not isinstance(other, Rotation): - return NotImplemented - return np.logical_or(np.all(self.quaternion == other.quaternion,axis=-1), + return NotImplemented if not isinstance(other, Rotation) else \ + np.logical_or(np.all(self.quaternion == other.quaternion,axis=-1), np.all(self.quaternion == -1.0*other.quaternion,axis=-1)) @@ -163,7 +162,7 @@ class Rotation: Returns ------- - mask : numpy.ndarray bool + mask : numpy.ndarray of bool Mask indicating where corresponding rotations are close. """ @@ -228,13 +227,13 @@ class Rotation: def __pow__(self: MyType, - exp: int) -> MyType: + exp: Union[float, int]) -> MyType: """ Perform the rotation 'exp' times. Parameters ---------- - exp : float + exp : scalar Exponent. """ @@ -243,13 +242,13 @@ class Rotation: return self.copy(rotation=Rotation(np.block([np.cos(exp*phi),np.sin(exp*phi)*p]))._standardize()) def __ipow__(self: MyType, - exp: int) -> MyType: + exp: Union[float, int]) -> MyType: """ Perform the rotation 'exp' times (in-place). Parameters ---------- - exp : float + exp : scalar Exponent. """ @@ -263,7 +262,7 @@ class Rotation: Parameters ---------- - other : Rotation of shape (self.shape) + other : Rotation, shape (self.shape) Rotation for composition. Returns @@ -290,7 +289,7 @@ class Rotation: Parameters ---------- - other : Rotation of shape (self.shape) + other : Rotation, shape (self.shape) Rotation for composition. """ @@ -304,7 +303,7 @@ class Rotation: Parameters ---------- - other : damask.Rotation of shape (self.shape) + other : damask.Rotation, shape (self.shape) Rotation to invert for composition. Returns @@ -325,7 +324,7 @@ class Rotation: Parameters ---------- - other : Rotation of shape (self.shape) + other : Rotation, shape (self.shape) Rotation to invert for composition. """ @@ -339,12 +338,12 @@ class Rotation: Parameters ---------- - other : numpy.ndarray of shape (...,3), (...,3,3), or (...,3,3,3,3) + other : numpy.ndarray, shape (...,3), (...,3,3), or (...,3,3,3,3) Vector or tensor on which to apply the rotation. Returns ------- - rotated : numpy.ndarray of shape (...,3), (...,3,3), or (...,3,3,3,3) + rotated : numpy.ndarray, shape (...,3), (...,3,3), or (...,3,3,3,3) Rotated vector or tensor, i.e. transformed to frame defined by rotation. """ @@ -401,6 +400,15 @@ class Rotation: """ Flatten array. + Parameters + ---------- + order : {'C', 'F', 'A'}, optional + 'C' flattens in row-major (C-style) order. + 'F' flattens in column-major (Fortran-style) order. + 'A' flattens in column-major order if object is Fortran contiguous in memory, + row-major order otherwise. + Defaults to 'C'. + Returns ------- flattened : damask.Rotation @@ -416,6 +424,18 @@ class Rotation: """ Reshape array. + Parameters + ---------- + shape : int or tuple of ints + The new shape should be compatible with the original shape. + If an integer is supplied, then the result will be a 1-D array of that length. + order : {'C', 'F', 'A'}, optional + 'C' flattens in row-major (C-style) order. + 'F' flattens in column-major (Fortran-style) order. + 'A' flattens in column-major order if object is Fortran contiguous in memory, + row-major order otherwise. + Defaults to 'C'. + Returns ------- reshaped : damask.Rotation @@ -434,7 +454,7 @@ class Rotation: Parameters ---------- - shape : int, tuple + shape : int or tuple of ints Shape of broadcasted array. mode : str, optional Where to preferentially locate missing dimensions. @@ -458,7 +478,7 @@ class Rotation: Parameters ---------- - weights : FloatSequence, optional + weights : numpy.ndarray, optional Relative weight of each rotation. Returns @@ -518,7 +538,7 @@ class Rotation: Returns ------- - q : numpy.ndarray of shape (...,4) + q : numpy.ndarray, shape (...,4) Unit quaternion (q_0, q_1, q_2, q_3) in positive real hemisphere, i.e. ǀqǀ = 1, q_0 ≥ 0. """ @@ -536,7 +556,7 @@ class Rotation: Returns ------- - phi : numpy.ndarray of shape (...,3) + phi : numpy.ndarray, shape (...,3) Bunge Euler angles (φ_1 ∈ [0,2π], ϕ ∈ [0,π], φ_2 ∈ [0,2π]) or (φ_1 ∈ [0,360], ϕ ∈ [0,180], φ_2 ∈ [0,360]) if degrees == True. @@ -555,8 +575,7 @@ class Rotation: """ eu = Rotation._qu2eu(self.quaternion) - if degrees: eu = np.degrees(eu) - return eu + return np.degrees(eu) if degrees else eu def as_axis_angle(self, degrees: bool = False, @@ -573,7 +592,7 @@ class Rotation: Returns ------- - axis_angle : numpy.ndarray of shape (...,4) or tuple ((...,3), (...)) if pair == True + axis_angle : numpy.ndarray, shape (...,4) or tuple ((...,3), (...)) if pair == True Axis and angle [n_1, n_2, n_3, ω] with ǀnǀ = 1 and ω ∈ [0,π] or ω ∈ [0,180] if degrees == True. @@ -597,7 +616,7 @@ class Rotation: Returns ------- - R : numpy.ndarray of shape (...,3,3) + R : numpy.ndarray, shape (...,3,3) Rotation matrix R with det(R) = 1, R.T ∙ R = I. Examples @@ -627,7 +646,7 @@ class Rotation: Returns ------- - rho : numpy.ndarray of shape (...,4) or (...,3) if compact == True + rho : numpy.ndarray, shape (...,4) or (...,3) if compact == True Rodrigues–Frank vector [n_1, n_2, n_3, tan(ω/2)] with ǀnǀ = 1 and ω ∈ [0,π] or [n_1, n_2, n_3] with ǀnǀ = tan(ω/2) and ω ∈ [0,π] if compact == True. @@ -654,7 +673,7 @@ class Rotation: Returns ------- - h : numpy.ndarray of shape (...,3) + h : numpy.ndarray, shape (...,3) Homochoric vector (h_1, h_2, h_3) with ǀhǀ < (3/4*π)^(1/3). Examples @@ -675,7 +694,7 @@ class Rotation: Returns ------- - x : numpy.ndarray of shape (...,3) + x : numpy.ndarray, shape (...,3) Cubochoric vector (x_1, x_2, x_3) with max(x_i) < 1/2*π^(2/3). Examples @@ -702,7 +721,7 @@ class Rotation: Parameters ---------- - q : numpy.ndarray of shape (...,4) + q : numpy.ndarray, shape (...,4) Unit quaternion (q_0, q_1, q_2, q_3) in positive real hemisphere, i.e. ǀqǀ = 1, q_0 ≥ 0. accept_homomorph : bool, optional Allow homomorphic variants, i.e. q_0 < 0 (negative real hemisphere). @@ -736,7 +755,7 @@ class Rotation: Parameters ---------- - phi : numpy.ndarray of shape (...,3) + phi : numpy.ndarray, shape (...,3) Euler angles (φ_1 ∈ [0,2π], ϕ ∈ [0,π], φ_2 ∈ [0,2π]) or (φ_1 ∈ [0,360], ϕ ∈ [0,180], φ_2 ∈ [0,360]) if degrees == True. degrees : bool, optional @@ -767,7 +786,7 @@ class Rotation: Parameters ---------- - axis_angle : numpy.ndarray of shape (...,4) + axis_angle : numpy.ndarray, shape (...,4) Axis and angle (n_1, n_2, n_3, ω) with ǀnǀ = 1 and ω ∈ [0,π] or ω ∈ [0,180] if degrees == True. degrees : bool, optional @@ -804,7 +823,7 @@ class Rotation: Parameters ---------- - basis : numpy.ndarray of shape (...,3,3) + basis : numpy.ndarray, shape (...,3,3) Three three-dimensional lattice basis vectors. orthonormal : bool, optional Basis is strictly orthonormal, i.e. is free of stretch components. Defaults to True. @@ -838,7 +857,7 @@ class Rotation: Parameters ---------- - R : numpy.ndarray of shape (...,3,3) + R : numpy.ndarray, shape (...,3,3) Rotation matrix with det(R) = 1, R.T ∙ R = I. """ @@ -852,9 +871,9 @@ class Rotation: Parameters ---------- - a : numpy.ndarray of shape (...,2,3) + a : numpy.ndarray, shape (...,2,3) Two three-dimensional lattice vectors of first orthogonal basis. - b : numpy.ndarray of shape (...,2,3) + b : numpy.ndarray, shape (...,2,3) Corresponding three-dimensional lattice vectors of second basis. """ @@ -882,7 +901,7 @@ class Rotation: Parameters ---------- - rho : numpy.ndarray of shape (...,4) + rho : numpy.ndarray, shape (...,4) Rodrigues–Frank vector (n_1, n_2, n_3, tan(ω/2)) with ǀnǀ = 1 and ω ∈ [0,π]. normalize : bool, optional Allow ǀnǀ ≠ 1. Defaults to False. @@ -913,7 +932,7 @@ class Rotation: Parameters ---------- - h : numpy.ndarray of shape (...,3) + h : numpy.ndarray, shape (...,3) Homochoric vector (h_1, h_2, h_3) with ǀhǀ < (3/4*π)^(1/3). P : int ∈ {-1,1}, optional Sign convention. Defaults to -1. @@ -940,7 +959,7 @@ class Rotation: Parameters ---------- - x : numpy.ndarray of shape (...,3) + x : numpy.ndarray, shape (...,3) Cubochoric vector (x_1, x_2, x_3) with max(x_i) < 1/2*π^(2/3). P : int ∈ {-1,1}, optional Sign convention. Defaults to -1. @@ -1002,9 +1021,9 @@ class Rotation: Parameters ---------- - weights : numpy.ndarray of shape (n) + weights : numpy.ndarray, shape (n) Texture intensity values (probability density or volume fraction) at Euler space grid points. - phi : numpy.ndarray of shape (n,3) + phi : numpy.ndarray, shape (n,3) Grid coordinates in Euler space at which weights are defined. N : integer, optional Number of discrete orientations to be sampled from the given ODF. @@ -1020,14 +1039,14 @@ class Rotation: Returns ------- - samples : damask.Rotation of shape (N) - Array of sampled rotations closely representing the input ODF. + samples : damask.Rotation, shape (N) + Array of sampled rotations that approximate the input ODF. Notes ----- Due to the distortion of Euler space in the vicinity of ϕ = 0, probability densities, p, defined on grid points with ϕ = 0 will never result in reconstructed orientations as their dV/V = p dγ = p × 0. - Hence, it is recommended to transform any such dataset to cell centers that avoid grid points at ϕ = 0. + Hence, it is recommended to transform any such dataset to a cell-centered version, which avoids grid points at ϕ = 0. References ---------- @@ -1095,9 +1114,9 @@ class Rotation: Parameters ---------- - alpha : numpy.ndarray of shape (2) + alpha : numpy.ndarray, shape (2) Polar coordinates (phi from x, theta from z) of fiber direction in crystal frame. - beta : numpy.ndarray of shape (2) + beta : numpy.ndarray, shape (2) Polar coordinates (phi from x, theta from z) of fiber direction in sample frame. sigma : float, optional Standard deviation of (Gaussian) misorientation distribution. diff --git a/python/damask/_table.py b/python/damask/_table.py index 1572c4f76..189f46d6b 100644 --- a/python/damask/_table.py +++ b/python/damask/_table.py @@ -185,7 +185,7 @@ class Table: Returns ------- - mask : numpy.ndarray bool + mask : numpy.ndarray of bool Mask indicating where corresponding table values are close. """ From c6a188a1fe1b96da102afbf714c1472f3be9b876 Mon Sep 17 00:00:00 2001 From: Philip Eisenlohr Date: Fri, 11 Feb 2022 15:40:14 -0500 Subject: [PATCH 42/72] added CrystalFamily, CrystalLattice, CrystalKinematics typehints --- python/damask/_crystal.py | 26 +++++++++++++------------- python/damask/_orientation.py | 10 +++++----- python/damask/_typehints.py | 6 +++++- 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/python/damask/_crystal.py b/python/damask/_crystal.py index a63cb0c81..6da13f679 100644 --- a/python/damask/_crystal.py +++ b/python/damask/_crystal.py @@ -2,11 +2,11 @@ from typing import Union, Dict, List, Tuple import numpy as np -from ._typehints import FloatSequence +from ._typehints import FloatSequence, CrystalFamily, CrystalLattice, CrystalKinematics from . import util from . import Rotation -lattice_symmetries = { +lattice_symmetries: Dict[CrystalLattice, CrystalFamily] = { 'aP': 'triclinic', 'mP': 'monoclinic', @@ -32,8 +32,8 @@ class Crystal(): """Crystal lattice.""" def __init__(self,*, - family = None, - lattice = None, + family: CrystalFamily = None, + lattice: CrystalLattice = None, a: float = None, b: float = None, c: float = None, alpha: float = None, beta: float = None, gamma: float = None, degrees: bool = False): @@ -208,7 +208,7 @@ class Crystal(): ... } """ - _basis = { + _basis: Dict[CrystalFamily, Dict[str, np.ndarray]] = { 'cubic': {'improper':np.array([ [-1. , 0. , 1. ], [ np.sqrt(2.) , -np.sqrt(2.) , 0. ], [ 0. , np.sqrt(3.) , 0. ] ]), @@ -322,12 +322,12 @@ class Crystal(): Parameters ---------- - direction|plane : numpy.ndarray of shape (...,3) + direction|plane : numpy.ndarray, shape (...,3) Vector along direction or plane normal. Returns ------- - Miller : numpy.ndarray of shape (...,3) + Miller : numpy.ndarray, shape (...,3) Lattice vector of direction or plane. Use util.scale_to_coprime to convert to (integer) Miller indices. @@ -348,12 +348,12 @@ class Crystal(): Parameters ---------- - uvw|hkl : numpy.ndarray of shape (...,3) + uvw|hkl : numpy.ndarray, shape (...,3) Miller indices of crystallographic direction or plane normal. Returns ------- - vector : numpy.ndarray of shape (...,3) + vector : numpy.ndarray, shape (...,3) Crystal frame vector along [uvw] direction or (hkl) plane normal. """ @@ -366,7 +366,7 @@ class Crystal(): def kinematics(self, - mode: str) -> Dict[str, List[np.ndarray]]: + mode: CrystalKinematics) -> Dict[str, List[np.ndarray]]: """ Return crystal kinematics systems. @@ -381,7 +381,7 @@ class Crystal(): Directions and planes of deformation mode families. """ - _kinematics = { + _kinematics: Dict[CrystalLattice, Dict[CrystalKinematics, List[np.ndarray]]] = { 'cF': { 'slip': [np.array([ [+0,+1,-1, +1,+1,+1], @@ -626,7 +626,7 @@ class Crystal(): def relation_operations(self, - model: str) -> Tuple[str, Rotation]: + model: str) -> Tuple[CrystalLattice, Rotation]: """ Crystallographic orientation relationships for phase transformations. @@ -658,7 +658,7 @@ class Crystal(): https://doi.org/10.1016/j.actamat.2004.11.021 """ - _orientation_relationships = { + _orientation_relationships: Dict[str, Dict[CrystalLattice,np.ndarray]] = { 'KS': { 'cF' : np.array([ [[-1, 0, 1],[ 1, 1, 1]], diff --git a/python/damask/_orientation.py b/python/damask/_orientation.py index 5a9b7b141..54ffb6728 100644 --- a/python/damask/_orientation.py +++ b/python/damask/_orientation.py @@ -1,10 +1,10 @@ import inspect import copy -from typing import Union, Callable, Dict, Any, Tuple +from typing import Union, Callable, List, Dict, Any, Tuple import numpy as np -from ._typehints import FloatSequence, IntSequence +from ._typehints import FloatSequence, IntSequence, CrystalFamily, CrystalLattice from . import Rotation from . import Crystal from . import util @@ -98,8 +98,8 @@ class Orientation(Rotation,Crystal): def __init__(self, rotation: Union[FloatSequence, Rotation] = np.array([1.,0.,0.,0.]), *, - family: str = None, - lattice: str = None, + family: CrystalFamily = None, + lattice: CrystalLattice = None, a: float = None, b: float = None, c: float = None, alpha: float = None, beta: float = None, gamma: float = None, degrees: bool = False): @@ -787,7 +787,7 @@ class Orientation(Rotation,Crystal): @property def symmetry_operations(self) -> Rotation: """Symmetry operations as Rotations.""" - _symmetry_operations = { + _symmetry_operations: Dict[CrystalFamily, List] = { 'cubic': [ [ 1.0, 0.0, 0.0, 0.0 ], [ 0.0, 1.0, 0.0, 0.0 ], diff --git a/python/damask/_typehints.py b/python/damask/_typehints.py index 0b4a56a69..674f54721 100644 --- a/python/damask/_typehints.py +++ b/python/damask/_typehints.py @@ -1,6 +1,6 @@ """Functionality for typehints.""" -from typing import Sequence, Union, TextIO +from typing import Sequence, Union, Literal, TextIO from pathlib import Path import numpy as np @@ -10,5 +10,9 @@ FloatSequence = Union[np.ndarray,Sequence[float]] IntSequence = Union[np.ndarray,Sequence[int]] FileHandle = Union[TextIO, str, Path] NumpyRngSeed = Union[int, IntSequence, np.random.SeedSequence, np.random.Generator] +CrystalFamily = Union[None,Literal['triclinic', 'monoclinic', 'orthorhombic', 'tetragonal', 'hexagonal', 'cubic']] +CrystalLattice = Union[None,Literal['aP', 'mP', 'mS', 'oP', 'oS', 'oI', 'oF', 'tP', 'tI', 'hP', 'cP', 'cI', 'cF']] +CrystalKinematics = Literal['slip', 'twin'] + # BitGenerator does not exists in older numpy versions #NumpyRngSeed = Union[int, IntSequence, np.random.SeedSequence, np.random.BitGenerator, np.random.Generator] From eb0fca922247543990e36ba2a73812f4a1defe98 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 12 Feb 2022 09:08:38 +0100 Subject: [PATCH 43/72] generic examples might help some users to make the connection between old an new names, good to have examples anyways --- examples/config/phase/bct.yaml | 2 ++ examples/config/phase/hcp.yaml | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 examples/config/phase/bct.yaml create mode 100644 examples/config/phase/hcp.yaml diff --git a/examples/config/phase/bct.yaml b/examples/config/phase/bct.yaml new file mode 100644 index 000000000..a840e6ede --- /dev/null +++ b/examples/config/phase/bct.yaml @@ -0,0 +1,2 @@ +lattice: tI +c/a: 0.55 diff --git a/examples/config/phase/hcp.yaml b/examples/config/phase/hcp.yaml new file mode 100644 index 000000000..e9bf6b85c --- /dev/null +++ b/examples/config/phase/hcp.yaml @@ -0,0 +1,2 @@ +lattice: hP +c/a: 1.6333 From 3bdfc29fb2a685613409f02838b5396c363082ff Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 12 Feb 2022 11:40:30 +0100 Subject: [PATCH 44/72] Parameter set for beta-Sn --- examples/config/phase/Sn-beta.yaml | 8 +++++ .../eigen/thermalexpansion_Sn-beta.yaml | 13 +++++++++ .../mechanical/elastic/Hooke_Sn-beta.yaml | 25 ++++++++++++++++ .../plastic/phenopowerlaw_Sn-beta.yaml | 29 +++++++++++++++++++ 4 files changed, 75 insertions(+) create mode 100644 examples/config/phase/Sn-beta.yaml create mode 100644 examples/config/phase/mechanical/eigen/thermalexpansion_Sn-beta.yaml create mode 100644 examples/config/phase/mechanical/elastic/Hooke_Sn-beta.yaml create mode 100644 examples/config/phase/mechanical/plastic/phenopowerlaw_Sn-beta.yaml diff --git a/examples/config/phase/Sn-beta.yaml b/examples/config/phase/Sn-beta.yaml new file mode 100644 index 000000000..fbf885fb8 --- /dev/null +++ b/examples/config/phase/Sn-beta.yaml @@ -0,0 +1,8 @@ +references: + - J.A. Rayne and B.S. Chandrasekhar, + Physical Review 120(5):1658-1663, 1960, + https://doi.org/10.1103/PhysRev.120.1658 + - https://en.wikipedia.org/wiki/Tin +lattice: tI +c/a: 0.5458 # T=300K (c=31.83nm, a=5.832nm) +rho: 7265.0 diff --git a/examples/config/phase/mechanical/eigen/thermalexpansion_Sn-beta.yaml b/examples/config/phase/mechanical/eigen/thermalexpansion_Sn-beta.yaml new file mode 100644 index 000000000..7da58b246 --- /dev/null +++ b/examples/config/phase/mechanical/eigen/thermalexpansion_Sn-beta.yaml @@ -0,0 +1,13 @@ +type: thermalexpansion +references: + - V.T. Deshpande and D.B. Sirdeshmukh, + Acta Crystallographica 15:294-295, 1962, + https://doi.org/10.1107/S0365110X62000742, + fitted from Tab. 2 +A_11: 1.639e-05 +A_11,T: 1.799e-08 +A_11,T^2: 1.734e-10 +A_33: 3.263e-05 +A_33,T: 1.387e-08 +A_33,T^2: 5.794e-10 +T_ref: 293.15 diff --git a/examples/config/phase/mechanical/elastic/Hooke_Sn-beta.yaml b/examples/config/phase/mechanical/elastic/Hooke_Sn-beta.yaml new file mode 100644 index 000000000..c6a77729e --- /dev/null +++ b/examples/config/phase/mechanical/elastic/Hooke_Sn-beta.yaml @@ -0,0 +1,25 @@ +type: Hooke +references: + - J.A. Rayne and B.S. Chandrasekhar, + Physical Review 120(5):1658-1663, 1960, + https://doi.org/10.1103/PhysRev.120.1658, + fitted from Fig. 2 and Tab. IV (C_13) +C_11: 72.89e+9 +C_11,T: -4.479e+7 +C_11,T^2: -3.149e+4 +C_12: 59.27e+9 +C_12,T: 1.110e+7 +C_12,T^2: 1.300e+4 +C_13: 35.97e+9 +C_13,T: -2.638e+7 +C_13,T^2: -1.123e+5 +C_33: 88.77e+10 +C_33,T: -5.361e+7 +C_33,T^2: -2.770e+3 +C_44: 22.26e+9 +C_44,T: -1.994e+7 +C_44,T^2: -9.519e+3 +C_66: 24.17e+9 +C_66,T: -1.919e+7 +C_66,T^2: -1.161e+4 +T_ref: 293.15 diff --git a/examples/config/phase/mechanical/plastic/phenopowerlaw_Sn-beta.yaml b/examples/config/phase/mechanical/plastic/phenopowerlaw_Sn-beta.yaml new file mode 100644 index 000000000..2f7871cf5 --- /dev/null +++ b/examples/config/phase/mechanical/plastic/phenopowerlaw_Sn-beta.yaml @@ -0,0 +1,29 @@ +type: phenopowerlaw +references: + - A. Chakraborty and P. Eisenlohr, + Journal of Applied Physics 124:025302, 2018, + https://doi.org/10.1063/1.5029933 +output: [xi_sl, gamma_sl] +N_sl: [2, 2, 2, 4, 2, 4, 2, 2, 4, 0, 0, 8] +n_sl: 6.0 +a_sl: 2.0 +h_0_sl-sl: 20.0e+6 +xi_0_sl: [8.5e+6, 4.3e+6, 10.4e+6, 4.5e+6, 5.6e+6, 5.1e+6, 7.4e+6, 15.0e+6, 6.6e+6, 0.0, 0.0, 12.0e+6] +xi_inf_sl: [11.0e+6, 9.0e+6, 11.0e+6, 9.0e+6, 10.0e+6, 10.0e+6, 10.0e+6, 10.0e+6, 9.0e+6, 0.0, 0.0, 13.0e+6] +h_sl-sl: [+1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + +1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + +1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + +1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + +1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, # 50 + +1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + +1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + +1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + +1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, # 100 + -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, + -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, + -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, + -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + +1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, # 150 + +1.0, 1.0, 1.0, 1.0, 1.0, 1.0] # unused entries are indicated by -1.0 +dot_gamma_0_sl: 2.6e-8 From cdabdb98829395ac3433591d1c2302f7a1a23992 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 12 Feb 2022 16:11:09 +0100 Subject: [PATCH 45/72] temperature-dependent thermal conductivity --- examples/config/phase/thermal/Al.yaml | 10 ++++++++-- examples/config/phase/thermal/Cu.yaml | 9 ++++++++- examples/config/phase/thermal/Fe.yaml | 11 +++++++++++ examples/config/phase/thermal/W.yaml | 9 ++++++++- 4 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 examples/config/phase/thermal/Fe.yaml diff --git a/examples/config/phase/thermal/Al.yaml b/examples/config/phase/thermal/Al.yaml index 50273fde3..6e9705e82 100644 --- a/examples/config/phase/thermal/Al.yaml +++ b/examples/config/phase/thermal/Al.yaml @@ -1,5 +1,11 @@ references: - - https://www.engineeringtoolbox.com/thermal-conductivity-metals-d_858.html + - J.G. Hust and A.B. Lankford, + Thermal Conductivity of Aluminum, Copper, Iron, and Tungsten from 1K to the Melting Point, + US Department of Commerce, Boulder, Colorado, 1984, + fitted to Tab. 3.4.1 (RRR=1000, T_min=200K, T_max=900K) - https://www.engineeringtoolbox.com/specific-heat-metals-d_152.html +K_11: 2.380e+02 +K_11,T: 2.068e-03 +K_11,T^2: -7.765e-05 +T_ref: 293.15 C_p: 910.0 -K_11: 236.0 diff --git a/examples/config/phase/thermal/Cu.yaml b/examples/config/phase/thermal/Cu.yaml index c171d3245..cd4df2d74 100644 --- a/examples/config/phase/thermal/Cu.yaml +++ b/examples/config/phase/thermal/Cu.yaml @@ -1,4 +1,11 @@ references: + - J.G. Hust and A.B. Lankford, + Thermal Conductivity of Aluminum, Copper, Iron, and Tungsten from 1K to the Melting Point, + US Department of Commerce, Boulder, Colorado, 1984, + fitted to Tab. 2.4.1 (RRR=1000, T_min=200K, T_max=1000K) - https://www.mit.edu/~6.777/matprops/copper.htm +K_11: 4.039e+02 +K_11,T: -8.119e-02 +K_11,T^2: 1.454e-05 +T_ref: 293.15 C_p: 385.0 -K_11: 401.0 diff --git a/examples/config/phase/thermal/Fe.yaml b/examples/config/phase/thermal/Fe.yaml new file mode 100644 index 000000000..49d397599 --- /dev/null +++ b/examples/config/phase/thermal/Fe.yaml @@ -0,0 +1,11 @@ +references: + - J.G. Hust and A.B. Lankford, + Thermal Conductivity of Aluminum, Copper, Iron, and Tungsten from 1K to the Melting Point, + US Department of Commerce, Boulder, Colorado, 1984, + fitted to Tab. 4.4.1 (RRR=300, T_min=200K, T_max=1000K) + - https://www.engineeringtoolbox.com/specific-heat-metals-d_152.html +K_11: 8.055e+01 +K_11,T: -1.051e-01 +K_11,T^2: 5.464e-05 +T_ref: 293.15 +C_p: 450.0 diff --git a/examples/config/phase/thermal/W.yaml b/examples/config/phase/thermal/W.yaml index 95918303f..af4a164c8 100644 --- a/examples/config/phase/thermal/W.yaml +++ b/examples/config/phase/thermal/W.yaml @@ -1,4 +1,11 @@ references: + - J.G. Hust and A.B. Lankford, + Thermal Conductivity of Aluminum, Copper, Iron, and Tungsten from 1K to the Melting Point, + US Department of Commerce, Boulder, Colorado, 1984, + fitted to Tab. 5.4.1 (RRR=300, T_min=200K, T_max=1000K) - https://www.mit.edu/~6.777/matprops/tungsten.htm +K_11: 1.758e+02 +K_11,T: -1.605e-01 +K_11,T^2: 1.160e-04 +T_ref: 293.15 C_p: 132.51 -K_11: 178.0 From 4d808335de2ced0792eed8a59948f4490f3e17af Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 12 Feb 2022 18:41:59 +0100 Subject: [PATCH 46/72] polishing --- examples/config/phase/AISI304.yaml | 5 +++-- examples/config/phase/Ag.yaml | 1 + examples/config/phase/Al.yaml | 1 + examples/config/phase/Au.yaml | 1 + examples/config/phase/Cu.yaml | 1 + examples/config/phase/Fe.yaml | 1 + examples/config/phase/Mg.yaml | 1 + examples/config/phase/Ni.yaml | 1 + examples/config/phase/Sn-beta.yaml | 1 + examples/config/phase/Ti.yaml | 1 + examples/config/phase/W.yaml | 1 + examples/config/phase/damage/anisobrittle_cubic.yaml | 6 ++++-- examples/config/phase/damage/isobrittle_generic.yaml | 2 +- .../mechanical/eigen/thermalexpansion_AISI304.yaml | 6 ++++-- .../phase/mechanical/eigen/thermalexpansion_Al.yaml | 2 ++ .../phase/mechanical/eigen/thermalexpansion_Au.yaml | 2 ++ .../phase/mechanical/eigen/thermalexpansion_C35E.yaml | 5 ++++- .../phase/mechanical/eigen/thermalexpansion_Cu.yaml | 2 ++ .../phase/mechanical/eigen/thermalexpansion_Fe.yaml | 2 ++ .../mechanical/eigen/thermalexpansion_Sn-beta.yaml | 6 +++++- .../phase/mechanical/eigen/thermalexpansion_W.yaml | 2 ++ .../mechanical/eigen/thermalexpansion_X20Cr13.yaml | 7 +++++-- .../phase/mechanical/elastic/Hooke_AISI304.yaml | 6 ++++-- .../config/phase/mechanical/elastic/Hooke_Ag.yaml | 5 +++-- .../config/phase/mechanical/elastic/Hooke_Al.yaml | 5 +++-- .../config/phase/mechanical/elastic/Hooke_Au.yaml | 2 ++ .../config/phase/mechanical/elastic/Hooke_Cu.yaml | 2 ++ .../config/phase/mechanical/elastic/Hooke_Fe.yaml | 5 +++-- .../config/phase/mechanical/elastic/Hooke_Mg.yaml | 2 ++ .../config/phase/mechanical/elastic/Hooke_Ni.yaml | 2 ++ .../mechanical/elastic/Hooke_SAE1050-martensite.yaml | 2 ++ .../phase/mechanical/elastic/Hooke_Sn-beta.yaml | 10 +++++++++- .../phase/mechanical/elastic/Hooke_TWIP-steel.yaml | 2 ++ .../config/phase/mechanical/elastic/Hooke_Ti.yaml | 2 ++ examples/config/phase/mechanical/elastic/Hooke_W.yaml | 2 ++ .../elastic/Hooke_vanishing-Poisson-ratio.yaml | 2 ++ .../phase/mechanical/plastic/dislotungsten_W.yaml | 4 ++++ .../phase/mechanical/plastic/dislotwin_IF-steel.yaml | 4 ++++ .../mechanical/plastic/isotropic_free-surface.yaml | 3 +++ .../config/phase/mechanical/plastic/nonlocal_Al.yaml | 11 +++++++---- .../config/phase/mechanical/plastic/nonlocal_Ni.yaml | 11 +++++++---- .../phase/mechanical/plastic/phenopowerlaw_Al.yaml | 4 ++++ .../phase/mechanical/plastic/phenopowerlaw_Au.yaml | 4 ++++ .../phase/mechanical/plastic/phenopowerlaw_Cu.yaml | 4 ++++ .../plastic/phenopowerlaw_DP-steel-ferrite.yaml | 4 ++++ .../phase/mechanical/plastic/phenopowerlaw_Mg.yaml | 1 + .../mechanical/plastic/phenopowerlaw_Sn-beta.yaml | 4 ++++ .../phase/mechanical/plastic/phenopowerlaw_Ti.yaml | 3 +++ examples/config/phase/thermal/AISI304.yaml | 1 + examples/config/phase/thermal/Al.yaml | 5 ++++- examples/config/phase/thermal/Au.yaml | 1 + examples/config/phase/thermal/Cu.yaml | 5 ++++- examples/config/phase/thermal/Fe.yaml | 5 ++++- examples/config/phase/thermal/W.yaml | 5 ++++- .../phase/thermal/source/dissipation_generic.yaml | 1 + .../thermal/source/externalheat_ramp-and-hold.yaml | 1 + examples/config/phase/thermal/steel-0.5C.yaml | 1 + 57 files changed, 156 insertions(+), 32 deletions(-) diff --git a/examples/config/phase/AISI304.yaml b/examples/config/phase/AISI304.yaml index 0ca55635b..4d83ad8b5 100644 --- a/examples/config/phase/AISI304.yaml +++ b/examples/config/phase/AISI304.yaml @@ -1,6 +1,7 @@ references: - - H.M. Ledbetter - physica status solidi (a) 85(1):89-96, 1984 + - H.M. Ledbetter, + physica status solidi (a) 85(1):89-96, 1984, https://doi.org/10.1002/pssa.2210850111 + lattice: cF rho: 7937.0 diff --git a/examples/config/phase/Ag.yaml b/examples/config/phase/Ag.yaml index ebcd21082..1d870d4bf 100644 --- a/examples/config/phase/Ag.yaml +++ b/examples/config/phase/Ag.yaml @@ -1,4 +1,5 @@ references: - https://en.wikipedia.org/wiki/Silver + lattice: cF rho: 10490.0 diff --git a/examples/config/phase/Al.yaml b/examples/config/phase/Al.yaml index f3c19924b..ae48a06b4 100644 --- a/examples/config/phase/Al.yaml +++ b/examples/config/phase/Al.yaml @@ -1,4 +1,5 @@ references: - https://en.wikipedia.org/wiki/Aluminium + lattice: cF rho: 2700.0 diff --git a/examples/config/phase/Au.yaml b/examples/config/phase/Au.yaml index fab05ad99..5dd3ff6f2 100644 --- a/examples/config/phase/Au.yaml +++ b/examples/config/phase/Au.yaml @@ -1,4 +1,5 @@ references: - https://en.wikipedia.org/wiki/Gold + lattice: cF rho: 19300.0 diff --git a/examples/config/phase/Cu.yaml b/examples/config/phase/Cu.yaml index f1e1e9e36..3d742fd25 100644 --- a/examples/config/phase/Cu.yaml +++ b/examples/config/phase/Cu.yaml @@ -1,4 +1,5 @@ references: - https://en.wikipedia.org/wiki/Copper + lattice: cF rho: 8960.0 diff --git a/examples/config/phase/Fe.yaml b/examples/config/phase/Fe.yaml index 271ff8661..2189957c9 100644 --- a/examples/config/phase/Fe.yaml +++ b/examples/config/phase/Fe.yaml @@ -1,4 +1,5 @@ references: - https://en.wikipedia.org/wiki/Iron + lattice: cI rho: 7874.0 diff --git a/examples/config/phase/Mg.yaml b/examples/config/phase/Mg.yaml index 96eb6ad78..39e878b68 100644 --- a/examples/config/phase/Mg.yaml +++ b/examples/config/phase/Mg.yaml @@ -2,6 +2,7 @@ references: - D. Tromans, International Journal of Recent Research and Applied Studies 6(4):462-483, 2011, https://www.arpapress.com/Volumes/Vol6Issue4/IJRRAS_6_4_14.pdf + lattice: hP c/a: 1.62350 rho: 1740.0 diff --git a/examples/config/phase/Ni.yaml b/examples/config/phase/Ni.yaml index 575984583..149889302 100644 --- a/examples/config/phase/Ni.yaml +++ b/examples/config/phase/Ni.yaml @@ -1,4 +1,5 @@ references: - https://en.wikipedia.org/wiki/Nickel + lattice: cF rho: 8908.0 diff --git a/examples/config/phase/Sn-beta.yaml b/examples/config/phase/Sn-beta.yaml index fbf885fb8..833995f30 100644 --- a/examples/config/phase/Sn-beta.yaml +++ b/examples/config/phase/Sn-beta.yaml @@ -3,6 +3,7 @@ references: Physical Review 120(5):1658-1663, 1960, https://doi.org/10.1103/PhysRev.120.1658 - https://en.wikipedia.org/wiki/Tin + lattice: tI c/a: 0.5458 # T=300K (c=31.83nm, a=5.832nm) rho: 7265.0 diff --git a/examples/config/phase/Ti.yaml b/examples/config/phase/Ti.yaml index 48eae3949..886830194 100644 --- a/examples/config/phase/Ti.yaml +++ b/examples/config/phase/Ti.yaml @@ -1,6 +1,7 @@ references: - https://www.totalmateria.com/page.aspx?ID=CheckArticle&site=ktn&NM=221 - https://en.wikipedia.org/wiki/Titanium + lattice: hP c/a: 1.587 rho: 4506.0 diff --git a/examples/config/phase/W.yaml b/examples/config/phase/W.yaml index 740fe0992..7b4d7d4d3 100644 --- a/examples/config/phase/W.yaml +++ b/examples/config/phase/W.yaml @@ -1,4 +1,5 @@ references: - https://en.wikipedia.org/wiki/Tungsten + lattice: cI rho: 19300.0 diff --git a/examples/config/phase/damage/anisobrittle_cubic.yaml b/examples/config/phase/damage/anisobrittle_cubic.yaml index 41f64efcf..372fdc6d0 100644 --- a/examples/config/phase/damage/anisobrittle_cubic.yaml +++ b/examples/config/phase/damage/anisobrittle_cubic.yaml @@ -1,11 +1,13 @@ type: anisobrittle + +output: [f_phi] + N_cl: [3] + g_crit: [0.5e+7] s_crit: [0.006666] dot_o: 1.e-3 q: 20 -output: [f_phi] - D_11: 1.0 mu: 0.001 diff --git a/examples/config/phase/damage/isobrittle_generic.yaml b/examples/config/phase/damage/isobrittle_generic.yaml index 95c0e8b61..851302a49 100644 --- a/examples/config/phase/damage/isobrittle_generic.yaml +++ b/examples/config/phase/damage/isobrittle_generic.yaml @@ -1,7 +1,7 @@ type: isobrittle -W_crit: 1400000.0 output: [f_phi] +W_crit: 1400000.0 D_11: 1.0 mu: 0.001 diff --git a/examples/config/phase/mechanical/eigen/thermalexpansion_AISI304.yaml b/examples/config/phase/mechanical/eigen/thermalexpansion_AISI304.yaml index 6a3b339bb..f3605e1d9 100644 --- a/examples/config/phase/mechanical/eigen/thermalexpansion_AISI304.yaml +++ b/examples/config/phase/mechanical/eigen/thermalexpansion_AISI304.yaml @@ -1,7 +1,9 @@ type: thermalexpansion + references: - - R.H. Bogaard et al. - Thermochimica Acta 218:373-393, 1993 + - R.H. Bogaard et al., + Thermochimica Acta 218:373-393, 1993, https://doi.org/10.1016/0040-6031(93)80437-F + A_11: 15.0e-6 T_ref: 300.0 diff --git a/examples/config/phase/mechanical/eigen/thermalexpansion_Al.yaml b/examples/config/phase/mechanical/eigen/thermalexpansion_Al.yaml index b0db392e1..ccd8b347b 100644 --- a/examples/config/phase/mechanical/eigen/thermalexpansion_Al.yaml +++ b/examples/config/phase/mechanical/eigen/thermalexpansion_Al.yaml @@ -1,5 +1,7 @@ type: thermalexpansion + references: - https://en.wikipedia.org/wiki/Thermal_expansion + A_11: 23.1e-6 T_ref: 293.15 diff --git a/examples/config/phase/mechanical/eigen/thermalexpansion_Au.yaml b/examples/config/phase/mechanical/eigen/thermalexpansion_Au.yaml index 934b4f721..8211516de 100644 --- a/examples/config/phase/mechanical/eigen/thermalexpansion_Au.yaml +++ b/examples/config/phase/mechanical/eigen/thermalexpansion_Au.yaml @@ -1,5 +1,7 @@ type: thermalexpansion + references: - https://en.wikipedia.org/wiki/Thermal_expansion + A_11: 14.e-6 T_ref: 293.15 diff --git a/examples/config/phase/mechanical/eigen/thermalexpansion_C35E.yaml b/examples/config/phase/mechanical/eigen/thermalexpansion_C35E.yaml index 13d99b0ed..08e9d6894 100644 --- a/examples/config/phase/mechanical/eigen/thermalexpansion_C35E.yaml +++ b/examples/config/phase/mechanical/eigen/thermalexpansion_C35E.yaml @@ -1,8 +1,11 @@ type: thermalexpansion + references: - https://commons.wikimedia.org/wiki/File:Coefficient_dilatation_lineique_aciers.svg, - fitted from image description (Scilab code) + fit to image description (Scilab code) + A_11: 12.70371e-6 A_11,T: 7.54e-9 A_11,T^2: -1.0e-11 + T_ref: 273.0 diff --git a/examples/config/phase/mechanical/eigen/thermalexpansion_Cu.yaml b/examples/config/phase/mechanical/eigen/thermalexpansion_Cu.yaml index 4c82421f3..d7c71931b 100644 --- a/examples/config/phase/mechanical/eigen/thermalexpansion_Cu.yaml +++ b/examples/config/phase/mechanical/eigen/thermalexpansion_Cu.yaml @@ -1,5 +1,7 @@ type: thermalexpansion + references: - https://en.wikipedia.org/wiki/Thermal_expansion + A_11: 17.e-6 T_ref: 293.15 diff --git a/examples/config/phase/mechanical/eigen/thermalexpansion_Fe.yaml b/examples/config/phase/mechanical/eigen/thermalexpansion_Fe.yaml index c0891ea6a..9798fb8a0 100644 --- a/examples/config/phase/mechanical/eigen/thermalexpansion_Fe.yaml +++ b/examples/config/phase/mechanical/eigen/thermalexpansion_Fe.yaml @@ -1,5 +1,7 @@ type: thermalexpansion + references: - https://en.wikipedia.org/wiki/Thermal_expansion + A_11: 11.8e-6 T_ref: 293.15 diff --git a/examples/config/phase/mechanical/eigen/thermalexpansion_Sn-beta.yaml b/examples/config/phase/mechanical/eigen/thermalexpansion_Sn-beta.yaml index 7da58b246..16e78f82c 100644 --- a/examples/config/phase/mechanical/eigen/thermalexpansion_Sn-beta.yaml +++ b/examples/config/phase/mechanical/eigen/thermalexpansion_Sn-beta.yaml @@ -1,13 +1,17 @@ type: thermalexpansion + references: - V.T. Deshpande and D.B. Sirdeshmukh, Acta Crystallographica 15:294-295, 1962, https://doi.org/10.1107/S0365110X62000742, - fitted from Tab. 2 + fit to Tab. 2 + A_11: 1.639e-05 A_11,T: 1.799e-08 A_11,T^2: 1.734e-10 + A_33: 3.263e-05 A_33,T: 1.387e-08 A_33,T^2: 5.794e-10 + T_ref: 293.15 diff --git a/examples/config/phase/mechanical/eigen/thermalexpansion_W.yaml b/examples/config/phase/mechanical/eigen/thermalexpansion_W.yaml index 427731186..338f60fe2 100644 --- a/examples/config/phase/mechanical/eigen/thermalexpansion_W.yaml +++ b/examples/config/phase/mechanical/eigen/thermalexpansion_W.yaml @@ -1,5 +1,7 @@ type: thermalexpansion + references: - https://en.wikipedia.org/wiki/Thermal_expansion + A_11: 4.5e-6 T_ref: 293.15 diff --git a/examples/config/phase/mechanical/eigen/thermalexpansion_X20Cr13.yaml b/examples/config/phase/mechanical/eigen/thermalexpansion_X20Cr13.yaml index 19b4cb485..1b8f1545b 100644 --- a/examples/config/phase/mechanical/eigen/thermalexpansion_X20Cr13.yaml +++ b/examples/config/phase/mechanical/eigen/thermalexpansion_X20Cr13.yaml @@ -1,7 +1,10 @@ type: thermalexpansion + references: - - https://commons.wikimedia.org/wiki/File:Coefficient_dilatation_lineique_aciers.svg - fitted from image description (Scilab code) + - https://commons.wikimedia.org/wiki/File:Coefficient_dilatation_lineique_aciers.svg, + fit to image description (Scilab code) + A_11: 11.365e-6 A_11,T: 5.0e-9 + T_ref: 273.0 diff --git a/examples/config/phase/mechanical/elastic/Hooke_AISI304.yaml b/examples/config/phase/mechanical/elastic/Hooke_AISI304.yaml index 70fbd25c7..898702455 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_AISI304.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_AISI304.yaml @@ -1,8 +1,10 @@ type: Hooke + references: - - H.M. Ledbetter - physica status solidi (a) 85(1):89-96, 1984 + - H.M. Ledbetter, + physica status solidi (a) 85(1):89-96, 1984, https://doi.org/10.1002/pssa.2210850111 + C_11: 204.6e+9 C_12: 137.7e+9 C_44: 126.2e+9 diff --git a/examples/config/phase/mechanical/elastic/Hooke_Ag.yaml b/examples/config/phase/mechanical/elastic/Hooke_Ag.yaml index 9485a4bb2..3b136a5c2 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_Ag.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_Ag.yaml @@ -1,4 +1,5 @@ type: Hooke + references: - J.R. Neighbours and G.A. Alers, Physical Review 111:707-712, 1958, @@ -7,8 +8,6 @@ references: Journal of Applied Physics 37:3567-3572, 1966, https://doi.org/10.1063/1.1708903 -T_ref: 300 - C_11: 122.9e+9 C_11,T: -313.5e+5 C_11,T^2: -107.3e+2 @@ -20,3 +19,5 @@ C_12,T^2: -681.6e+1 C_44: 42.63e+9 C_44,T: -180.5e+5 C_44,T^2: -353.8e+1 + +T_ref: 300 diff --git a/examples/config/phase/mechanical/elastic/Hooke_Al.yaml b/examples/config/phase/mechanical/elastic/Hooke_Al.yaml index f4c266d54..97d45e62f 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_Al.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_Al.yaml @@ -1,4 +1,5 @@ type: Hooke + references: - G.N. Kamm and G.A. Alers, Journal of Applied Physics 35:327-330, 1964, @@ -7,8 +8,6 @@ references: Journal of Physics and Chemistry of Solids 30:1197-1205, 1969 https://doi.org/10.1016/0022-3697(69)90377-1 -T_ref: 300 - C_11: 106.1e+9 C_11,T: -359.3e+5 C_11,T^2: -152.7e+2 @@ -20,3 +19,5 @@ C_12,T^2: -551.3e+1 C_44: 24.31e+9 C_44,T: -142.9e+5 C_44,T^2: -404.6e+1 + +T_ref: 300 diff --git a/examples/config/phase/mechanical/elastic/Hooke_Au.yaml b/examples/config/phase/mechanical/elastic/Hooke_Au.yaml index 452807a6e..47afd262b 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_Au.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_Au.yaml @@ -1,9 +1,11 @@ type: Hooke + references: - J.P. Hirth and J. Lothe, Theory of Dislocations, 1982, John Wiley & Sons, page 837 + C_11: 186.e+9 C_12: 157.e+9 C_44: 42.e+9 diff --git a/examples/config/phase/mechanical/elastic/Hooke_Cu.yaml b/examples/config/phase/mechanical/elastic/Hooke_Cu.yaml index 7b458a421..90a0bd269 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_Cu.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_Cu.yaml @@ -1,7 +1,9 @@ type: Hooke + references: - https://www.mit.edu/~6.777/matprops/copper.htm, fixed typo + C_11: 168.3e+9 C_12: 122.1e+9 C_44: 75.7e+9 diff --git a/examples/config/phase/mechanical/elastic/Hooke_Fe.yaml b/examples/config/phase/mechanical/elastic/Hooke_Fe.yaml index 94e761aaf..a6d7d1868 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_Fe.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_Fe.yaml @@ -1,11 +1,10 @@ type: Hooke + references: - D.J. Dever, Journal of Applied Physics 43(8):3293-3301, 1972, https://doi.org/10.1063/1.1661710 -T_ref: 300 - C_11: 231.7e+9 C_11,T: -47.6e+6 C_11,T^2: -54.4e+3 @@ -17,3 +16,5 @@ C_12,T^2: -7.3e+3 C_44: 116.8e+9 C_44,T: -19.4e+6 C_44,T^2: -2.5e+3 + +T_ref: 300 diff --git a/examples/config/phase/mechanical/elastic/Hooke_Mg.yaml b/examples/config/phase/mechanical/elastic/Hooke_Mg.yaml index 1e08a94a9..aa089d4b4 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_Mg.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_Mg.yaml @@ -1,8 +1,10 @@ type: Hooke + references: - D. Tromans, International Journal of Recent Research and Applied Studies 6(4):462-483, 2011, https://www.arpapress.com/Volumes/Vol6Issue4/IJRRAS_6_4_14.pdf + C_11: 59.3e+9 C_33: 61.5e+9 C_44: 16.4e+9 diff --git a/examples/config/phase/mechanical/elastic/Hooke_Ni.yaml b/examples/config/phase/mechanical/elastic/Hooke_Ni.yaml index c11f664d3..6bba784fb 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_Ni.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_Ni.yaml @@ -1,9 +1,11 @@ type: Hooke + references: - J.P. Hirth and J. Lothe, Theory of Dislocations, 1982, John Wiley & Sons, page 837 + C_11: 246.5e+9 C_12: 147.3e+9 C_44: 124.7e+9 diff --git a/examples/config/phase/mechanical/elastic/Hooke_SAE1050-martensite.yaml b/examples/config/phase/mechanical/elastic/Hooke_SAE1050-martensite.yaml index 7ba941066..191756cc7 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_SAE1050-martensite.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_SAE1050-martensite.yaml @@ -1,8 +1,10 @@ type: Hooke + references: - S.A. Kim and W.L. Johnson, Materials Science & Engineering A 452-453:633-639, 2007, https://doi.org/10.1016/j.msea.2006.11.147 + C_11: 268.1e+9 C_12: 111.2e+9 C_44: 79.06e+9 diff --git a/examples/config/phase/mechanical/elastic/Hooke_Sn-beta.yaml b/examples/config/phase/mechanical/elastic/Hooke_Sn-beta.yaml index c6a77729e..a49c246f9 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_Sn-beta.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_Sn-beta.yaml @@ -1,25 +1,33 @@ type: Hooke + references: - J.A. Rayne and B.S. Chandrasekhar, Physical Review 120(5):1658-1663, 1960, https://doi.org/10.1103/PhysRev.120.1658, - fitted from Fig. 2 and Tab. IV (C_13) + fit to Fig. 2 and Tab. IV (C_13) + C_11: 72.89e+9 C_11,T: -4.479e+7 C_11,T^2: -3.149e+4 + C_12: 59.27e+9 C_12,T: 1.110e+7 C_12,T^2: 1.300e+4 + C_13: 35.97e+9 C_13,T: -2.638e+7 C_13,T^2: -1.123e+5 + C_33: 88.77e+10 C_33,T: -5.361e+7 C_33,T^2: -2.770e+3 + C_44: 22.26e+9 C_44,T: -1.994e+7 C_44,T^2: -9.519e+3 + C_66: 24.17e+9 C_66,T: -1.919e+7 C_66,T^2: -1.161e+4 + T_ref: 293.15 diff --git a/examples/config/phase/mechanical/elastic/Hooke_TWIP-steel.yaml b/examples/config/phase/mechanical/elastic/Hooke_TWIP-steel.yaml index c31589955..d4f5b684a 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_TWIP-steel.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_TWIP-steel.yaml @@ -1,4 +1,5 @@ type: Hooke + references: - D. Music et al., Applied Physics Letters 99(19):191904, 2007, @@ -6,6 +7,7 @@ references: - S.L. Wong et al., Acta Materialia 118:140-151, 2016, https://doi.org/10.1016/j.actamat.2016.07.032 + C_11: 175.0e+9 C_12: 115.0e+9 C_44: 135.0e+9 diff --git a/examples/config/phase/mechanical/elastic/Hooke_Ti.yaml b/examples/config/phase/mechanical/elastic/Hooke_Ti.yaml index ee8cae0ad..79b7c04f7 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_Ti.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_Ti.yaml @@ -1,8 +1,10 @@ type: Hooke + references: - L. Wang et al., Acta Materialia 132:598-610, 2017, https://doi.org/10.1016/j.actamat.2017.05.015 + C_11: 162.4e+9 C_33: 181.6e+9 C_44: 47.2e+9 diff --git a/examples/config/phase/mechanical/elastic/Hooke_W.yaml b/examples/config/phase/mechanical/elastic/Hooke_W.yaml index 49bb7858a..a1191f8c7 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_W.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_W.yaml @@ -1,8 +1,10 @@ type: Hooke + references: - D. Cereceda et al., International Journal of Plasticity 78:242-265, 2016, https://doi.org/10.1016/j.ijplas.2015.09.002 + C_11: 523.e+9 C_12: 202.e+9 C_44: 161.e+9 diff --git a/examples/config/phase/mechanical/elastic/Hooke_vanishing-Poisson-ratio.yaml b/examples/config/phase/mechanical/elastic/Hooke_vanishing-Poisson-ratio.yaml index 9a69dda4e..04045c0c4 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_vanishing-Poisson-ratio.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_vanishing-Poisson-ratio.yaml @@ -1,8 +1,10 @@ type: Hooke + references: - T. Maiti and P. Eisenlohr, Scripta Materialia 145:37-40, 2018, https://doi.org/10.1016/j.scriptamat.2017.09.047 + C_11: 1.e+8 C_12: 1.e+6 C_44: 4.95e+7 diff --git a/examples/config/phase/mechanical/plastic/dislotungsten_W.yaml b/examples/config/phase/mechanical/plastic/dislotungsten_W.yaml index 55814c3f8..a1332acc9 100644 --- a/examples/config/phase/mechanical/plastic/dislotungsten_W.yaml +++ b/examples/config/phase/mechanical/plastic/dislotungsten_W.yaml @@ -1,4 +1,5 @@ type: dislotungsten + references: - D. Cereceda et al., International Journal of Plasticity 78:242-265, 2016, @@ -6,8 +7,11 @@ references: - R. Gröger et al., Acta Materialia 56(19):5412-5425, 2008, https://doi.org/10.1016/j.actamat.2008.07.037 + output: [Lambda_sl] + N_sl: [12] + b_sl: [2.72e-10] rho_mob_0: [1.0e+9] # estimated from section 3.2 rho_dip_0: [1.0] # not given diff --git a/examples/config/phase/mechanical/plastic/dislotwin_IF-steel.yaml b/examples/config/phase/mechanical/plastic/dislotwin_IF-steel.yaml index 4e4ff1a9f..62801414f 100644 --- a/examples/config/phase/mechanical/plastic/dislotwin_IF-steel.yaml +++ b/examples/config/phase/mechanical/plastic/dislotwin_IF-steel.yaml @@ -1,4 +1,5 @@ type: dislotwin + references: - K. Sedighiani et al., International Journal of Plasticity 134:102779, 2020, @@ -6,8 +7,11 @@ references: - K. Sedighiani et al., Mechanics of Materials, 164:104117, 2022, https://doi.org/10.1016/j.mechmat.2021.104117 + output: [rho_dip, rho_mob] + N_sl: [12, 12] + b_sl: [2.49e-10, 2.49e-10] rho_mob_0: [2.81e12, 2.8e+12] rho_dip_0: [1.0, 1.0] # not given diff --git a/examples/config/phase/mechanical/plastic/isotropic_free-surface.yaml b/examples/config/phase/mechanical/plastic/isotropic_free-surface.yaml index fba7effa8..c58dc24fc 100644 --- a/examples/config/phase/mechanical/plastic/isotropic_free-surface.yaml +++ b/examples/config/phase/mechanical/plastic/isotropic_free-surface.yaml @@ -1,9 +1,12 @@ type: isotropic + references: - T. Maiti and P. Eisenlohr, Scripta Materialia 145:37-40, 2018, https://doi.org/10.1016/j.scriptamat.2017.09.047 + output: [xi] + dot_gamma_0: 0.001 n: 20. xi_0: 0.3e+6 diff --git a/examples/config/phase/mechanical/plastic/nonlocal_Al.yaml b/examples/config/phase/mechanical/plastic/nonlocal_Al.yaml index 7ee79f9e5..451ce53db 100644 --- a/examples/config/phase/mechanical/plastic/nonlocal_Al.yaml +++ b/examples/config/phase/mechanical/plastic/nonlocal_Al.yaml @@ -1,10 +1,13 @@ type: nonlocal + references: - C. Kords, - On the role of dislocation transport in the constitutive description of crystal plasticity, - RWTH Aachen 2013, - http://publications.rwth-aachen.de/record/229993/files/4862.pdf + - C. Kords, + On the role of dislocation transport in the constitutive description of crystal plasticity, + RWTH Aachen 2013, + http://publications.rwth-aachen.de/record/229993/files/4862.pdf + output: [rho_u_ed_pos, rho_b_ed_pos, rho_u_ed_neg, rho_b_ed_neg, rho_u_sc_pos, rho_b_sc_pos, rho_u_sc_neg, rho_b_sc_neg, rho_d_ed, rho_d_sc] + N_sl: [12] b_sl: [2.86e-10] diff --git a/examples/config/phase/mechanical/plastic/nonlocal_Ni.yaml b/examples/config/phase/mechanical/plastic/nonlocal_Ni.yaml index c14b912b1..68cf48f3c 100644 --- a/examples/config/phase/mechanical/plastic/nonlocal_Ni.yaml +++ b/examples/config/phase/mechanical/plastic/nonlocal_Ni.yaml @@ -1,10 +1,13 @@ type: nonlocal + references: - C. Kords, - On the role of dislocation transport in the constitutive description of crystal plasticity, - RWTH Aachen 2013, - http://publications.rwth-aachen.de/record/229993/files/4862.pdf + - C. Kords, + On the role of dislocation transport in the constitutive description of crystal plasticity, + RWTH Aachen 2013, + http://publications.rwth-aachen.de/record/229993/files/4862.pdf + output: [rho_u_ed_pos, rho_b_ed_pos, rho_u_ed_neg, rho_b_ed_neg, rho_u_sc_pos, rho_b_sc_pos, rho_u_sc_neg, rho_b_sc_neg, rho_d_ed, rho_d_sc] + N_sl: [12] b_sl: [2.48e-10] diff --git a/examples/config/phase/mechanical/plastic/phenopowerlaw_Al.yaml b/examples/config/phase/mechanical/plastic/phenopowerlaw_Al.yaml index cc4b56eb6..68c51cdea 100644 --- a/examples/config/phase/mechanical/plastic/phenopowerlaw_Al.yaml +++ b/examples/config/phase/mechanical/plastic/phenopowerlaw_Al.yaml @@ -1,4 +1,5 @@ type: phenopowerlaw + references: - W.F. Hosford et al., Acta Metallurgica 8(3):187-199, 1960, @@ -7,8 +8,11 @@ references: - U.F. Kocks, Metallurgical and Materials Transactions B 1:1121–1143, 1970, https://doi.org/10.1007/BF02900224 + output: [xi_sl, gamma_sl] + N_sl: [12] + n_sl: 20 a_sl: 3.1 h_0_sl-sl: 1.7e+8 diff --git a/examples/config/phase/mechanical/plastic/phenopowerlaw_Au.yaml b/examples/config/phase/mechanical/plastic/phenopowerlaw_Au.yaml index ac9c93ccf..3eaed00c4 100644 --- a/examples/config/phase/mechanical/plastic/phenopowerlaw_Au.yaml +++ b/examples/config/phase/mechanical/plastic/phenopowerlaw_Au.yaml @@ -1,4 +1,5 @@ type: phenopowerlaw + references: - D. Ma et al., Acta Materialia 103:796-808, 2016, @@ -9,8 +10,11 @@ references: - U.F. Kocks, Metallurgical and Materials Transactions B 1:1121–1143, 1970, https://doi.org/10.1007/BF02900224 + output: [xi_sl, gamma_sl] + N_sl: [12] + n_sl: 83.3 a_sl: 1.0 h_0_sl-sl: 75.0e+6 diff --git a/examples/config/phase/mechanical/plastic/phenopowerlaw_Cu.yaml b/examples/config/phase/mechanical/plastic/phenopowerlaw_Cu.yaml index 4047703cb..223495d26 100644 --- a/examples/config/phase/mechanical/plastic/phenopowerlaw_Cu.yaml +++ b/examples/config/phase/mechanical/plastic/phenopowerlaw_Cu.yaml @@ -1,4 +1,5 @@ type: phenopowerlaw + references: - T Takeuchi, Transactions of the Japan Institute of Metals 16(10):629-640, 1975, @@ -7,8 +8,11 @@ references: - U.F. Kocks, Metallurgical and Materials Transactions B 1:1121–1143, 1970, https://doi.org/10.1007/BF02900224 + output: [xi_sl, gamma_sl] + N_sl: [12] + n_sl: 20 a_sl: 1.0 h_0_sl-sl: 2.4e+8 diff --git a/examples/config/phase/mechanical/plastic/phenopowerlaw_DP-steel-ferrite.yaml b/examples/config/phase/mechanical/plastic/phenopowerlaw_DP-steel-ferrite.yaml index 5218e42a8..023159bb2 100644 --- a/examples/config/phase/mechanical/plastic/phenopowerlaw_DP-steel-ferrite.yaml +++ b/examples/config/phase/mechanical/plastic/phenopowerlaw_DP-steel-ferrite.yaml @@ -1,4 +1,5 @@ type: phenopowerlaw + references: - C.C. Tasan et al., Acta Materialia 81:386-400, 2014, @@ -6,8 +7,11 @@ references: - U.F. Kocks, Metallurgical and Materials Transactions B 1:1121–1143, 1970, https://doi.org/10.1007/BF02900224 + output: [xi_sl, gamma_sl] + N_sl: [12, 12] + n_sl: 20 a_sl: 2.25 h_0_sl-sl: 1.0e+9 diff --git a/examples/config/phase/mechanical/plastic/phenopowerlaw_Mg.yaml b/examples/config/phase/mechanical/plastic/phenopowerlaw_Mg.yaml index 8a3147604..9ccc0ab3c 100644 --- a/examples/config/phase/mechanical/plastic/phenopowerlaw_Mg.yaml +++ b/examples/config/phase/mechanical/plastic/phenopowerlaw_Mg.yaml @@ -1,4 +1,5 @@ type: phenopowerlaw + references: - F. Wang et al., Acta Materialia 80:77-93, 2014, diff --git a/examples/config/phase/mechanical/plastic/phenopowerlaw_Sn-beta.yaml b/examples/config/phase/mechanical/plastic/phenopowerlaw_Sn-beta.yaml index 2f7871cf5..6877fe229 100644 --- a/examples/config/phase/mechanical/plastic/phenopowerlaw_Sn-beta.yaml +++ b/examples/config/phase/mechanical/plastic/phenopowerlaw_Sn-beta.yaml @@ -1,10 +1,14 @@ type: phenopowerlaw + references: - A. Chakraborty and P. Eisenlohr, Journal of Applied Physics 124:025302, 2018, https://doi.org/10.1063/1.5029933 + output: [xi_sl, gamma_sl] + N_sl: [2, 2, 2, 4, 2, 4, 2, 2, 4, 0, 0, 8] + n_sl: 6.0 a_sl: 2.0 h_0_sl-sl: 20.0e+6 diff --git a/examples/config/phase/mechanical/plastic/phenopowerlaw_Ti.yaml b/examples/config/phase/mechanical/plastic/phenopowerlaw_Ti.yaml index 890f580cc..2dbf81ddc 100644 --- a/examples/config/phase/mechanical/plastic/phenopowerlaw_Ti.yaml +++ b/examples/config/phase/mechanical/plastic/phenopowerlaw_Ti.yaml @@ -1,4 +1,5 @@ type: phenopowerlaw + references: - C. Zambaldi et al., Journal of Materials Research 27(1):356-367, 2021, @@ -6,9 +7,11 @@ references: - L. Wang et al., Acta Materialia 132:598-610, 2017, https://doi.org/10.1016/j.actamat.2017.05.015 + output: [gamma_sl] N_sl: [3, 3, 0, 12] # basal, prism, -, 1. pyr + n_sl: 20 a_sl: 2.0 dot_gamma_0_sl: 0.001 diff --git a/examples/config/phase/thermal/AISI304.yaml b/examples/config/phase/thermal/AISI304.yaml index ef09fd850..7d7cbd40c 100644 --- a/examples/config/phase/thermal/AISI304.yaml +++ b/examples/config/phase/thermal/AISI304.yaml @@ -5,5 +5,6 @@ references: - R.H. Bogaard et al. Thermochimica Acta 218:373-393, 1993 https://doi.org/10.1016/0040-6031(93)80437-F + C_p: 470.0 K_11: 14.34 diff --git a/examples/config/phase/thermal/Al.yaml b/examples/config/phase/thermal/Al.yaml index 6e9705e82..485cc5a31 100644 --- a/examples/config/phase/thermal/Al.yaml +++ b/examples/config/phase/thermal/Al.yaml @@ -2,10 +2,13 @@ references: - J.G. Hust and A.B. Lankford, Thermal Conductivity of Aluminum, Copper, Iron, and Tungsten from 1K to the Melting Point, US Department of Commerce, Boulder, Colorado, 1984, - fitted to Tab. 3.4.1 (RRR=1000, T_min=200K, T_max=900K) + fit to Tab. 3.4.1 (RRR=1000, T_min=200K, T_max=900K) - https://www.engineeringtoolbox.com/specific-heat-metals-d_152.html + K_11: 2.380e+02 K_11,T: 2.068e-03 K_11,T^2: -7.765e-05 + T_ref: 293.15 + C_p: 910.0 diff --git a/examples/config/phase/thermal/Au.yaml b/examples/config/phase/thermal/Au.yaml index 43fe9558e..7ff814d53 100644 --- a/examples/config/phase/thermal/Au.yaml +++ b/examples/config/phase/thermal/Au.yaml @@ -1,4 +1,5 @@ references: - https://de.wikipedia.org/wiki/Gold + C_p: 128.0 K_11: 320.0 diff --git a/examples/config/phase/thermal/Cu.yaml b/examples/config/phase/thermal/Cu.yaml index cd4df2d74..50e3fdc23 100644 --- a/examples/config/phase/thermal/Cu.yaml +++ b/examples/config/phase/thermal/Cu.yaml @@ -2,10 +2,13 @@ references: - J.G. Hust and A.B. Lankford, Thermal Conductivity of Aluminum, Copper, Iron, and Tungsten from 1K to the Melting Point, US Department of Commerce, Boulder, Colorado, 1984, - fitted to Tab. 2.4.1 (RRR=1000, T_min=200K, T_max=1000K) + fit to Tab. 2.4.1 (RRR=1000, T_min=200K, T_max=1000K) - https://www.mit.edu/~6.777/matprops/copper.htm + K_11: 4.039e+02 K_11,T: -8.119e-02 K_11,T^2: 1.454e-05 + T_ref: 293.15 + C_p: 385.0 diff --git a/examples/config/phase/thermal/Fe.yaml b/examples/config/phase/thermal/Fe.yaml index 49d397599..7fa8902bb 100644 --- a/examples/config/phase/thermal/Fe.yaml +++ b/examples/config/phase/thermal/Fe.yaml @@ -2,10 +2,13 @@ references: - J.G. Hust and A.B. Lankford, Thermal Conductivity of Aluminum, Copper, Iron, and Tungsten from 1K to the Melting Point, US Department of Commerce, Boulder, Colorado, 1984, - fitted to Tab. 4.4.1 (RRR=300, T_min=200K, T_max=1000K) + fit to Tab. 4.4.1 (RRR=300, T_min=200K, T_max=1000K) - https://www.engineeringtoolbox.com/specific-heat-metals-d_152.html + K_11: 8.055e+01 K_11,T: -1.051e-01 K_11,T^2: 5.464e-05 + T_ref: 293.15 + C_p: 450.0 diff --git a/examples/config/phase/thermal/W.yaml b/examples/config/phase/thermal/W.yaml index af4a164c8..2f9ef56e8 100644 --- a/examples/config/phase/thermal/W.yaml +++ b/examples/config/phase/thermal/W.yaml @@ -2,10 +2,13 @@ references: - J.G. Hust and A.B. Lankford, Thermal Conductivity of Aluminum, Copper, Iron, and Tungsten from 1K to the Melting Point, US Department of Commerce, Boulder, Colorado, 1984, - fitted to Tab. 5.4.1 (RRR=300, T_min=200K, T_max=1000K) + fit to Tab. 5.4.1 (RRR=300, T_min=200K, T_max=1000K) - https://www.mit.edu/~6.777/matprops/tungsten.htm + K_11: 1.758e+02 K_11,T: -1.605e-01 K_11,T^2: 1.160e-04 + T_ref: 293.15 + C_p: 132.51 diff --git a/examples/config/phase/thermal/source/dissipation_generic.yaml b/examples/config/phase/thermal/source/dissipation_generic.yaml index af5214582..87bed84af 100644 --- a/examples/config/phase/thermal/source/dissipation_generic.yaml +++ b/examples/config/phase/thermal/source/dissipation_generic.yaml @@ -1,2 +1,3 @@ type: dissipation + kappa: .9 diff --git a/examples/config/phase/thermal/source/externalheat_ramp-and-hold.yaml b/examples/config/phase/thermal/source/externalheat_ramp-and-hold.yaml index 333ece989..3567f55cf 100644 --- a/examples/config/phase/thermal/source/externalheat_ramp-and-hold.yaml +++ b/examples/config/phase/thermal/source/externalheat_ramp-and-hold.yaml @@ -1,3 +1,4 @@ type: externalheat + f_T: [1, 1, 0, 0] t_n: [0, 500, 500.001, 1000] diff --git a/examples/config/phase/thermal/steel-0.5C.yaml b/examples/config/phase/thermal/steel-0.5C.yaml index 1b1d8995a..e810a811d 100644 --- a/examples/config/phase/thermal/steel-0.5C.yaml +++ b/examples/config/phase/thermal/steel-0.5C.yaml @@ -1,5 +1,6 @@ references: - https://www.engineeringtoolbox.com/thermal-conductivity-metals-d_858.html - https://www.engineeringtoolbox.com/specific-heat-metals-d_152.html + C_p: 490.0 K_11: 54.0 From 80f5496ef2862ef2c6b8c63247a408667056b3e1 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 12 Feb 2022 21:26:42 +0100 Subject: [PATCH 47/72] adjustments and improved documentation --- .../eigen/thermalexpansion_AISI304.yaml | 10 ++++++--- .../mechanical/eigen/thermalexpansion_Al.yaml | 4 ++-- .../mechanical/eigen/thermalexpansion_Au.yaml | 4 ++-- .../mechanical/eigen/thermalexpansion_Cu.yaml | 4 ++-- .../mechanical/eigen/thermalexpansion_Fe.yaml | 4 ++-- .../eigen/thermalexpansion_Sn-beta.yaml | 2 +- .../mechanical/eigen/thermalexpansion_W.yaml | 4 ++-- .../phase/mechanical/elastic/Hooke_Fe.yaml | 21 ++++++++++--------- 8 files changed, 29 insertions(+), 24 deletions(-) diff --git a/examples/config/phase/mechanical/eigen/thermalexpansion_AISI304.yaml b/examples/config/phase/mechanical/eigen/thermalexpansion_AISI304.yaml index f3605e1d9..bc0db5c5e 100644 --- a/examples/config/phase/mechanical/eigen/thermalexpansion_AISI304.yaml +++ b/examples/config/phase/mechanical/eigen/thermalexpansion_AISI304.yaml @@ -3,7 +3,11 @@ type: thermalexpansion references: - R.H. Bogaard et al., Thermochimica Acta 218:373-393, 1993, - https://doi.org/10.1016/0040-6031(93)80437-F + https://doi.org/10.1016/0040-6031(93)80437-F, + fit to Fig. 6 (T_min=100K, T_max=1400K) -A_11: 15.0e-6 -T_ref: 300.0 +A_11: 2.068e-08 +A_11,T: 1.579e-09 +A_11,T^2: 3.449e-13 + +T_ref: 293.15 diff --git a/examples/config/phase/mechanical/eigen/thermalexpansion_Al.yaml b/examples/config/phase/mechanical/eigen/thermalexpansion_Al.yaml index ccd8b347b..495680b4e 100644 --- a/examples/config/phase/mechanical/eigen/thermalexpansion_Al.yaml +++ b/examples/config/phase/mechanical/eigen/thermalexpansion_Al.yaml @@ -1,7 +1,7 @@ type: thermalexpansion references: - - https://en.wikipedia.org/wiki/Thermal_expansion + - https://en.wikipedia.org/wiki/Thermal_expansion, + 293.15K A_11: 23.1e-6 -T_ref: 293.15 diff --git a/examples/config/phase/mechanical/eigen/thermalexpansion_Au.yaml b/examples/config/phase/mechanical/eigen/thermalexpansion_Au.yaml index 8211516de..a14ac6b0f 100644 --- a/examples/config/phase/mechanical/eigen/thermalexpansion_Au.yaml +++ b/examples/config/phase/mechanical/eigen/thermalexpansion_Au.yaml @@ -1,7 +1,7 @@ type: thermalexpansion references: - - https://en.wikipedia.org/wiki/Thermal_expansion + - https://en.wikipedia.org/wiki/Thermal_expansion, + 293.15K A_11: 14.e-6 -T_ref: 293.15 diff --git a/examples/config/phase/mechanical/eigen/thermalexpansion_Cu.yaml b/examples/config/phase/mechanical/eigen/thermalexpansion_Cu.yaml index d7c71931b..a0a35c955 100644 --- a/examples/config/phase/mechanical/eigen/thermalexpansion_Cu.yaml +++ b/examples/config/phase/mechanical/eigen/thermalexpansion_Cu.yaml @@ -1,7 +1,7 @@ type: thermalexpansion references: - - https://en.wikipedia.org/wiki/Thermal_expansion + - https://en.wikipedia.org/wiki/Thermal_expansion, + 293.15K A_11: 17.e-6 -T_ref: 293.15 diff --git a/examples/config/phase/mechanical/eigen/thermalexpansion_Fe.yaml b/examples/config/phase/mechanical/eigen/thermalexpansion_Fe.yaml index 9798fb8a0..da8ead4c1 100644 --- a/examples/config/phase/mechanical/eigen/thermalexpansion_Fe.yaml +++ b/examples/config/phase/mechanical/eigen/thermalexpansion_Fe.yaml @@ -1,7 +1,7 @@ type: thermalexpansion references: - - https://en.wikipedia.org/wiki/Thermal_expansion + - https://en.wikipedia.org/wiki/Thermal_expansion, + 293.15K A_11: 11.8e-6 -T_ref: 293.15 diff --git a/examples/config/phase/mechanical/eigen/thermalexpansion_Sn-beta.yaml b/examples/config/phase/mechanical/eigen/thermalexpansion_Sn-beta.yaml index 16e78f82c..f77f79bba 100644 --- a/examples/config/phase/mechanical/eigen/thermalexpansion_Sn-beta.yaml +++ b/examples/config/phase/mechanical/eigen/thermalexpansion_Sn-beta.yaml @@ -4,7 +4,7 @@ references: - V.T. Deshpande and D.B. Sirdeshmukh, Acta Crystallographica 15:294-295, 1962, https://doi.org/10.1107/S0365110X62000742, - fit to Tab. 2 + fit to Tab. 2 (T_min=30ºC, T_max=210ºC) A_11: 1.639e-05 A_11,T: 1.799e-08 diff --git a/examples/config/phase/mechanical/eigen/thermalexpansion_W.yaml b/examples/config/phase/mechanical/eigen/thermalexpansion_W.yaml index 338f60fe2..cb29ab270 100644 --- a/examples/config/phase/mechanical/eigen/thermalexpansion_W.yaml +++ b/examples/config/phase/mechanical/eigen/thermalexpansion_W.yaml @@ -1,7 +1,7 @@ type: thermalexpansion references: - - https://en.wikipedia.org/wiki/Thermal_expansion + - https://en.wikipedia.org/wiki/Thermal_expansion, + 293.15K A_11: 4.5e-6 -T_ref: 293.15 diff --git a/examples/config/phase/mechanical/elastic/Hooke_Fe.yaml b/examples/config/phase/mechanical/elastic/Hooke_Fe.yaml index a6d7d1868..198a2b4d3 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_Fe.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_Fe.yaml @@ -4,17 +4,18 @@ references: - D.J. Dever, Journal of Applied Physics 43(8):3293-3301, 1972, https://doi.org/10.1063/1.1661710 + fit to Tab. II (T_min=25ºC, T_max=880ºC) -C_11: 231.7e+9 -C_11,T: -47.6e+6 -C_11,T^2: -54.4e+3 +C_11: 232.1e+9 +C_11,T: -4.678e+7 +C_11,T^2: -5.762e+4 -C_12: 135.8e+9 -C_12,T: -12.9e+6 -C_12,T^2: -7.3e+3 +C_12: 135.9e+9 +C_12,T: -1.695e+7 +C_12,T^2: 1.555e+3 -C_44: 116.8e+9 -C_44,T: -19.4e+6 -C_44,T^2: -2.5e+3 +C_44: 117.0e+9 +C_44,T: -2.047e+7 +C_44,T^2: -2.814e+2 -T_ref: 300 +T_ref: 293.15 From 663b84641e20521896ca15cd0473680fd5349ac6 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 12 Feb 2022 22:29:56 +0100 Subject: [PATCH 48/72] needed for a complete set for Sn-beta --- examples/config/phase/thermal/Sn-beta.yaml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 examples/config/phase/thermal/Sn-beta.yaml diff --git a/examples/config/phase/thermal/Sn-beta.yaml b/examples/config/phase/thermal/Sn-beta.yaml new file mode 100644 index 000000000..a4d16cd98 --- /dev/null +++ b/examples/config/phase/thermal/Sn-beta.yaml @@ -0,0 +1,18 @@ +references: + - Y.S. Touloukian et al., + TPRC Data Series Volume 1. Thermal conductivity - metallic elements and alloys, + IFI/Plenum, 1970, + fit to Tab. 61R (T_min=100K, T_max=400K) + - https://www.engineeringtoolbox.com/specific-heat-metals-d_152.html + +K_11: 7.414e+1 +K_11,T: -6.465e-2 +K_11,T^2: 2.066e-4 + +K_33: 5.147e+1 +K_33,T: -4.506e-2 +K_33,T^2: 1.435e-4 + +T_ref: 293.15 + +C_p: 210.0 From 2c05395b88c4b0b6e693e87db2ad0845b4de1556 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 12 Feb 2022 22:30:46 +0100 Subject: [PATCH 49/72] including test for new data --- PRIVATE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PRIVATE b/PRIVATE index 5774122bf..19a2a62de 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit 5774122bf48d637704bb4afb10b87c34a4dbcaba +Subproject commit 19a2a62ded818e4843cf8a248ec6189ff9e4359b From 99c2f5855332885a2bf8ead476f1824ed9748fd8 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 12 Feb 2022 22:38:58 +0100 Subject: [PATCH 50/72] ensure that data is read --- src/phase_mechanical_elastic.f90 | 2 +- src/phase_thermal.f90 | 21 ++++++++++++++------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/phase_mechanical_elastic.f90 b/src/phase_mechanical_elastic.f90 index 7f30c8165..84ad7a20e 100644 --- a/src/phase_mechanical_elastic.f90 +++ b/src/phase_mechanical_elastic.f90 @@ -48,7 +48,7 @@ module subroutine elastic_init(phases) prm%C_11 = polynomial(elastic%asDict(),'C_11','T') prm%C_12 = polynomial(elastic%asDict(),'C_12','T') prm%C_44 = polynomial(elastic%asDict(),'C_44','T') - + if (any(phase_lattice(ph) == ['hP','tI'])) then prm%C_13 = polynomial(elastic%asDict(),'C_13','T') prm%C_33 = polynomial(elastic%asDict(),'C_33','T') diff --git a/src/phase_thermal.f90 b/src/phase_thermal.f90 index bc464d35a..11314531e 100644 --- a/src/phase_thermal.f90 +++ b/src/phase_thermal.f90 @@ -96,17 +96,24 @@ module subroutine thermal_init(phases) do ph = 1, phases%length Nmembers = count(material_phaseID == ph) - allocate(current(ph)%T(Nmembers),source=300.0_pReal) + allocate(current(ph)%T(Nmembers),source=T_ROOM) allocate(current(ph)%dot_T(Nmembers),source=0.0_pReal) phase => phases%get(ph) thermal => phase%get('thermal',defaultVal=emptyDict) - param(ph)%C_p = thermal%get_asFloat('C_p',defaultVal=0.0_pReal) ! ToDo: make mandatory? - param(ph)%K(1,1) = thermal%get_asFloat('K_11',defaultVal=0.0_pReal) ! ToDo: make mandatory? - param(ph)%K(3,3) = thermal%get_asFloat('K_33',defaultVal=0.0_pReal) ! ToDo: depends on symmtery - param(ph)%K = lattice_symmetrize_33(param(ph)%K,phase_lattice(ph)) - sources => thermal%get('source',defaultVal=emptyList) - thermal_Nsources(ph) = sources%length + ! ToDo: temperature dependency of K and C_p + if (thermal%length > 0) then + param(ph)%C_p = thermal%get_asFloat('C_p') + param(ph)%K(1,1) = thermal%get_asFloat('K_11') + if (any(phase_lattice(ph) == ['hP','tI'])) param(ph)%K(3,3) = thermal%get_asFloat('K_33') + param(ph)%K = lattice_symmetrize_33(param(ph)%K,phase_lattice(ph)) + + sources => thermal%get('source',defaultVal=emptyList) + thermal_Nsources(ph) = sources%length + else + thermal_Nsources(ph) = 0 + end if + allocate(thermalstate(ph)%p(thermal_Nsources(ph))) enddo From 2907facfd34c4ad79b3f89fb7609c536c892d63a Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 13 Feb 2022 01:24:02 +0100 Subject: [PATCH 51/72] polishing classes should return 'MyType' for inheritance without hassle --- python/damask/_crystal.py | 2 +- python/damask/_orientation.py | 39 ++++++++++++------------- python/damask/_rotation.py | 55 +++++++++++++++++------------------ python/damask/_typehints.py | 3 +- 4 files changed, 47 insertions(+), 52 deletions(-) diff --git a/python/damask/_crystal.py b/python/damask/_crystal.py index 6da13f679..077d2e13a 100644 --- a/python/damask/_crystal.py +++ b/python/damask/_crystal.py @@ -31,7 +31,7 @@ lattice_symmetries: Dict[CrystalLattice, CrystalFamily] = { class Crystal(): """Crystal lattice.""" - def __init__(self,*, + def __init__(self, *, family: CrystalFamily = None, lattice: CrystalLattice = None, a: float = None, b: float = None, c: float = None, diff --git a/python/damask/_orientation.py b/python/damask/_orientation.py index 54ffb6728..16df11984 100644 --- a/python/damask/_orientation.py +++ b/python/damask/_orientation.py @@ -1,6 +1,6 @@ import inspect import copy -from typing import Union, Callable, List, Dict, Any, Tuple +from typing import Union, Callable, List, Dict, Any, Tuple, TypeVar import numpy as np @@ -11,7 +11,6 @@ from . import util from . import tensor - _parameter_doc = \ """ family : {'triclinic', 'monoclinic', 'orthorhombic', 'tetragonal', 'hexagonal', 'cubic'}, optional. @@ -36,6 +35,7 @@ _parameter_doc = \ """ +MyType = TypeVar('MyType', bound='Orientation') class Orientation(Rotation,Crystal): """ @@ -124,8 +124,8 @@ class Orientation(Rotation,Crystal): return '\n'.join([Crystal.__repr__(self), Rotation.__repr__(self)]) - def __copy__(self, - rotation: Union[FloatSequence, Rotation] = None) -> 'Orientation': + def __copy__(self: MyType, + rotation: Union[FloatSequence, Rotation] = None) -> MyType: """Create deep copy.""" dup = copy.deepcopy(self) if rotation is not None: @@ -189,7 +189,7 @@ class Orientation(Rotation,Crystal): Returns ------- - mask : numpy.ndarray of bool + mask : numpy.ndarray of bool, shape (self.shape) Mask indicating where corresponding orientations are close. """ @@ -230,8 +230,8 @@ class Orientation(Rotation,Crystal): return bool(np.all(self.isclose(other,rtol,atol,equal_nan))) - def __mul__(self, - other: Union[Rotation, 'Orientation']) -> 'Orientation': + def __mul__(self: MyType, + other: Union[Rotation, 'Orientation']) -> MyType: """ Compose this orientation with other. @@ -246,8 +246,8 @@ class Orientation(Rotation,Crystal): Compound rotation self*other, i.e. first other then self rotation. """ - if isinstance(other,Orientation) or isinstance(other,Rotation): - return self.copy(rotation=Rotation.__mul__(self,Rotation(other.quaternion))) + if isinstance(other, (Orientation,Rotation)): + return self.copy(Rotation(self.quaternion)*Rotation(other.quaternion)) else: raise TypeError('use "O@b", i.e. matmul, to apply Orientation "O" to object "b"') @@ -382,11 +382,11 @@ class Orientation(Rotation,Crystal): x = o.to_frame(uvw=uvw) z = o.to_frame(hkl=hkl) om = np.stack([x,np.cross(z,x),z],axis=-2) - return o.copy(rotation=Rotation.from_matrix(tensor.transpose(om/np.linalg.norm(om,axis=-1,keepdims=True)))) + return o.copy(Rotation.from_matrix(tensor.transpose(om/np.linalg.norm(om,axis=-1,keepdims=True)))) @property - def equivalent(self) -> 'Orientation': + def equivalent(self: MyType) -> MyType: """ Orientations that are symmetrically equivalent. @@ -396,11 +396,11 @@ class Orientation(Rotation,Crystal): """ sym_ops = self.symmetry_operations o = sym_ops.broadcast_to(sym_ops.shape+self.shape,mode='right') - return self.copy(rotation=o*Rotation(self.quaternion).broadcast_to(o.shape,mode='left')) + return self.copy(o*Rotation(self.quaternion).broadcast_to(o.shape,mode='left')) @property - def reduced(self) -> 'Orientation': + def reduced(self: MyType) -> MyType: """Select symmetrically equivalent orientation that falls into fundamental zone according to symmetry.""" eq = self.equivalent ok = eq.in_FZ @@ -616,11 +616,8 @@ class Orientation(Rotation,Crystal): np.argmin(m,axis=0)[np.newaxis,...,np.newaxis], axis=0), axis=0)) - return ( - (self.copy(rotation=Rotation(r).average(weights)), - self.copy(rotation=Rotation(r))) - if return_cloud else - self.copy(rotation=Rotation(r).average(weights)) + return ((self.copy(Rotation(r).average(weights)),self.copy(Rotation(r))) if return_cloud else + self.copy(Rotation(r).average(weights)) ) @@ -930,7 +927,7 @@ class Orientation(Rotation,Crystal): if active == '*': active = [len(a) for a in kinematics['direction']] if not active: - raise RuntimeError # ToDo + raise ValueError('Schmid matrix not defined') d = self.to_frame(uvw=np.vstack([kinematics['direction'][i][:n] for i,n in enumerate(active)])) p = self.to_frame(hkl=np.vstack([kinematics['plane'][i][:n] for i,n in enumerate(active)])) P = np.einsum('...i,...j',d/np.linalg.norm(d,axis=1,keepdims=True), @@ -941,8 +938,8 @@ class Orientation(Rotation,Crystal): @ np.broadcast_to(P.reshape(util.shapeshifter(P.shape,shape)),shape) - def related(self, - model: str) -> 'Orientation': + def related(self: MyType, + model: str) -> MyType: """ Orientations derived from the given relationship. diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index 273cf8e92..b11147482 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -1,14 +1,13 @@ import copy +from typing import Union, Sequence, Tuple, Literal, List, TypeVar import numpy as np +from ._typehints import FloatSequence, IntSequence, NumpyRngSeed from . import tensor from . import util from . import grid_filters -from typing import Union, Sequence, Tuple, Literal, List, TypeVar -from ._typehints import FloatSequence, IntSequence, NumpyRngSeed - _P = -1 # parameters for conversion from/to cubochoric @@ -109,7 +108,7 @@ class Rotation: item: Union[Tuple[int], int, bool, np.bool_, np.ndarray]): """Return slice according to item.""" return self.copy() if self.shape == () else \ - self.copy(rotation=self.quaternion[item+(slice(None),)] if isinstance(item,tuple) else self.quaternion[item]) + self.copy(self.quaternion[item+(slice(None),)] if isinstance(item,tuple) else self.quaternion[item]) def __eq__(self, @@ -162,7 +161,7 @@ class Rotation: Returns ------- - mask : numpy.ndarray of bool + mask : numpy.ndarray of bool, shape (self.shape) Mask indicating where corresponding rotations are close. """ @@ -233,13 +232,13 @@ class Rotation: Parameters ---------- - exp : scalar + exp : float Exponent. """ phi = np.arccos(self.quaternion[...,0:1]) p = self.quaternion[...,1:]/np.linalg.norm(self.quaternion[...,1:],axis=-1,keepdims=True) - return self.copy(rotation=Rotation(np.block([np.cos(exp*phi),np.sin(exp*phi)*p]))._standardize()) + return self.copy(Rotation(np.block([np.cos(exp*phi),np.sin(exp*phi)*p]))._standardize()) def __ipow__(self: MyType, exp: Union[float, int]) -> MyType: @@ -248,7 +247,7 @@ class Rotation: Parameters ---------- - exp : scalar + exp : float Exponent. """ @@ -278,7 +277,7 @@ class Rotation: p_o = other.quaternion[...,1:] q = (q_m*q_o - np.einsum('...i,...i',p_m,p_o).reshape(self.shape+(1,))) p = q_m*p_o + q_o*p_m + _P * np.cross(p_m,p_o) - return Rotation(np.block([q,p]))._standardize() #type: ignore + return self.copy(Rotation(np.block([q,p]))._standardize()) else: raise TypeError('Use "R@b", i.e. matmul, to apply rotation "R" to object "b"') @@ -391,8 +390,8 @@ class Rotation: other : (list of) damask.Rotation """ - return self.copy(rotation=np.vstack(tuple(map(lambda x:x.quaternion, - [self]+other if isinstance(other,list) else [self,other])))) + return self.copy(np.vstack(tuple(map(lambda x:x.quaternion, + [self]+other if isinstance(other,list) else [self,other])))) def flatten(self: MyType, @@ -415,7 +414,7 @@ class Rotation: Rotation flattened to single dimension. """ - return self.copy(rotation=self.quaternion.reshape((-1,4),order=order)) + return self.copy(self.quaternion.reshape((-1,4),order=order)) def reshape(self: MyType, @@ -443,7 +442,7 @@ class Rotation: """ if isinstance(shape,(int,np.integer)): shape = (shape,) - return self.copy(rotation=self.quaternion.reshape(tuple(shape)+(4,),order=order)) + return self.copy(self.quaternion.reshape(tuple(shape)+(4,),order=order)) def broadcast_to(self: MyType, @@ -467,18 +466,18 @@ class Rotation: """ if isinstance(shape,(int,np.integer)): shape = (shape,) - return self.copy(rotation=np.broadcast_to(self.quaternion.reshape(util.shapeshifter(self.shape,shape,mode)+(4,)), + return self.copy(np.broadcast_to(self.quaternion.reshape(util.shapeshifter(self.shape,shape,mode)+(4,)), shape+(4,))) - def average(self, - weights: FloatSequence = None) -> 'Rotation': + def average(self: MyType, + weights: FloatSequence = None) -> MyType: """ Average along last array dimension. Parameters ---------- - weights : numpy.ndarray, optional + weights : numpy.ndarray, shape (self.shape), optional Relative weight of each rotation. Returns @@ -501,13 +500,13 @@ class Rotation: eig, vec = np.linalg.eig(np.sum(_M(self.quaternion) * weights_[...,np.newaxis,np.newaxis],axis=-3) \ /np.sum( weights_[...,np.newaxis,np.newaxis],axis=-3)) - return Rotation.from_quaternion(np.real( - np.squeeze( - np.take_along_axis(vec, - eig.argmax(axis=-1)[...,np.newaxis,np.newaxis], - axis=-1), - axis=-1)), - accept_homomorph = True) + return self.copy(Rotation.from_quaternion(np.real( + np.squeeze( + np.take_along_axis(vec, + eig.argmax(axis=-1)[...,np.newaxis,np.newaxis], + axis=-1), + axis=-1)), + accept_homomorph = True)) def misorientation(self: MyType, @@ -730,7 +729,7 @@ class Rotation: Sign convention. Defaults to -1. """ - qu: np.ndarray = np.array(q,dtype=float) + qu = np.array(q,dtype=float) if qu.shape[:-2:-1] != (4,): raise ValueError('Invalid shape.') if abs(P) != 1: @@ -996,7 +995,7 @@ class Rotation: Defaults to None, i.e. unpredictable entropy will be pulled from the OS. """ - rng: np.random.Generator = np.random.default_rng(rng_seed) + rng = np.random.default_rng(rng_seed) r = rng.random(3 if shape is None else tuple(shape)+(3,) if hasattr(shape, '__iter__') else (shape,3)) #type: ignore A = np.sqrt(r[...,2]) @@ -1131,8 +1130,8 @@ class Rotation: """ rng = np.random.default_rng(rng_seed) - sigma_: np.ndarray; alpha_: np.ndarray; beta_: np.ndarray - sigma_,alpha_,beta_ = (np.radians(coordinate) for coordinate in (sigma,alpha,beta)) if degrees else (sigma,alpha,beta) #type: ignore + sigma_,alpha_,beta_ = (np.radians(coordinate) for coordinate in (sigma,alpha,beta)) if degrees else \ + map(np.array, (sigma,alpha,beta)) d_cr = np.array([np.sin(alpha_[0])*np.cos(alpha_[1]), np.sin(alpha_[0])*np.sin(alpha_[1]), np.cos(alpha_[0])]) d_lab = np.array([np.sin( beta_[0])*np.cos( beta_[1]), np.sin( beta_[0])*np.sin( beta_[1]), np.cos( beta_[0])]) diff --git a/python/damask/_typehints.py b/python/damask/_typehints.py index 674f54721..5fcf39a41 100644 --- a/python/damask/_typehints.py +++ b/python/damask/_typehints.py @@ -9,10 +9,9 @@ import numpy as np FloatSequence = Union[np.ndarray,Sequence[float]] IntSequence = Union[np.ndarray,Sequence[int]] FileHandle = Union[TextIO, str, Path] -NumpyRngSeed = Union[int, IntSequence, np.random.SeedSequence, np.random.Generator] CrystalFamily = Union[None,Literal['triclinic', 'monoclinic', 'orthorhombic', 'tetragonal', 'hexagonal', 'cubic']] CrystalLattice = Union[None,Literal['aP', 'mP', 'mS', 'oP', 'oS', 'oI', 'oF', 'tP', 'tI', 'hP', 'cP', 'cI', 'cF']] CrystalKinematics = Literal['slip', 'twin'] - +NumpyRngSeed = Union[int, IntSequence, np.random.SeedSequence, np.random.Generator] # BitGenerator does not exists in older numpy versions #NumpyRngSeed = Union[int, IntSequence, np.random.SeedSequence, np.random.BitGenerator, np.random.Generator] From b1922c9fc03c295446b320281c44da0eda212225 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 13 Feb 2022 10:41:10 +0100 Subject: [PATCH 52/72] return most specific type --- python/damask/_orientation.py | 8 ++++---- python/damask/util.py | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/python/damask/_orientation.py b/python/damask/_orientation.py index 16df11984..c3afd0bed 100644 --- a/python/damask/_orientation.py +++ b/python/damask/_orientation.py @@ -558,8 +558,8 @@ class Orientation(Rotation,Crystal): s = self.equivalent o = other.equivalent - s_ = s.reshape((s.shape[0],1)+ self.shape).broadcast_to((s.shape[0],o.shape[0])+blend,mode='right') #type: ignore - o_ = o.reshape((1,o.shape[0])+other.shape).broadcast_to((s.shape[0],o.shape[0])+blend,mode='right') #type: ignore + s_ = s.reshape((s.shape[0],1)+ self.shape).broadcast_to((s.shape[0],o.shape[0])+blend,mode='right') + o_ = o.reshape((1,o.shape[0])+other.shape).broadcast_to((s.shape[0],o.shape[0])+blend,mode='right') r_ = s_.misorientation(o_) _r = ~r_ @@ -654,7 +654,7 @@ class Orientation(Rotation,Crystal): raise ValueError('input is not a field of three-dimensional vectors') eq = self.equivalent blend = util.shapeblender(eq.shape,vector_.shape[:-1]) - poles = eq.broadcast_to(blend,mode='right') @ np.broadcast_to(vector_,blend+(3,)) #type: ignore + poles = eq.broadcast_to(blend,mode='right') @ np.broadcast_to(vector_,blend+(3,)) ok = self.in_SST(poles,proper=proper) ok &= np.cumsum(ok,axis=0) == 1 loc = np.where(ok) @@ -884,7 +884,7 @@ class Orientation(Rotation,Crystal): blend += sym_ops.shape v = sym_ops.broadcast_to(shape) \ @ np.broadcast_to(v.reshape(util.shapeshifter(v.shape,shape+(3,))),shape+(3,)) - return ~(self.broadcast_to(blend))@ np.broadcast_to(v,blend+(3,)) #type: ignore + return ~(self.broadcast_to(blend))@ np.broadcast_to(v,blend+(3,)) def Schmid(self, *, diff --git a/python/damask/util.py b/python/damask/util.py index cc5b8906e..ab34df7c0 100644 --- a/python/damask/util.py +++ b/python/damask/util.py @@ -9,7 +9,7 @@ import re import fractions from collections import abc from functools import reduce -from typing import Union, Tuple, Iterable, Callable, Dict, List, Any, Literal, SupportsIndex +from typing import Union, Tuple, Iterable, Callable, Dict, List, Any, Literal from pathlib import Path import numpy as np @@ -427,7 +427,7 @@ def hybrid_IA(dist: np.ndarray, def shapeshifter(fro: Tuple[int, ...], to: Tuple[int, ...], mode: Literal['left','right'] = 'left', - keep_ones: bool = False) -> Tuple[SupportsIndex, ...]: + keep_ones: bool = False) -> Tuple[int, ...]: """ Return dimensions that reshape 'fro' to become broadcastable to 'to'. @@ -490,7 +490,7 @@ def shapeshifter(fro: Tuple[int, ...], def shapeblender(a: Tuple[int, ...], - b: Tuple[int, ...]) -> Tuple[SupportsIndex, ...]: + b: Tuple[int, ...]) -> Tuple[int, ...]: """ Return a shape that overlaps the rightmost entries of 'a' with the leftmost of 'b'. From bb6a62c475a34c6f764d6d647c04316089b16277 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 13 Feb 2022 01:49:07 +0100 Subject: [PATCH 53/72] more temperature dependent data --- PRIVATE | 2 +- .../phase/mechanical/elastic/Hooke_Cu.yaml | 22 ++++++++--- .../phase/mechanical/elastic/Hooke_Mg.yaml | 33 +++++++++++++---- .../phase/mechanical/elastic/Hooke_Ni.yaml | 24 ++++++++---- .../phase/mechanical/elastic/Hooke_Ti.yaml | 37 +++++++++++++++---- .../phase/mechanical/elastic/Hooke_W.yaml | 22 ++++++++--- examples/config/phase/thermal/Al.yaml | 6 +-- examples/config/phase/thermal/Cu.yaml | 6 +-- examples/config/phase/thermal/Fe.yaml | 6 +-- examples/config/phase/thermal/Ni.yaml | 14 +++++++ examples/config/phase/thermal/W.yaml | 6 +-- 11 files changed, 131 insertions(+), 47 deletions(-) create mode 100644 examples/config/phase/thermal/Ni.yaml diff --git a/PRIVATE b/PRIVATE index 19a2a62de..0d639a9ba 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit 19a2a62ded818e4843cf8a248ec6189ff9e4359b +Subproject commit 0d639a9ba41db279b0d2825c8e8eddf0ccd91326 diff --git a/examples/config/phase/mechanical/elastic/Hooke_Cu.yaml b/examples/config/phase/mechanical/elastic/Hooke_Cu.yaml index 90a0bd269..d21324084 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_Cu.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_Cu.yaml @@ -1,9 +1,21 @@ type: Hooke references: - - https://www.mit.edu/~6.777/matprops/copper.htm, - fixed typo + - W.C. Overton, Jr. and J. Gaffney, + Physical Review 98(4):969-977, 1955, + https://doi.org/10.1103/PhysRev.98.969, + fit to Tab. I (T_min=100K, T_max=300K) -C_11: 168.3e+9 -C_12: 122.1e+9 -C_44: 75.7e+9 +C_11: 168.6e+9 +C_11,T: -3.779e+7 +C_11,T^2: -2.536e+4 + +C_12: 121.5e+9 +C_12,T: -1.632e+7 +C_12,T^2: -1.116e+4 + +C_44: 75.59e+9 +C_44,T: -2.912e+7 +C_44,T^2: -1.669e+4 + +T_ref: 293.15 diff --git a/examples/config/phase/mechanical/elastic/Hooke_Mg.yaml b/examples/config/phase/mechanical/elastic/Hooke_Mg.yaml index aa089d4b4..06a6cfb62 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_Mg.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_Mg.yaml @@ -1,12 +1,29 @@ type: Hooke references: - - D. Tromans, - International Journal of Recent Research and Applied Studies 6(4):462-483, 2011, - https://www.arpapress.com/Volumes/Vol6Issue4/IJRRAS_6_4_14.pdf + - L.J. Slutsky and C.W. Garland, + Physical Review 107(4):972-976, 1957, + https://doi.org/10.1103/PhysRev.107.972, + fit to Tab. I (T_min=100K, T_max=300K) -C_11: 59.3e+9 -C_33: 61.5e+9 -C_44: 16.4e+9 -C_12: 25.7e+9 -C_13: 21.4e+9 +C_11: 59.50e+9 +C_11,T: -1.930e+7 +C_11,T^2: -1.215e+4 + +C_33: 61.72e+9 +C_33,T: -2.175e+7 +C_33,T^2: -5.624e+3 + +C_44: 16.46e+9 +C_44,T: -1.006e+7 +C_44,T^2: -7.692e+3 + +C_12: 25.62e+9 +C_12,T: -2.216e+6 +C_12,T^2: -4.138e+3 + +C_13: 21.46e+9 +C_13,T: -1.921e+6 +C_13,T^2: -4.283e+3 + +T_ref: 293.15 diff --git a/examples/config/phase/mechanical/elastic/Hooke_Ni.yaml b/examples/config/phase/mechanical/elastic/Hooke_Ni.yaml index 6bba784fb..bf63ae047 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_Ni.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_Ni.yaml @@ -1,11 +1,21 @@ type: Hooke references: - - J.P. Hirth and J. Lothe, - Theory of Dislocations, 1982, - John Wiley & Sons, - page 837 + - G.A. Alers, + Journal of Physics and Chemistry of Solids 13(1-2):40-55, 1960, + https://doi.org/10.1016/0022-3697(60)90125-6, + fit to Tab. 2 (T_min=100K, T_max=700K) -C_11: 246.5e+9 -C_12: 147.3e+9 -C_44: 124.7e+9 +C_11: 251.0e+9 +C_11,T: -4.998e+7 +C_11,T^2: -2.952e+4 + +C_12: 150.0e+9 +C_12,T: -4.269e+6 +C_12,T^2: -6.429e+3 + +C_44: 123.7e+9 +C_44,T: -3.618e+7 +C_44,T^2: -7.024e+3 + +T_ref: 293.15 diff --git a/examples/config/phase/mechanical/elastic/Hooke_Ti.yaml b/examples/config/phase/mechanical/elastic/Hooke_Ti.yaml index 79b7c04f7..983452cd9 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_Ti.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_Ti.yaml @@ -1,12 +1,33 @@ type: Hooke references: - - L. Wang et al., - Acta Materialia 132:598-610, 2017, - https://doi.org/10.1016/j.actamat.2017.05.015 + - E.S. Fisher and C.J. Renken, + Physical Review 135(2A):A482-A494, 1964, + https://doi.org/10.1103/PhysRev.135.A482, + fit to Tab. IV (T_min=150K, T_max=250K) + - H. Ogi et al., + Acta Materialia 52(7):2075-2080, 2004, + https://doi.org/10.1016/j.actamat.2004.01.002, + fit to Fig. 3 (T_min=300K, T_max=900K) -C_11: 162.4e+9 -C_33: 181.6e+9 -C_44: 47.2e+9 -C_12: 92.e+9 -C_13: 69.e+9 +C_11: 162.6e+9 +C_11,T: -6.150e+7 +C_11,T^2: -5.557e+2 + +C_33: 183.3e+9 +C_33,T: -1.655e+07 +C_33,T^2: -1.022e+04 + +C_44: 45.80e+9 +C_44,T: -2.936e+07 +C_44,T^2: 7.120e+02 + +C_12: 89.97e+9 +C_12,T: 2.776e+6 +C_12,T^2: -2.389e+4 + +C_13: 69.53e+9 +C_13,T: 1.057e+7 +C_13,T^2: -2.966e+3 + +T_ref: 293.15 diff --git a/examples/config/phase/mechanical/elastic/Hooke_W.yaml b/examples/config/phase/mechanical/elastic/Hooke_W.yaml index a1191f8c7..bb333d6af 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_W.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_W.yaml @@ -1,10 +1,20 @@ type: Hooke references: - - D. Cereceda et al., - International Journal of Plasticity 78:242-265, 2016, - https://doi.org/10.1016/j.ijplas.2015.09.002 + - F.H. Featherston and J.R. Nieghbours, + Physical Review 130(4):1324-1333, + https://doi.org/10.1103/PhysRev.130.1324, + fit to Tab. III (T_min=100K, T_max=300K) -C_11: 523.e+9 -C_12: 202.e+9 -C_44: 161.e+9 +C_11: 523.6e+9 +C_11,T: -7.607e+7 +C_11,T^2: -1.551e+5 + +C_12: 205.1e+9 +C_12,T: -2.843e+6 + +C_44: 160.8e+9 +C_44,T: -1.057e+7 +C_44,T^2: 9.933e+3 + +T_ref: 293.15 diff --git a/examples/config/phase/thermal/Al.yaml b/examples/config/phase/thermal/Al.yaml index 485cc5a31..d2015a5b2 100644 --- a/examples/config/phase/thermal/Al.yaml +++ b/examples/config/phase/thermal/Al.yaml @@ -5,9 +5,9 @@ references: fit to Tab. 3.4.1 (RRR=1000, T_min=200K, T_max=900K) - https://www.engineeringtoolbox.com/specific-heat-metals-d_152.html -K_11: 2.380e+02 -K_11,T: 2.068e-03 -K_11,T^2: -7.765e-05 +K_11: 2.380e+2 +K_11,T: 2.068e-3 +K_11,T^2: -7.765e-5 T_ref: 293.15 diff --git a/examples/config/phase/thermal/Cu.yaml b/examples/config/phase/thermal/Cu.yaml index 50e3fdc23..332ef7cc0 100644 --- a/examples/config/phase/thermal/Cu.yaml +++ b/examples/config/phase/thermal/Cu.yaml @@ -5,9 +5,9 @@ references: fit to Tab. 2.4.1 (RRR=1000, T_min=200K, T_max=1000K) - https://www.mit.edu/~6.777/matprops/copper.htm -K_11: 4.039e+02 -K_11,T: -8.119e-02 -K_11,T^2: 1.454e-05 +K_11: 4.039e+2 +K_11,T: -8.119e-2 +K_11,T^2: 1.454e-5 T_ref: 293.15 diff --git a/examples/config/phase/thermal/Fe.yaml b/examples/config/phase/thermal/Fe.yaml index 7fa8902bb..a8e06ed04 100644 --- a/examples/config/phase/thermal/Fe.yaml +++ b/examples/config/phase/thermal/Fe.yaml @@ -5,9 +5,9 @@ references: fit to Tab. 4.4.1 (RRR=300, T_min=200K, T_max=1000K) - https://www.engineeringtoolbox.com/specific-heat-metals-d_152.html -K_11: 8.055e+01 -K_11,T: -1.051e-01 -K_11,T^2: 5.464e-05 +K_11: 8.055e+1 +K_11,T: -1.051e-1 +K_11,T^2: 5.464e-5 T_ref: 293.15 diff --git a/examples/config/phase/thermal/Ni.yaml b/examples/config/phase/thermal/Ni.yaml new file mode 100644 index 000000000..d71c15a3f --- /dev/null +++ b/examples/config/phase/thermal/Ni.yaml @@ -0,0 +1,14 @@ +references: + - Y.S. Touloukian et al., + TPRC Data Series Volume 1. Thermal conductivity - metallic elements and alloys, + IFI/Plenum, 1970, + fit to Tab. 35R (T_min=150K, T_max=500K) + - https://www.engineeringtoolbox.com/specific-heat-metals-d_152.html + +K_11: 9.132e+1 +K_11,T: -1.525e-1 +K_11,T^2: 3.053e-4 + +T_ref: 293.15 + +C_p: 440.0 diff --git a/examples/config/phase/thermal/W.yaml b/examples/config/phase/thermal/W.yaml index 2f9ef56e8..fb01c285a 100644 --- a/examples/config/phase/thermal/W.yaml +++ b/examples/config/phase/thermal/W.yaml @@ -5,9 +5,9 @@ references: fit to Tab. 5.4.1 (RRR=300, T_min=200K, T_max=1000K) - https://www.mit.edu/~6.777/matprops/tungsten.htm -K_11: 1.758e+02 -K_11,T: -1.605e-01 -K_11,T^2: 1.160e-04 +K_11: 1.758e+2 +K_11,T: -1.605e-1 +K_11,T^2: 1.160e-4 T_ref: 293.15 From ba16ea21a0a6d133fcaa7581afd417e4f47fd8c2 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 13 Feb 2022 14:48:15 +0100 Subject: [PATCH 54/72] avoid overfitting there are only 3 data points for C_13, with one close to 0K. Leave this point out and fit only a 1st order polynomial --- .../config/phase/mechanical/elastic/Hooke_Sn-beta.yaml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/examples/config/phase/mechanical/elastic/Hooke_Sn-beta.yaml b/examples/config/phase/mechanical/elastic/Hooke_Sn-beta.yaml index a49c246f9..57cd2913c 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_Sn-beta.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_Sn-beta.yaml @@ -4,7 +4,7 @@ references: - J.A. Rayne and B.S. Chandrasekhar, Physical Review 120(5):1658-1663, 1960, https://doi.org/10.1103/PhysRev.120.1658, - fit to Fig. 2 and Tab. IV (C_13) + fit to Fig. 2 (T_min=40K, T_max=300K) and Tab. IV (C_13, T_min=77K, T_max=300K) C_11: 72.89e+9 C_11,T: -4.479e+7 @@ -14,9 +14,8 @@ C_12: 59.27e+9 C_12,T: 1.110e+7 C_12,T^2: 1.300e+4 -C_13: 35.97e+9 -C_13,T: -2.638e+7 -C_13,T^2: -1.123e+5 +C_13: 35.80e+9 +C_13,T: -2.870e+6 C_33: 88.77e+10 C_33,T: -5.361e+7 From e3a64ae4ff33867827611a3bd481db82aa583e4b Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 13 Feb 2022 14:57:01 +0100 Subject: [PATCH 55/72] don't fit close to 0K cryogenic temperatures are normally not of interest, avoid considering the strongly curved region below 80K in the fit gives probably better extrapolation properties for T>300K --- .../mechanical/elastic/Hooke_Sn-beta.yaml | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/examples/config/phase/mechanical/elastic/Hooke_Sn-beta.yaml b/examples/config/phase/mechanical/elastic/Hooke_Sn-beta.yaml index 57cd2913c..a208c3aec 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_Sn-beta.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_Sn-beta.yaml @@ -4,29 +4,29 @@ references: - J.A. Rayne and B.S. Chandrasekhar, Physical Review 120(5):1658-1663, 1960, https://doi.org/10.1103/PhysRev.120.1658, - fit to Fig. 2 (T_min=40K, T_max=300K) and Tab. IV (C_13, T_min=77K, T_max=300K) + fit to Fig. 2 (T_min=100K, T_max=300K) and Tab. IV (C_13, T_min=77K, T_max=300K) -C_11: 72.89e+9 -C_11,T: -4.479e+7 -C_11,T^2: -3.149e+4 +C_11: 72.90e+9 +C_11,T: -4.399e+7 +C_11,T^2: -2.645e+4 C_12: 59.27e+9 -C_12,T: 1.110e+7 -C_12,T^2: 1.300e+4 +C_12,T: 1.058e+7 +C_12,T^2: 1.002e+4 C_13: 35.80e+9 C_13,T: -2.870e+6 -C_33: 88.77e+10 -C_33,T: -5.361e+7 -C_33,T^2: -2.770e+3 +C_33: 88.78e+9 +C_33,T: -5.250e+7 +C_33,T^2: 3.546e+3 C_44: 22.26e+9 -C_44,T: -1.994e+7 -C_44,T^2: -9.519e+3 +C_44,T: -1.982e+7 +C_44,T^2: -8.711e+3 -C_66: 24.17e+9 -C_66,T: -1.919e+7 -C_66,T^2: -1.161e+4 +C_66: 24.18e+9 +C_66,T: -1.806e+7 +C_66,T^2: -4.112e+3 T_ref: 293.15 From bba105c2a824aae9133e3809fa129405d6f99549 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 13 Feb 2022 17:58:51 +0100 Subject: [PATCH 56/72] re-fit, documented details --- .../phase/mechanical/elastic/Hooke_Al.yaml | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/examples/config/phase/mechanical/elastic/Hooke_Al.yaml b/examples/config/phase/mechanical/elastic/Hooke_Al.yaml index 97d45e62f..3550449a3 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_Al.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_Al.yaml @@ -3,21 +3,23 @@ type: Hooke references: - G.N. Kamm and G.A. Alers, Journal of Applied Physics 35:327-330, 1964, - https://doi.org/10.1063/1.1713309 + https://doi.org/10.1063/1.1713309, + fit to Tab. I (T_min=100K, T_max=300K) - D. Gerlich and E.S. Fisher, Journal of Physics and Chemistry of Solids 30:1197-1205, 1969 - https://doi.org/10.1016/0022-3697(69)90377-1 + https://doi.org/10.1016/0022-3697(69)90377-1, + fit to Tab. 2 (T_min=293K, T_max=900K) -C_11: 106.1e+9 -C_11,T: -359.3e+5 -C_11,T^2: -152.7e+2 +C_11: 106.9e+9 +C_11,T: -3.685e+7 +C_11,T^2: -1.016e+4 -C_12: 57.83e+9 -C_12,T: -781.6e+4 -C_12,T^2: -551.3e+1 +C_12: 60.55e+9 +C_12,T: -8.307e+6 +C_12,T^2: -4.353e+3 -C_44: 24.31e+9 -C_44,T: -142.9e+5 -C_44,T^2: -404.6e+1 +C_44: 28.37e+9 +C_44,T: -1.418e+7 +C_44,T^2: -3.253e+3 -T_ref: 300 +T_ref: 293.15 From e210a9873d33783289a33349164e689f49a20ff6 Mon Sep 17 00:00:00 2001 From: Test User Date: Mon, 14 Feb 2022 02:21:46 +0100 Subject: [PATCH 57/72] [skip ci] updated version information after successful test of v3.0.0-alpha5-624-g26979da58 --- python/damask/VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/damask/VERSION b/python/damask/VERSION index 00113e2f3..90c1162f3 100644 --- a/python/damask/VERSION +++ b/python/damask/VERSION @@ -1 +1 @@ -v3.0.0-alpha5-608-g3e8d1a60d +v3.0.0-alpha5-624-g26979da58 From 0300912b3032eb7c1a309e620de01c0efecb4b3a Mon Sep 17 00:00:00 2001 From: Philip Eisenlohr Date: Sun, 13 Feb 2022 22:00:48 -0500 Subject: [PATCH 58/72] Table.__eq__ for proper comparison; logical masks for slicing now work --- python/damask/_table.py | 27 ++++++++++++++++++--------- python/tests/test_Table.py | 6 +++++- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/python/damask/_table.py b/python/damask/_table.py index 1572c4f76..81c23e73b 100644 --- a/python/damask/_table.py +++ b/python/damask/_table.py @@ -44,6 +44,13 @@ class Table: return '\n'.join(['# '+c for c in self.comments])+'\n'+data_repr + def __eq__(self, + other: object) -> bool: + """Compare to other Table.""" + return NotImplemented if not isinstance(other,Table) else \ + self.shapes == other.shapes and self.data.equals(other.data) + + def __getitem__(self, item: Union[slice, Tuple[slice, ...]]) -> 'Table': """ @@ -75,20 +82,22 @@ class Table: colB colA 0 1 0 2 7 6 - >>> tbl[1:2,'colB'] + >>> tbl[[True,False,False,True],'colB'] colB - 1 4 - 2 7 + 0 1 + 3 10 """ - item = (item,slice(None,None,None)) if isinstance(item,slice) else \ - item if isinstance(item[0],slice) else \ - (slice(None,None,None),item) - sliced = self.data.loc[item] - cols = np.array(sliced.columns if isinstance(sliced,pd.core.frame.DataFrame) else [item[1]]) + item_ = (item,slice(None,None,None)) if isinstance(item,(slice,np.ndarray)) else \ + (np.array(item),slice(None,None,None)) if isinstance(item,list) and np.array(item).dtype == np.bool_ else \ + (np.array(item[0]),item[1]) if isinstance(item[0],list) else \ + item if isinstance(item[0],(slice,np.ndarray)) else \ + (slice(None,None,None),item) + sliced = self.data.loc[item_] + cols = np.array(sliced.columns if isinstance(sliced,pd.core.frame.DataFrame) else [item_[1]]) _,idx = np.unique(cols,return_index=True) return self.__class__(data=sliced, - shapes = {k:self.shapes[k] for k in cols[np.sort(idx)]}, + shapes={k:self.shapes[k] for k in cols[np.sort(idx)]}, comments=self.comments) diff --git a/python/tests/test_Table.py b/python/tests/test_Table.py index 62eb6d63b..1f89026a3 100644 --- a/python/tests/test_Table.py +++ b/python/tests/test_Table.py @@ -59,10 +59,14 @@ class TestTable: @pytest.mark.parametrize('N',[1,3,4]) def test_slice(self,default,N): + mask = np.random.choice([True,False],len(default)) assert len(default[:N]) == 1+N assert len(default[:N,['F','s']]) == 1+N + assert len(default[mask,['F','s']]) == np.count_nonzero(mask) + assert default[mask,['F','s']] == default[mask][['F','s']] == default[['F','s']][mask] + assert default[np.logical_not(mask),['F','s']] != default[mask][['F','s']] assert default[N:].get('F').shape == (len(default)-N,3,3) - assert (default[:N,['v','s']].data == default['v','s'][:N].data).all().all() + assert default[:N,['v','s']].data.equals(default['v','s'][:N].data) @pytest.mark.parametrize('mode',['str','path']) def test_write_read(self,default,tmp_path,mode): From ac4beea14b718b5c86ebc59356e614dbba0c1a42 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 13 Feb 2022 21:00:21 +0100 Subject: [PATCH 59/72] use precalculated dyad --- src/grid/spectral_utilities.f90 | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/grid/spectral_utilities.f90 b/src/grid/spectral_utilities.f90 index 34a976644..28ff0f8b3 100644 --- a/src/grid/spectral_utilities.f90 +++ b/src/grid/spectral_utilities.f90 @@ -372,7 +372,7 @@ subroutine utilities_updateGamma(C) C_ref = C if (.not. num%memory_efficient) then - gamma_hat = cmplx(0.0_pReal,0.0_pReal,pReal) ! for the singular point and any non invertible A + gamma_hat = cmplx(0.0_pReal,0.0_pReal,pReal) ! for the singular point and any non invertible A do k = cells3Offset+1, cells3Offset+cells3; do j = 1, cells(2); do i = 1, grid1Red if (any([i,j,k] /= 1)) then ! singular point at xi=(0.0,0.0,0.0) i.e. i=j=k=1 do concurrent (l = 1:3, m = 1:3) @@ -387,8 +387,7 @@ subroutine utilities_updateGamma(C) call math_invert(A_inv, err, A) temp33_complex = cmplx(A_inv(1:3,1:3),A_inv(1:3,4:6),pReal) do concurrent(l=1:3, m=1:3, n=1:3, o=1:3) - gamma_hat(l,m,n,o,i,j,k-cells3Offset) = temp33_complex(l,n)* & - conjg(-xi1st(o,i,j,k-cells3Offset))*xi1st(m,i,j,k-cells3Offset) + gamma_hat(l,m,n,o,i,j,k-cells3Offset) = temp33_complex(l,n) * xiDyad_cmplx(o,m) end do end if end if @@ -507,7 +506,7 @@ subroutine utilities_fourierGammaConvolution(fieldAim) call math_invert(A_inv, err, A) temp33_complex = cmplx(A_inv(1:3,1:3),A_inv(1:3,4:6),pReal) do concurrent(l=1:3, m=1:3, n=1:3, o=1:3) - gamma_hat(l,m,n,o,1,1,1) = temp33_complex(l,n)*conjg(-xi1st(o,i,j,k))*xi1st(m,i,j,k) + gamma_hat(l,m,n,o,1,1,1) = temp33_complex(l,n)*xiDyad_cmplx(o,m) end do else gamma_hat(1:3,1:3,1:3,1:3,1,1,1) = cmplx(0.0_pReal,0.0_pReal,pReal) @@ -521,7 +520,7 @@ subroutine utilities_fourierGammaConvolution(fieldAim) else memoryEfficient do k = 1, cells3; do j = 1, cells(2); do i = 1,grid1Red do concurrent(l = 1:3, m = 1:3) - temp33_Complex(l,m) = sum(gamma_hat(l,m,1:3,1:3,i,j,k) * tensorField_fourier(1:3,1:3,i,j,k)) + temp33_Complex(l,m) = sum(gamma_hat(l,m,1:3,1:3,i,j,k)*tensorField_fourier(1:3,1:3,i,j,k)) end do tensorField_fourier(1:3,1:3,i,j,k) = temp33_Complex end do; end do; end do @@ -884,11 +883,10 @@ pure function utilities_calculateRate(heterogeneous,field0,field,dt,avRate) real(pReal), dimension(3,3,cells(1),cells(2),cells3) :: & utilities_calculateRate - if (heterogeneous) then - utilities_calculateRate = (field-field0) / dt - else - utilities_calculateRate = spread(spread(spread(avRate,3,cells(1)),4,cells(2)),5,cells3) - endif + + utilities_calculateRate = merge((field-field0) / dt, & + spread(spread(spread(avRate,3,cells(1)),4,cells(2)),5,cells3), & + heterogeneous) end function utilities_calculateRate @@ -1041,7 +1039,7 @@ subroutine utilities_updateCoords(F) rank_b = modulo(worldrank-1_MPI_INTEGER_KIND,worldsize) ! send bottom layer to process below - call MPI_Isend(IPfluct_padded(:,:,:,2), c,MPI_DOUBLE,rank_b,0_MPI_INTEGER_KIND,MPI_COMM_WORLD,request(1),err_MPI) + call MPI_Isend(IPfluct_padded(:,:,:,2), c,MPI_DOUBLE,rank_b,0_MPI_INTEGER_KIND,MPI_COMM_WORLD,request(1),err_MPI) if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' call MPI_Irecv(IPfluct_padded(:,:,:,cells3+2),c,MPI_DOUBLE,rank_t,0_MPI_INTEGER_KIND,MPI_COMM_WORLD,request(2),err_MPI) if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' @@ -1049,7 +1047,7 @@ subroutine utilities_updateCoords(F) ! send top layer to process above call MPI_Isend(IPfluct_padded(:,:,:,cells3+1),c,MPI_DOUBLE,rank_t,1_MPI_INTEGER_KIND,MPI_COMM_WORLD,request(3),err_MPI) if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' - call MPI_Irecv(IPfluct_padded(:,:,:,1), c,MPI_DOUBLE,rank_b,1_MPI_INTEGER_KIND,MPI_COMM_WORLD,request(4),err_MPI) + call MPI_Irecv(IPfluct_padded(:,:,:,1), c,MPI_DOUBLE,rank_b,1_MPI_INTEGER_KIND,MPI_COMM_WORLD,request(4),err_MPI) if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' call MPI_Waitall(4,request,status,err_MPI) From 1b08f90d6c8911e1b2f171ff0319c687b7ca820a Mon Sep 17 00:00:00 2001 From: Philip Eisenlohr Date: Sun, 13 Feb 2022 23:54:16 -0500 Subject: [PATCH 60/72] allow constant (non-label) value in cm.from_table() keys --- python/damask/_configmaterial.py | 22 +++++++++++++++++++--- python/tests/test_ConfigMaterial.py | 12 ++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/python/damask/_configmaterial.py b/python/damask/_configmaterial.py index 01d85f6a4..250b52e7e 100644 --- a/python/damask/_configmaterial.py +++ b/python/damask/_configmaterial.py @@ -178,8 +178,9 @@ class ConfigMaterial(Config): table : damask.Table Table that contains material information. **kwargs - Keyword arguments where the key is the name and the value specifies - the label of the data column in the table. + Keyword arguments where the key is the property name and + the value specifies either the label of the data column in the table + or a constant value. Returns ------- @@ -211,8 +212,23 @@ class ConfigMaterial(Config): homogenization: {} phase: {} + >>> cm.from_table(t,O='qu',phase='phase',homogenization='SX') + material: + - constituents: + - O: [0.19, 0.8, 0.24, -0.51] + v: 1.0 + phase: Aluminum + homogenization: SX + - constituents: + - O: [0.8, 0.19, 0.24, -0.51] + v: 1.0 + phase: Steel + homogenization: SX + homogenization: {} + phase: {} + """ - kwargs_ = {k:table.get(v) for k,v in kwargs.items()} + kwargs_ = {k:table.get(v) if v in table.labels else np.atleast_2d([v]*len(table)).T for k,v in kwargs.items()} _,idx = np.unique(np.hstack(list(kwargs_.values())),return_index=True,axis=0) idx = np.sort(idx) diff --git a/python/tests/test_ConfigMaterial.py b/python/tests/test_ConfigMaterial.py index a713b636f..b8b5df52a 100644 --- a/python/tests/test_ConfigMaterial.py +++ b/python/tests/test_ConfigMaterial.py @@ -96,6 +96,18 @@ class TestConfigMaterial: for i,m in enumerate(c['material']): assert m['homogenization'] == 1 and (m['constituents'][0]['O'] == [1,0,1,1]).all() + def test_from_table_with_constant(self): + N = np.random.randint(3,10) + a = np.vstack((np.hstack((np.arange(N),np.arange(N)[::-1])), + np.ones(N*2),np.zeros(N*2),np.ones(N*2),np.ones(N*2), + np.ones(N*2), + )).T + t = Table(a,{'varying':1,'constant':4,'ones':1}) + c = ConfigMaterial.from_table(t,**{'phase':'varying','O':'constant','homogenization':1}) + assert len(c['material']) == N + for i,m in enumerate(c['material']): + assert m['homogenization'] == 1 and (m['constituents'][0]['O'] == [1,0,1,1]).all() + @pytest.mark.parametrize('N,n,kw',[ (1,1,{'phase':'Gold', 'O':[1,0,0,0], From 0008ad1bf8fe7eea6728ab742bd2480b8072a33e Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 14 Feb 2022 05:57:48 +0100 Subject: [PATCH 61/72] easier to understand --- src/grid/spectral_utilities.f90 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/grid/spectral_utilities.f90 b/src/grid/spectral_utilities.f90 index 28ff0f8b3..08d983c8a 100644 --- a/src/grid/spectral_utilities.f90 +++ b/src/grid/spectral_utilities.f90 @@ -508,13 +508,13 @@ subroutine utilities_fourierGammaConvolution(fieldAim) do concurrent(l=1:3, m=1:3, n=1:3, o=1:3) gamma_hat(l,m,n,o,1,1,1) = temp33_complex(l,n)*xiDyad_cmplx(o,m) end do + do concurrent(l = 1:3, m = 1:3) + temp33_Complex(l,m) = sum(gamma_hat(l,m,1:3,1:3,1,1,1)*tensorField_fourier(1:3,1:3,i,j,k)) + end do + tensorField_fourier(1:3,1:3,i,j,k) = temp33_Complex else - gamma_hat(1:3,1:3,1:3,1:3,1,1,1) = cmplx(0.0_pReal,0.0_pReal,pReal) + tensorField_fourier(1:3,1:3,i,j,k) = cmplx(0.0_pReal,0.0_pReal,pReal) end if - do concurrent(l = 1:3, m = 1:3) - temp33_Complex(l,m) = sum(gamma_hat(l,m,1:3,1:3,1,1,1)*tensorField_fourier(1:3,1:3,i,j,k)) - end do - tensorField_fourier(1:3,1:3,i,j,k) = temp33_Complex end if end do; end do; end do else memoryEfficient From 61e11a0529f8f192b411304a8d382feb59532e71 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 14 Feb 2022 07:58:15 +0100 Subject: [PATCH 62/72] use openMP for operations in Fourier space --- src/grid/spectral_utilities.f90 | 65 ++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 26 deletions(-) diff --git a/src/grid/spectral_utilities.f90 b/src/grid/spectral_utilities.f90 index 08d983c8a..418f83b05 100644 --- a/src/grid/spectral_utilities.f90 +++ b/src/grid/spectral_utilities.f90 @@ -362,7 +362,7 @@ end subroutine spectral_utilities_init subroutine utilities_updateGamma(C) real(pReal), intent(in), dimension(3,3,3,3) :: C !< input stiffness to store as reference stiffness - complex(pReal), dimension(3,3) :: temp33_complex, xiDyad_cmplx + complex(pReal), dimension(3,3) :: temp33_cmplx, xiDyad_cmplx real(pReal), dimension(6,6) :: A, A_inv integer :: & i, j, k, & @@ -373,25 +373,27 @@ subroutine utilities_updateGamma(C) if (.not. num%memory_efficient) then gamma_hat = cmplx(0.0_pReal,0.0_pReal,pReal) ! for the singular point and any non invertible A + !$OMP PARALLEL DO PRIVATE(l,m,n,o,temp33_cmplx,xiDyad_cmplx,A,A_inv,err) do k = cells3Offset+1, cells3Offset+cells3; do j = 1, cells(2); do i = 1, grid1Red if (any([i,j,k] /= 1)) then ! singular point at xi=(0.0,0.0,0.0) i.e. i=j=k=1 do concurrent (l = 1:3, m = 1:3) xiDyad_cmplx(l,m) = conjg(-xi1st(l,i,j,k-cells3Offset))*xi1st(m,i,j,k-cells3Offset) end do do concurrent(l = 1:3, m = 1:3) - temp33_complex(l,m) = sum(cmplx(C_ref(l,1:3,m,1:3),0.0_pReal)*xiDyad_cmplx) + temp33_cmplx(l,m) = sum(cmplx(C_ref(l,1:3,m,1:3),0.0_pReal)*xiDyad_cmplx) end do - A(1:3,1:3) = temp33_complex%re; A(4:6,4:6) = temp33_complex%re - A(1:3,4:6) = temp33_complex%im; A(4:6,1:3) = -temp33_complex%im + A(1:3,1:3) = temp33_cmplx%re; A(4:6,4:6) = temp33_cmplx%re + A(1:3,4:6) = temp33_cmplx%im; A(4:6,1:3) = -temp33_cmplx%im if (abs(math_det33(A(1:3,1:3))) > 1e-16) then call math_invert(A_inv, err, A) - temp33_complex = cmplx(A_inv(1:3,1:3),A_inv(1:3,4:6),pReal) + temp33_cmplx = cmplx(A_inv(1:3,1:3),A_inv(1:3,4:6),pReal) do concurrent(l=1:3, m=1:3, n=1:3, o=1:3) - gamma_hat(l,m,n,o,i,j,k-cells3Offset) = temp33_complex(l,n) * xiDyad_cmplx(o,m) + gamma_hat(l,m,n,o,i,j,k-cells3Offset) = temp33_cmplx(l,n) * xiDyad_cmplx(o,m) end do end if end if end do; end do; end do + !$OMP END PARALLEL DO endif end subroutine utilities_updateGamma @@ -477,7 +479,7 @@ end subroutine utilities_FFTvectorBackward subroutine utilities_fourierGammaConvolution(fieldAim) real(pReal), intent(in), dimension(3,3) :: fieldAim !< desired average value of the field after convolution - complex(pReal), dimension(3,3) :: temp33_complex, xiDyad_cmplx + complex(pReal), dimension(3,3) :: temp33_cmplx, xiDyad_cmplx real(pReal), dimension(6,6) :: A, A_inv integer :: & @@ -492,38 +494,42 @@ subroutine utilities_fourierGammaConvolution(fieldAim) !-------------------------------------------------------------------------------------------------- ! do the actual spectral method calculation (mechanical equilibrium) memoryEfficient: if (num%memory_efficient) then + !$OMP PARALLEL DO PRIVATE(l,m,n,o,temp33_cmplx,xiDyad_cmplx,A,A_inv,err,gamma_hat) do k = 1, cells3; do j = 1, cells(2); do i = 1, grid1Red if (any([i,j,k+cells3Offset] /= 1)) then ! singular point at xi=(0.0,0.0,0.0) i.e. i=j=k=1 do concurrent(l = 1:3, m = 1:3) xiDyad_cmplx(l,m) = conjg(-xi1st(l,i,j,k))*xi1st(m,i,j,k) end do do concurrent(l = 1:3, m = 1:3) - temp33_complex(l,m) = sum(cmplx(C_ref(l,1:3,m,1:3),0.0_pReal)*xiDyad_cmplx) + temp33_cmplx(l,m) = sum(cmplx(C_ref(l,1:3,m,1:3),0.0_pReal)*xiDyad_cmplx) end do - A(1:3,1:3) = temp33_complex%re; A(4:6,4:6) = temp33_complex%re - A(1:3,4:6) = temp33_complex%im; A(4:6,1:3) = -temp33_complex%im + A(1:3,1:3) = temp33_cmplx%re; A(4:6,4:6) = temp33_cmplx%re + A(1:3,4:6) = temp33_cmplx%im; A(4:6,1:3) = -temp33_cmplx%im if (abs(math_det33(A(1:3,1:3))) > 1e-16) then call math_invert(A_inv, err, A) - temp33_complex = cmplx(A_inv(1:3,1:3),A_inv(1:3,4:6),pReal) + temp33_cmplx = cmplx(A_inv(1:3,1:3),A_inv(1:3,4:6),pReal) do concurrent(l=1:3, m=1:3, n=1:3, o=1:3) - gamma_hat(l,m,n,o,1,1,1) = temp33_complex(l,n)*xiDyad_cmplx(o,m) + gamma_hat(l,m,n,o,1,1,1) = temp33_cmplx(l,n)*xiDyad_cmplx(o,m) end do do concurrent(l = 1:3, m = 1:3) - temp33_Complex(l,m) = sum(gamma_hat(l,m,1:3,1:3,1,1,1)*tensorField_fourier(1:3,1:3,i,j,k)) + temp33_cmplx(l,m) = sum(gamma_hat(l,m,1:3,1:3,1,1,1)*tensorField_fourier(1:3,1:3,i,j,k)) end do - tensorField_fourier(1:3,1:3,i,j,k) = temp33_Complex + tensorField_fourier(1:3,1:3,i,j,k) = temp33_cmplx else tensorField_fourier(1:3,1:3,i,j,k) = cmplx(0.0_pReal,0.0_pReal,pReal) end if end if end do; end do; end do + !$OMP END PARALLEL DO else memoryEfficient + !$OMP PARALLEL DO PRIVATE(l,m,temp33_cmplx) do k = 1, cells3; do j = 1, cells(2); do i = 1,grid1Red do concurrent(l = 1:3, m = 1:3) - temp33_Complex(l,m) = sum(gamma_hat(l,m,1:3,1:3,i,j,k)*tensorField_fourier(1:3,1:3,i,j,k)) + temp33_cmplx(l,m) = sum(gamma_hat(l,m,1:3,1:3,i,j,k)*tensorField_fourier(1:3,1:3,i,j,k)) end do - tensorField_fourier(1:3,1:3,i,j,k) = temp33_Complex + tensorField_fourier(1:3,1:3,i,j,k) = temp33_cmplx end do; end do; end do + !$OMP END PARALLEL DO end if memoryEfficient if (cells3Offset == 0) tensorField_fourier(1:3,1:3,1,1,1) = cmplx(fieldAim/wgt,0.0_pReal,pReal) @@ -543,12 +549,14 @@ subroutine utilities_fourierGreenConvolution(D_ref, mu_ref, Delta_t) !-------------------------------------------------------------------------------------------------- ! do the actual spectral method calculation + !$OMP PARALLEL DO PRIVATE(GreenOp_hat) do k = 1, cells3; do j = 1, cells(2) ;do i = 1, grid1Red GreenOp_hat = cmplx(1.0_pReal,0.0_pReal,pReal) & / (cmplx(mu_ref,0.0_pReal,pReal) + cmplx(Delta_t,0.0_pReal) & * sum(conjg(xi1st(1:3,i,j,k))* matmul(cmplx(D_ref,0.0_pReal),xi1st(1:3,i,j,k)))) scalarField_fourier(i,j,k) = scalarField_fourier(i,j,k)*GreenOp_hat enddo; enddo; enddo + !$OMP END PARALLEL DO end subroutine utilities_fourierGreenConvolution @@ -735,9 +743,10 @@ subroutine utilities_fourierScalarGradient() integer :: i, j, k + do k = 1, cells3; do j = 1, cells(2); do i = 1,grid1Red vectorField_fourier(1:3,i,j,k) = scalarField_fourier(i,j,k)*xi1st(1:3,i,j,k) ! ToDo: no -conjg? - enddo; enddo; enddo + end do; end do; end do end subroutine utilities_fourierScalarGradient @@ -747,11 +756,9 @@ end subroutine utilities_fourierScalarGradient !-------------------------------------------------------------------------------------------------- subroutine utilities_fourierVectorDivergence() - integer :: i, j, k - do k = 1, cells3; do j = 1, cells(2); do i = 1,grid1Red - scalarField_fourier(i,j,k) = sum(vectorField_fourier(1:3,i,j,k)*conjg(-xi1st(1:3,i,j,k))) - enddo; enddo; enddo + scalarField_fourier(1:grid1Red,1:cells(2),1:cells3) = sum(vectorField_fourier(1:3,1:grid1Red,1:cells(2),1:cells3) & + *conjg(-xi1st)) end subroutine utilities_fourierVectorDivergence @@ -763,11 +770,12 @@ subroutine utilities_fourierVectorGradient() integer :: i, j, k, m, n + do k = 1, cells3; do j = 1, cells(2); do i = 1,grid1Red do m = 1, 3; do n = 1, 3 tensorField_fourier(m,n,i,j,k) = vectorField_fourier(m,i,j,k)*xi1st(n,i,j,k) - enddo; enddo - enddo; enddo; enddo + end do; end do + end do; end do; end do end subroutine utilities_fourierVectorGradient @@ -779,9 +787,10 @@ subroutine utilities_fourierTensorDivergence() integer :: i, j, k + do k = 1, cells3; do j = 1, cells(2); do i = 1,grid1Red vectorField_fourier(:,i,j,k) = matmul(tensorField_fourier(:,:,i,j,k),conjg(-xi1st(:,i,j,k))) - enddo; enddo; enddo + end do; end do; end do end subroutine utilities_fourierTensorDivergence @@ -978,6 +987,7 @@ end function utilities_getFreqDerivative subroutine utilities_updateCoords(F) real(pReal), dimension(3,3,cells(1),cells(2),cells3), intent(in) :: F + real(pReal), dimension(3, cells(1),cells(2),cells3) :: IPcoords real(pReal), dimension(3, cells(1),cells(2),cells3+2) :: IPfluct_padded ! Fluctuations of cell center displacement (padded along z for MPI) real(pReal), dimension(3, cells(1)+1,cells(2)+1,cells3+1) :: nodeCoords @@ -1008,20 +1018,23 @@ subroutine utilities_updateCoords(F) 1, 1, 1, & 0, 1, 1 ], [3,8]) + step = geomSize/real(cells, pReal) !-------------------------------------------------------------------------------------------------- ! integration in Fourier space to get fluctuations of cell center discplacements tensorField_real(1:3,1:3,1:cells(1),1:cells(2),1:cells3) = F call utilities_FFTtensorForward() + !$OMP PARALLEL DO do k = 1, cells3; do j = 1, cells(2); do i = 1, grid1Red if (any([i,j,k+cells3Offset] /= 1)) then vectorField_fourier(1:3,i,j,k) = matmul(tensorField_fourier(1:3,1:3,i,j,k),xi2nd(1:3,i,j,k)) & / sum(conjg(-xi2nd(1:3,i,j,k))*xi2nd(1:3,i,j,k)) * cmplx(wgt,0.0,pReal) else vectorField_fourier(1:3,i,j,k) = cmplx(0.0,0.0,pReal) - endif - enddo; enddo; enddo + end if + end do; end do; end do + !$OMP END PARALLEL DO call fftw_mpi_execute_dft_c2r(planVectorBack,vectorField_fourier,vectorField_real) From 466682e9787453fa28dd47c3794c036913c0e2da Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 14 Feb 2022 08:32:48 +0100 Subject: [PATCH 63/72] missing rename grid -> cells --- src/grid/spectral_utilities.f90 | 62 ++++++++++++++++----------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/src/grid/spectral_utilities.f90 b/src/grid/spectral_utilities.f90 index 418f83b05..f89485c7a 100644 --- a/src/grid/spectral_utilities.f90 +++ b/src/grid/spectral_utilities.f90 @@ -31,7 +31,7 @@ module spectral_utilities !-------------------------------------------------------------------------------------------------- ! grid related information real(pReal), protected, public :: wgt !< weighting factor 1/Nelems - integer, protected, public :: grid1Red !< cells(1)/2 + integer, protected, public :: cells1Red !< cells(1)/2 real(pReal), protected, public, dimension(3) :: scaledGeomSize !< scaled geometry size for calculation of divergence !-------------------------------------------------------------------------------------------------- @@ -201,7 +201,7 @@ subroutine spectral_utilities_init num_grid%get_asString('PETSc_options',defaultVal=''),err_PETSc) CHKERRQ(err_PETSc) - grid1Red = cells(1)/2 + 1 + cells1Red = cells(1)/2 + 1 wgt = 1.0/real(product(cells),pReal) num%memory_efficient = num_grid%get_asInt('memory_efficient', defaultVal=1) > 0 ! ToDo: should be logical in YAML file @@ -265,8 +265,8 @@ subroutine spectral_utilities_init gridFFTW = int(cells,C_INTPTR_T) alloc_local = fftw_mpi_local_size_3d(gridFFTW(3), gridFFTW(2), gridFFTW(1)/2 +1, & PETSC_COMM_WORLD, local_K, local_K_offset) - allocate (xi1st (3,grid1Red,cells(2),cells3),source = cmplx(0.0_pReal,0.0_pReal,pReal)) ! frequencies for first derivatives, only half the size for first dimension - allocate (xi2nd (3,grid1Red,cells(2),cells3),source = cmplx(0.0_pReal,0.0_pReal,pReal)) ! frequencies for second derivatives, only half the size for first dimension + allocate (xi1st (3,cells1Red,cells(2),cells3),source = cmplx(0.0_pReal,0.0_pReal,pReal)) ! frequencies for first derivatives, only half the size for first dimension + allocate (xi2nd (3,cells1Red,cells(2),cells3),source = cmplx(0.0_pReal,0.0_pReal,pReal)) ! frequencies for second derivatives, only half the size for first dimension tensorField = fftw_alloc_complex(tensorSize*alloc_local) call c_f_pointer(tensorField, tensorField_real, [3_C_INTPTR_T,3_C_INTPTR_T, & @@ -333,7 +333,7 @@ subroutine spectral_utilities_init do j = 1, cells(2) k_s(2) = j - 1 if (j > cells(2)/2 + 1) k_s(2) = k_s(2) - cells(2) ! running from 0,1,...,N/2,N/2+1,-N/2,-N/2+1,...,-1 - do i = 1, grid1Red + do i = 1, cells1Red k_s(1) = i - 1 ! symmetry, junst running from 0,1,...,N/2,N/2+1 xi2nd(1:3,i,j,k-cells3Offset) = utilities_getFreqDerivative(k_s) where(mod(cells,2)==0 .and. [i,j,k] == cells/2+1 .and. & @@ -347,7 +347,7 @@ subroutine spectral_utilities_init if (num%memory_efficient) then ! allocate just single fourth order tensor allocate (gamma_hat(3,3,3,3,1,1,1), source = cmplx(0.0_pReal,0.0_pReal,pReal)) else ! precalculation of gamma_hat field - allocate (gamma_hat(3,3,3,3,grid1Red,cells(2),cells3), source = cmplx(0.0_pReal,0.0_pReal,pReal)) + allocate (gamma_hat(3,3,3,3,cells1Red,cells(2),cells3), source = cmplx(0.0_pReal,0.0_pReal,pReal)) endif end subroutine spectral_utilities_init @@ -374,7 +374,7 @@ subroutine utilities_updateGamma(C) if (.not. num%memory_efficient) then gamma_hat = cmplx(0.0_pReal,0.0_pReal,pReal) ! for the singular point and any non invertible A !$OMP PARALLEL DO PRIVATE(l,m,n,o,temp33_cmplx,xiDyad_cmplx,A,A_inv,err) - do k = cells3Offset+1, cells3Offset+cells3; do j = 1, cells(2); do i = 1, grid1Red + do k = cells3Offset+1, cells3Offset+cells3; do j = 1, cells(2); do i = 1, cells1Red if (any([i,j,k] /= 1)) then ! singular point at xi=(0.0,0.0,0.0) i.e. i=j=k=1 do concurrent (l = 1:3, m = 1:3) xiDyad_cmplx(l,m) = conjg(-xi1st(l,i,j,k-cells3Offset))*xi1st(m,i,j,k-cells3Offset) @@ -406,7 +406,7 @@ end subroutine utilities_updateGamma !-------------------------------------------------------------------------------------------------- subroutine utilities_FFTtensorForward - tensorField_real(1:3,1:3,cells(1)+1:grid1Red*2,:,:) = 0.0_pReal + tensorField_real(1:3,1:3,cells(1)+1:cells1Red*2,:,:) = 0.0_pReal call fftw_mpi_execute_dft_r2c(planTensorForth,tensorField_real,tensorField_fourier) end subroutine utilities_FFTtensorForward @@ -430,7 +430,7 @@ end subroutine utilities_FFTtensorBackward !-------------------------------------------------------------------------------------------------- subroutine utilities_FFTscalarForward - scalarField_real(cells(1)+1:grid1Red*2,:,:) = 0.0_pReal + scalarField_real(cells(1)+1:cells1Red*2,:,:) = 0.0_pReal call fftw_mpi_execute_dft_r2c(planScalarForth,scalarField_real,scalarField_fourier) end subroutine utilities_FFTscalarForward @@ -455,7 +455,7 @@ end subroutine utilities_FFTscalarBackward !-------------------------------------------------------------------------------------------------- subroutine utilities_FFTvectorForward - vectorField_real(1:3,cells(1)+1:grid1Red*2,:,:) = 0.0_pReal + vectorField_real(1:3,cells(1)+1:cells1Red*2,:,:) = 0.0_pReal call fftw_mpi_execute_dft_r2c(planVectorForth,vectorField_real,vectorField_fourier) end subroutine utilities_FFTvectorForward @@ -495,7 +495,7 @@ subroutine utilities_fourierGammaConvolution(fieldAim) ! do the actual spectral method calculation (mechanical equilibrium) memoryEfficient: if (num%memory_efficient) then !$OMP PARALLEL DO PRIVATE(l,m,n,o,temp33_cmplx,xiDyad_cmplx,A,A_inv,err,gamma_hat) - do k = 1, cells3; do j = 1, cells(2); do i = 1, grid1Red + do k = 1, cells3; do j = 1, cells(2); do i = 1, cells1Red if (any([i,j,k+cells3Offset] /= 1)) then ! singular point at xi=(0.0,0.0,0.0) i.e. i=j=k=1 do concurrent(l = 1:3, m = 1:3) xiDyad_cmplx(l,m) = conjg(-xi1st(l,i,j,k))*xi1st(m,i,j,k) @@ -523,7 +523,7 @@ subroutine utilities_fourierGammaConvolution(fieldAim) !$OMP END PARALLEL DO else memoryEfficient !$OMP PARALLEL DO PRIVATE(l,m,temp33_cmplx) - do k = 1, cells3; do j = 1, cells(2); do i = 1,grid1Red + do k = 1, cells3; do j = 1, cells(2); do i = 1,cells1Red do concurrent(l = 1:3, m = 1:3) temp33_cmplx(l,m) = sum(gamma_hat(l,m,1:3,1:3,i,j,k)*tensorField_fourier(1:3,1:3,i,j,k)) end do @@ -550,7 +550,7 @@ subroutine utilities_fourierGreenConvolution(D_ref, mu_ref, Delta_t) !-------------------------------------------------------------------------------------------------- ! do the actual spectral method calculation !$OMP PARALLEL DO PRIVATE(GreenOp_hat) - do k = 1, cells3; do j = 1, cells(2) ;do i = 1, grid1Red + do k = 1, cells3; do j = 1, cells(2) ;do i = 1, cells1Red GreenOp_hat = cmplx(1.0_pReal,0.0_pReal,pReal) & / (cmplx(mu_ref,0.0_pReal,pReal) + cmplx(Delta_t,0.0_pReal) & * sum(conjg(xi1st(1:3,i,j,k))* matmul(cmplx(D_ref,0.0_pReal),xi1st(1:3,i,j,k)))) @@ -579,7 +579,7 @@ real(pReal) function utilities_divergenceRMS() ! calculating RMS divergence criterion in Fourier space utilities_divergenceRMS = 0.0_pReal do k = 1, cells3; do j = 1, cells(2) - do i = 2, grid1Red -1 ! Has somewhere a conj. complex counterpart. Therefore count it twice. + do i = 2, cells1Red -1 ! Has somewhere a conj. complex counterpart. Therefore count it twice. utilities_divergenceRMS = utilities_divergenceRMS & + 2.0_pReal*(sum (real(matmul(tensorField_fourier(1:3,1:3,i,j,k), & ! (sqrt(real(a)**2 + aimag(a)**2))**2 = real(a)**2 + aimag(a)**2, i.e. do not take square root and square again conjg(-xi1st(1:3,i,j,k))*rescaledGeom))**2) & ! --> sum squared L_2 norm of vector @@ -591,10 +591,10 @@ real(pReal) function utilities_divergenceRMS() conjg(-xi1st(1:3,1,j,k))*rescaledGeom))**2) & + sum(aimag(matmul(tensorField_fourier(1:3,1:3,1 ,j,k), & conjg(-xi1st(1:3,1,j,k))*rescaledGeom))**2) & - + sum( real(matmul(tensorField_fourier(1:3,1:3,grid1Red,j,k), & - conjg(-xi1st(1:3,grid1Red,j,k))*rescaledGeom))**2) & - + sum(aimag(matmul(tensorField_fourier(1:3,1:3,grid1Red,j,k), & - conjg(-xi1st(1:3,grid1Red,j,k))*rescaledGeom))**2) + + sum( real(matmul(tensorField_fourier(1:3,1:3,cells1Red,j,k), & + conjg(-xi1st(1:3,cells1Red,j,k))*rescaledGeom))**2) & + + sum(aimag(matmul(tensorField_fourier(1:3,1:3,cells1Red,j,k), & + conjg(-xi1st(1:3,cells1Red,j,k))*rescaledGeom))**2) enddo; enddo if (cells(1) == 1) utilities_divergenceRMS = utilities_divergenceRMS * 0.5_pReal ! counted twice in case of cells(1) == 1 call MPI_Allreduce(MPI_IN_PLACE,utilities_divergenceRMS,1_MPI_INTEGER_KIND,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD,err_MPI) @@ -624,7 +624,7 @@ real(pReal) function utilities_curlRMS() utilities_curlRMS = 0.0_pReal do k = 1, cells3; do j = 1, cells(2); - do i = 2, grid1Red - 1 + do i = 2, cells1Red - 1 do l = 1, 3 curl_fourier(l,1) = (+tensorField_fourier(l,3,i,j,k)*xi1st(2,i,j,k)*rescaledGeom(2) & -tensorField_fourier(l,2,i,j,k)*xi1st(3,i,j,k)*rescaledGeom(3)) @@ -647,12 +647,12 @@ real(pReal) function utilities_curlRMS() utilities_curlRMS = utilities_curlRMS & + sum(curl_fourier%re**2 + curl_fourier%im**2) ! this layer (DC) does not have a conjugate complex counterpart (if cells(1) /= 1) do l = 1, 3 - curl_fourier = (+tensorField_fourier(l,3,grid1Red,j,k)*xi1st(2,grid1Red,j,k)*rescaledGeom(2) & - -tensorField_fourier(l,2,grid1Red,j,k)*xi1st(3,grid1Red,j,k)*rescaledGeom(3)) - curl_fourier = (+tensorField_fourier(l,1,grid1Red,j,k)*xi1st(3,grid1Red,j,k)*rescaledGeom(3) & - -tensorField_fourier(l,3,grid1Red,j,k)*xi1st(1,grid1Red,j,k)*rescaledGeom(1)) - curl_fourier = (+tensorField_fourier(l,2,grid1Red,j,k)*xi1st(1,grid1Red,j,k)*rescaledGeom(1) & - -tensorField_fourier(l,1,grid1Red,j,k)*xi1st(2,grid1Red,j,k)*rescaledGeom(2)) + curl_fourier = (+tensorField_fourier(l,3,cells1Red,j,k)*xi1st(2,cells1Red,j,k)*rescaledGeom(2) & + -tensorField_fourier(l,2,cells1Red,j,k)*xi1st(3,cells1Red,j,k)*rescaledGeom(3)) + curl_fourier = (+tensorField_fourier(l,1,cells1Red,j,k)*xi1st(3,cells1Red,j,k)*rescaledGeom(3) & + -tensorField_fourier(l,3,cells1Red,j,k)*xi1st(1,cells1Red,j,k)*rescaledGeom(1)) + curl_fourier = (+tensorField_fourier(l,2,cells1Red,j,k)*xi1st(1,cells1Red,j,k)*rescaledGeom(1) & + -tensorField_fourier(l,1,cells1Red,j,k)*xi1st(2,cells1Red,j,k)*rescaledGeom(2)) enddo utilities_curlRMS = utilities_curlRMS & + sum(curl_fourier%re**2 + curl_fourier%im**2) ! this layer (Nyquist) does not have a conjugate complex counterpart (if cells(1) /= 1) @@ -744,7 +744,7 @@ subroutine utilities_fourierScalarGradient() integer :: i, j, k - do k = 1, cells3; do j = 1, cells(2); do i = 1,grid1Red + do k = 1, cells3; do j = 1, cells(2); do i = 1,cells1Red vectorField_fourier(1:3,i,j,k) = scalarField_fourier(i,j,k)*xi1st(1:3,i,j,k) ! ToDo: no -conjg? end do; end do; end do @@ -757,8 +757,8 @@ end subroutine utilities_fourierScalarGradient subroutine utilities_fourierVectorDivergence() - scalarField_fourier(1:grid1Red,1:cells(2),1:cells3) = sum(vectorField_fourier(1:3,1:grid1Red,1:cells(2),1:cells3) & - *conjg(-xi1st)) + scalarField_fourier(1:cells1Red,1:cells(2),1:cells3) = sum(vectorField_fourier(1:3,1:cells1Red,1:cells(2),1:cells3) & + *conjg(-xi1st)) end subroutine utilities_fourierVectorDivergence @@ -771,7 +771,7 @@ subroutine utilities_fourierVectorGradient() integer :: i, j, k, m, n - do k = 1, cells3; do j = 1, cells(2); do i = 1,grid1Red + do k = 1, cells3; do j = 1, cells(2); do i = 1,cells1Red do m = 1, 3; do n = 1, 3 tensorField_fourier(m,n,i,j,k) = vectorField_fourier(m,i,j,k)*xi1st(n,i,j,k) end do; end do @@ -788,7 +788,7 @@ subroutine utilities_fourierTensorDivergence() integer :: i, j, k - do k = 1, cells3; do j = 1, cells(2); do i = 1,grid1Red + do k = 1, cells3; do j = 1, cells(2); do i = 1,cells1Red vectorField_fourier(:,i,j,k) = matmul(tensorField_fourier(:,:,i,j,k),conjg(-xi1st(:,i,j,k))) end do; end do; end do @@ -1026,7 +1026,7 @@ subroutine utilities_updateCoords(F) call utilities_FFTtensorForward() !$OMP PARALLEL DO - do k = 1, cells3; do j = 1, cells(2); do i = 1, grid1Red + do k = 1, cells3; do j = 1, cells(2); do i = 1, cells1Red if (any([i,j,k+cells3Offset] /= 1)) then vectorField_fourier(1:3,i,j,k) = matmul(tensorField_fourier(1:3,1:3,i,j,k),xi2nd(1:3,i,j,k)) & / sum(conjg(-xi2nd(1:3,i,j,k))*xi2nd(1:3,i,j,k)) * cmplx(wgt,0.0,pReal) From 1d5abc206aa630596ca82b6d6349865bc018a3f3 Mon Sep 17 00:00:00 2001 From: Test User Date: Mon, 14 Feb 2022 11:23:42 +0100 Subject: [PATCH 64/72] [skip ci] updated version information after successful test of v3.0.0-alpha5-638-g1ecbeb692 --- python/damask/VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/damask/VERSION b/python/damask/VERSION index 90c1162f3..5041b8cde 100644 --- a/python/damask/VERSION +++ b/python/damask/VERSION @@ -1 +1 @@ -v3.0.0-alpha5-624-g26979da58 +v3.0.0-alpha5-638-g1ecbeb692 From c66e2336c25d704a36a60ea121c837c34210a388 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 14 Feb 2022 08:58:40 +0100 Subject: [PATCH 65/72] some versions of ifort have problems with 'do concurrent' --- src/grid/spectral_utilities.f90 | 35 ++++++++++++++++++++++++++++++-- src/math.f90 | 31 ++++++++-------------------- src/phase_mechanical_plastic.f90 | 3 +-- 3 files changed, 42 insertions(+), 27 deletions(-) diff --git a/src/grid/spectral_utilities.f90 b/src/grid/spectral_utilities.f90 index f89485c7a..2a675c9b6 100644 --- a/src/grid/spectral_utilities.f90 +++ b/src/grid/spectral_utilities.f90 @@ -376,20 +376,32 @@ subroutine utilities_updateGamma(C) !$OMP PARALLEL DO PRIVATE(l,m,n,o,temp33_cmplx,xiDyad_cmplx,A,A_inv,err) do k = cells3Offset+1, cells3Offset+cells3; do j = 1, cells(2); do i = 1, cells1Red if (any([i,j,k] /= 1)) then ! singular point at xi=(0.0,0.0,0.0) i.e. i=j=k=1 - do concurrent (l = 1:3, m = 1:3) +#ifndef __INTEL_COMPILER + do concurrent(l = 1:3, m = 1:3) xiDyad_cmplx(l,m) = conjg(-xi1st(l,i,j,k-cells3Offset))*xi1st(m,i,j,k-cells3Offset) end do do concurrent(l = 1:3, m = 1:3) temp33_cmplx(l,m) = sum(cmplx(C_ref(l,1:3,m,1:3),0.0_pReal)*xiDyad_cmplx) end do +#else + forall(l = 1:3, m = 1:3) & + xiDyad_cmplx(l,m) = conjg(-xi1st(l,i,j,k-cells3Offset))*xi1st(m,i,j,k-cells3Offset) + forall(l = 1:3, m = 1:3) & + temp33_cmplx(l,m) = sum(cmplx(C_ref(l,1:3,m,1:3),0.0_pReal)*xiDyad_cmplx) +#endif A(1:3,1:3) = temp33_cmplx%re; A(4:6,4:6) = temp33_cmplx%re A(1:3,4:6) = temp33_cmplx%im; A(4:6,1:3) = -temp33_cmplx%im if (abs(math_det33(A(1:3,1:3))) > 1e-16) then call math_invert(A_inv, err, A) temp33_cmplx = cmplx(A_inv(1:3,1:3),A_inv(1:3,4:6),pReal) +#ifndef __INTEL_COMPILER do concurrent(l=1:3, m=1:3, n=1:3, o=1:3) gamma_hat(l,m,n,o,i,j,k-cells3Offset) = temp33_cmplx(l,n) * xiDyad_cmplx(o,m) end do +#else + forall(l=1:3, m=1:3, n=1:3, o=1:3) & + gamma_hat(l,m,n,o,i,j,k-cells3Offset) = temp33_cmplx(l,n) * xiDyad_cmplx(o,m) +#endif end if end if end do; end do; end do @@ -497,23 +509,37 @@ subroutine utilities_fourierGammaConvolution(fieldAim) !$OMP PARALLEL DO PRIVATE(l,m,n,o,temp33_cmplx,xiDyad_cmplx,A,A_inv,err,gamma_hat) do k = 1, cells3; do j = 1, cells(2); do i = 1, cells1Red if (any([i,j,k+cells3Offset] /= 1)) then ! singular point at xi=(0.0,0.0,0.0) i.e. i=j=k=1 +#ifndef __INTEL_COMPILER do concurrent(l = 1:3, m = 1:3) xiDyad_cmplx(l,m) = conjg(-xi1st(l,i,j,k))*xi1st(m,i,j,k) end do do concurrent(l = 1:3, m = 1:3) temp33_cmplx(l,m) = sum(cmplx(C_ref(l,1:3,m,1:3),0.0_pReal)*xiDyad_cmplx) end do +#else + forall(l = 1:3, m = 1:3) & + xiDyad_cmplx(l,m) = conjg(-xi1st(l,i,j,k))*xi1st(m,i,j,k) + forall(l = 1:3, m = 1:3) & + temp33_cmplx(l,m) = sum(cmplx(C_ref(l,1:3,m,1:3),0.0_pReal)*xiDyad_cmplx) +#endif A(1:3,1:3) = temp33_cmplx%re; A(4:6,4:6) = temp33_cmplx%re A(1:3,4:6) = temp33_cmplx%im; A(4:6,1:3) = -temp33_cmplx%im if (abs(math_det33(A(1:3,1:3))) > 1e-16) then call math_invert(A_inv, err, A) temp33_cmplx = cmplx(A_inv(1:3,1:3),A_inv(1:3,4:6),pReal) +#ifndef __INTEL_COMPILER do concurrent(l=1:3, m=1:3, n=1:3, o=1:3) gamma_hat(l,m,n,o,1,1,1) = temp33_cmplx(l,n)*xiDyad_cmplx(o,m) end do do concurrent(l = 1:3, m = 1:3) temp33_cmplx(l,m) = sum(gamma_hat(l,m,1:3,1:3,1,1,1)*tensorField_fourier(1:3,1:3,i,j,k)) end do +#else + forall(l=1:3, m=1:3, n=1:3, o=1:3) & + gamma_hat(l,m,n,o,1,1,1) = temp33_cmplx(l,n)*xiDyad_cmplx(o,m) + forall(l = 1:3, m = 1:3) & + temp33_cmplx(l,m) = sum(gamma_hat(l,m,1:3,1:3,1,1,1)*tensorField_fourier(1:3,1:3,i,j,k)) +#endif tensorField_fourier(1:3,1:3,i,j,k) = temp33_cmplx else tensorField_fourier(1:3,1:3,i,j,k) = cmplx(0.0_pReal,0.0_pReal,pReal) @@ -524,9 +550,14 @@ subroutine utilities_fourierGammaConvolution(fieldAim) else memoryEfficient !$OMP PARALLEL DO PRIVATE(l,m,temp33_cmplx) do k = 1, cells3; do j = 1, cells(2); do i = 1,cells1Red +#ifndef __INTEL_COMPILER do concurrent(l = 1:3, m = 1:3) temp33_cmplx(l,m) = sum(gamma_hat(l,m,1:3,1:3,i,j,k)*tensorField_fourier(1:3,1:3,i,j,k)) end do +#else + forall(l = 1:3, m = 1:3) & + temp33_cmplx(l,m) = sum(gamma_hat(l,m,1:3,1:3,i,j,k)*tensorField_fourier(1:3,1:3,i,j,k)) +#endif tensorField_fourier(1:3,1:3,i,j,k) = temp33_cmplx end do; end do; end do !$OMP END PARALLEL DO @@ -758,7 +789,7 @@ subroutine utilities_fourierVectorDivergence() scalarField_fourier(1:cells1Red,1:cells(2),1:cells3) = sum(vectorField_fourier(1:3,1:cells1Red,1:cells(2),1:cells3) & - *conjg(-xi1st)) + *conjg(-xi1st),1) end subroutine utilities_fourierVectorDivergence diff --git a/src/math.f90 b/src/math.f90 index dd4690672..75b9ddea2 100644 --- a/src/math.f90 +++ b/src/math.f90 @@ -262,9 +262,8 @@ pure function math_identity4th() math_identity4th(i,j,k,l) = 0.5_pReal*(math_I3(i,k)*math_I3(j,l)+math_I3(i,l)*math_I3(j,k)) enddo #else - do i=1,3; do j=1,3; do k=1,3; do l=1,3 + forall(i=1:3, j=1:3, k=1:3, l=1:3) & math_identity4th(i,j,k,l) = 0.5_pReal*(math_I3(i,k)*math_I3(j,l)+math_I3(i,l)*math_I3(j,k)) - enddo; enddo; enddo; enddo #endif end function math_identity4th @@ -338,9 +337,7 @@ pure function math_outer(A,B) math_outer(i,j) = A(i)*B(j) enddo #else - do i=1,size(A,1); do j=1,size(B,1) - math_outer(i,j) = A(i)*B(j) - enddo; enddo + forall(i=1:size(A,1), j=1:size(B,1)) math_outer(i,j) = A(i)*B(j) #endif end function math_outer @@ -387,9 +384,7 @@ pure function math_mul3333xx33(A,B) math_mul3333xx33(i,j) = sum(A(i,j,1:3,1:3)*B(1:3,1:3)) enddo #else - do i=1,3; do j=1,3 - math_mul3333xx33(i,j) = sum(A(i,j,1:3,1:3)*B(1:3,1:3)) - enddo; enddo + forall (i=1:3, j=1:3) math_mul3333xx33(i,j) = sum(A(i,j,1:3,1:3)*B(1:3,1:3)) #endif end function math_mul3333xx33 @@ -411,9 +406,7 @@ pure function math_mul3333xx3333(A,B) math_mul3333xx3333(i,j,k,l) = sum(A(i,j,1:3,1:3)*B(1:3,1:3,k,l)) enddo #else - do i=1,3; do j=1,3; do k=1,3; do l=1,3 - math_mul3333xx3333(i,j,k,l) = sum(A(i,j,1:3,1:3)*B(1:3,1:3,k,l)) - enddo; enddo; enddo; enddo + forall(i=1:3, j=1:3, k=1:3, l=1:3) math_mul3333xx3333(i,j,k,l) = sum(A(i,j,1:3,1:3)*B(1:3,1:3,k,l)) #endif end function math_mul3333xx3333 @@ -752,9 +745,7 @@ pure function math_3333to99(m3333) math_3333to99(i,j) = m3333(MAPPLAIN(1,i),MAPPLAIN(2,i),MAPPLAIN(1,j),MAPPLAIN(2,j)) enddo #else - do i=1,9; do j=1,9 - math_3333to99(i,j) = m3333(MAPPLAIN(1,i),MAPPLAIN(2,i),MAPPLAIN(1,j),MAPPLAIN(2,j)) - enddo; enddo + forall(i=1:9, j=1:9) math_3333to99(i,j) = m3333(MAPPLAIN(1,i),MAPPLAIN(2,i),MAPPLAIN(1,j),MAPPLAIN(2,j)) #endif end function math_3333to99 @@ -775,9 +766,7 @@ pure function math_99to3333(m99) math_99to3333(MAPPLAIN(1,i),MAPPLAIN(2,i),MAPPLAIN(1,j),MAPPLAIN(2,j)) = m99(i,j) enddo #else - do i=1,9; do j=1,9 - math_99to3333(MAPPLAIN(1,i),MAPPLAIN(2,i),MAPPLAIN(1,j),MAPPLAIN(2,j)) = m99(i,j) - enddo; enddo + forall(i=1:9, j=1:9) math_99to3333(MAPPLAIN(1,i),MAPPLAIN(2,i),MAPPLAIN(1,j),MAPPLAIN(2,j)) = m99(i,j) #endif end function math_99to3333 @@ -810,9 +799,7 @@ pure function math_sym3333to66(m3333,weighted) math_sym3333to66(i,j) = w(i)*w(j)*m3333(MAPNYE(1,i),MAPNYE(2,i),MAPNYE(1,j),MAPNYE(2,j)) enddo #else - do i=1,6; do j=1,6 - math_sym3333to66(i,j) = w(i)*w(j)*m3333(MAPNYE(1,i),MAPNYE(2,i),MAPNYE(1,j),MAPNYE(2,j)) - enddo; enddo + forall(i=1:6, j=1:6) math_sym3333to66(i,j) = w(i)*w(j)*m3333(MAPNYE(1,i),MAPNYE(2,i),MAPNYE(1,j),MAPNYE(2,j)) #endif end function math_sym3333to66 @@ -950,9 +937,7 @@ pure function math_3333toVoigt66_stiffness(C) result(C_tilde) C_tilde(i,j) = C(MAPVOIGT(1,i),MAPVOIGT(2,i),MAPVOIGT(1,j),MAPVOIGT(2,j)) end do #else - do i=1,6; do j=1,6 - C_tilde(i,j) = C(MAPVOIGT(1,i),MAPVOIGT(2,i),MAPVOIGT(1,j),MAPVOIGT(2,j)) - end do; end do + forall(i=1:6, j=1:6) C_tilde(i,j) = C(MAPVOIGT(1,i),MAPVOIGT(2,i),MAPVOIGT(1,j),MAPVOIGT(2,j)) #endif end function math_3333toVoigt66_stiffness diff --git a/src/phase_mechanical_plastic.f90 b/src/phase_mechanical_plastic.f90 index 72b67ef64..3915c3b2d 100644 --- a/src/phase_mechanical_plastic.f90 +++ b/src/phase_mechanical_plastic.f90 @@ -379,10 +379,9 @@ module function plastic_deltaState(ph, en) result(broken) en logical :: broken - real(pReal), dimension(3,3) :: & + real(pReal), dimension(3,3) :: & Mp integer :: & - myOffset, & mySize From 7d015fbdc518a2a4081054b4ad0a44495ca63d2a Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 14 Feb 2022 14:32:02 +0000 Subject: [PATCH 66/72] avoid confusion with existing table entry --- python/damask/_configmaterial.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python/damask/_configmaterial.py b/python/damask/_configmaterial.py index 250b52e7e..725567b7f 100644 --- a/python/damask/_configmaterial.py +++ b/python/damask/_configmaterial.py @@ -212,18 +212,18 @@ class ConfigMaterial(Config): homogenization: {} phase: {} - >>> cm.from_table(t,O='qu',phase='phase',homogenization='SX') + >>> cm.from_table(t,O='qu',phase='phase',homogenization='single_crystal') material: - constituents: - O: [0.19, 0.8, 0.24, -0.51] v: 1.0 phase: Aluminum - homogenization: SX + homogenization: single_crystal - constituents: - O: [0.8, 0.19, 0.24, -0.51] v: 1.0 phase: Steel - homogenization: SX + homogenization: single_crystal homogenization: {} phase: {} From bdeb3e042ea09bd1723d74ceb6fb619782acbfda Mon Sep 17 00:00:00 2001 From: Test User Date: Tue, 15 Feb 2022 01:20:38 +0100 Subject: [PATCH 67/72] [skip ci] updated version information after successful test of v3.0.0-alpha5-642-ge38786515 --- python/damask/VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/damask/VERSION b/python/damask/VERSION index 5041b8cde..c1421b337 100644 --- a/python/damask/VERSION +++ b/python/damask/VERSION @@ -1 +1 @@ -v3.0.0-alpha5-638-g1ecbeb692 +v3.0.0-alpha5-642-ge38786515 From 00f44c9ed6b9ff79b1b4b45d88e780cefd01deeb Mon Sep 17 00:00:00 2001 From: Test User Date: Tue, 15 Feb 2022 17:06:48 +0100 Subject: [PATCH 68/72] [skip ci] updated version information after successful test of v3.0.0-alpha5-651-gd4f711416 --- python/damask/VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/damask/VERSION b/python/damask/VERSION index c1421b337..6de98cde2 100644 --- a/python/damask/VERSION +++ b/python/damask/VERSION @@ -1 +1 @@ -v3.0.0-alpha5-642-ge38786515 +v3.0.0-alpha5-651-gd4f711416 From 35caed305fce4f0c049a01370ad29d0a8ae8d0ca Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 15 Feb 2022 22:08:12 +0100 Subject: [PATCH 69/72] consistently define allclose for own type only --- python/damask/_orientation.py | 10 ++++------ python/damask/_rotation.py | 8 ++++---- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/python/damask/_orientation.py b/python/damask/_orientation.py index c3afd0bed..c7fbbbb85 100644 --- a/python/damask/_orientation.py +++ b/python/damask/_orientation.py @@ -168,8 +168,8 @@ class Orientation(Rotation,Crystal): return np.logical_not(self==other) if isinstance(other, Orientation) else NotImplemented - def isclose(self, - other: object, + def isclose(self: MyType, + other: MyType, rtol: float = 1e-5, atol: float = 1e-8, equal_nan: bool = True) -> bool: @@ -193,8 +193,6 @@ class Orientation(Rotation,Crystal): Mask indicating where corresponding orientations are close. """ - if not isinstance(other, Orientation): - raise TypeError matching_type = self.family == other.family and \ self.lattice == other.lattice and \ self.parameters == other.parameters @@ -202,8 +200,8 @@ class Orientation(Rotation,Crystal): - def allclose(self, - other: object, + def allclose(self: MyType, + other: MyType, rtol: float = 1e-5, atol: float = 1e-8, equal_nan: bool = True) -> bool: diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index b11147482..9c6bde2dc 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -140,8 +140,8 @@ class Rotation: """ return np.logical_not(self==other) if isinstance(other, Rotation) else NotImplemented - def isclose(self, - other: 'Rotation', + def isclose(self: MyType, + other: MyType, rtol: float = 1e-5, atol: float = 1e-8, equal_nan: bool = True) -> bool: @@ -171,8 +171,8 @@ class Rotation: np.all(np.isclose(s,-1.0*o,rtol,atol,equal_nan),axis=-1)) - def allclose(self, - other: 'Rotation', + def allclose(self: MyType, + other: MyType, rtol: float = 1e-5, atol: float = 1e-8, equal_nan: bool = True) -> Union[np.bool_, bool]: From 96133c68e90741f7e962aad8b9fb19dfa983bfcd Mon Sep 17 00:00:00 2001 From: Philip Eisenlohr Date: Tue, 15 Feb 2022 22:53:08 +0000 Subject: [PATCH 70/72] Corrected documentation for Table.set/add/sort_by --- python/damask/_table.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/python/damask/_table.py b/python/damask/_table.py index 81c23e73b..df364d46e 100644 --- a/python/damask/_table.py +++ b/python/damask/_table.py @@ -372,9 +372,9 @@ class Table: label : str Column label. data : numpy.ndarray - New data. + Replacement data. info : str, optional - Human-readable information about the new data. + Human-readable information about the modified data. Returns ------- @@ -407,9 +407,9 @@ class Table: label : str Column label. data : numpy.ndarray - Modified data. + New data. info : str, optional - Human-readable information about the modified data. + Human-readable information about the new data. Returns ------- @@ -485,7 +485,7 @@ class Table: labels: Union[str, List[str]], ascending: Union[bool, List[bool]] = True) -> 'Table': """ - Sort table by values of given labels. + Sort table by data of given columns. Parameters ---------- From 0f579e44ab1ad31a77cbb1929fe0720e63c9768a Mon Sep 17 00:00:00 2001 From: Test User Date: Wed, 16 Feb 2022 07:51:02 +0100 Subject: [PATCH 71/72] [skip ci] updated version information after successful test of v3.0.0-alpha5-691-gfe0ff7cab --- python/damask/VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/damask/VERSION b/python/damask/VERSION index 6de98cde2..d0eea3ce8 100644 --- a/python/damask/VERSION +++ b/python/damask/VERSION @@ -1 +1 @@ -v3.0.0-alpha5-651-gd4f711416 +v3.0.0-alpha5-691-gfe0ff7cab From 138b0e03f2b98151e4a3e933e0e7201c15ebe01e Mon Sep 17 00:00:00 2001 From: Test User Date: Wed, 16 Feb 2022 19:11:10 +0100 Subject: [PATCH 72/72] [skip ci] updated version information after successful test of v3.0.0-alpha5-696-g6fce27dee --- python/damask/VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/damask/VERSION b/python/damask/VERSION index d0eea3ce8..a275a6f55 100644 --- a/python/damask/VERSION +++ b/python/damask/VERSION @@ -1 +1 @@ -v3.0.0-alpha5-691-gfe0ff7cab +v3.0.0-alpha5-696-g6fce27dee