From 78a2941436dfcb0be765a9cca4a0d134882db58b Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 21 Oct 2019 16:59:49 +0200 Subject: [PATCH 01/78] avoid numerical issues --- python/damask/orientation.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/python/damask/orientation.py b/python/damask/orientation.py index 85a5c1866..688a3fa3f 100644 --- a/python/damask/orientation.py +++ b/python/damask/orientation.py @@ -702,14 +702,14 @@ class Symmetry: v = np.array(vector,dtype=float) if proper: # check both improper ... theComponents = np.dot(basis['improper'],v) - inSST = np.all(theComponents >= 0.0) + inSST = np.all(np.around(theComponents,12) >= 0.0) if not inSST: # ... and proper SST - theComponents = np.dot(basis['proper'],v) - inSST = np.all(theComponents >= 0.0) + theComponents = np.dot(basis['proper'],v) + inSST = np.all(np.around(theComponents,12) >= 0.0) else: v[2] = abs(v[2]) # z component projects identical theComponents = np.dot(basis['improper'],v) # for positive and negative values - inSST = np.all(theComponents >= 0.0) + inSST = np.all(np.around(theComponents,12) >= 0.0) if color: # have to return color array if inSST: From ecc51e34d3bf19d838f51079fda39270f826ae13 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 21 Oct 2019 22:44:12 +0200 Subject: [PATCH 02/78] rouding should affect color calculation avoid NaN in math.power(x,0.5). math.power(-0.0,0.5) is ok --- python/damask/orientation.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/python/damask/orientation.py b/python/damask/orientation.py index 688a3fa3f..dc851b35c 100644 --- a/python/damask/orientation.py +++ b/python/damask/orientation.py @@ -701,15 +701,15 @@ class Symmetry: v = np.array(vector,dtype=float) if proper: # check both improper ... - theComponents = np.dot(basis['improper'],v) - inSST = np.all(np.around(theComponents,12) >= 0.0) + theComponents = np.around(np.dot(basis['improper'],v),12) + inSST = np.all(theComponents >= 0.0) if not inSST: # ... and proper SST - theComponents = np.dot(basis['proper'],v) - inSST = np.all(np.around(theComponents,12) >= 0.0) + theComponents = np.around(np.dot(basis['proper'],v),12) + inSST = np.all(theComponents >= 0.0) else: v[2] = abs(v[2]) # z component projects identical - theComponents = np.dot(basis['improper'],v) # for positive and negative values - inSST = np.all(np.around(theComponents,12) >= 0.0) + theComponents = np.around(np.dot(basis['improper'],v),12) # for positive and negative values + inSST = np.all(theComponents >= 0.0) if color: # have to return color array if inSST: From 9489c04ccbfe3ec88e6502c14d1e4bb025a388d1 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 21 Oct 2019 23:02:31 +0200 Subject: [PATCH 03/78] less confusing --- python/damask/orientation.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python/damask/orientation.py b/python/damask/orientation.py index dc851b35c..97464f9e6 100644 --- a/python/damask/orientation.py +++ b/python/damask/orientation.py @@ -1046,13 +1046,13 @@ class Lattice: for miller in np.hstack((relationship['planes'],relationship['directions'])): myPlane = miller[myPlane_id]/ np.linalg.norm(miller[myPlane_id]) myDir = miller[myDir_id]/ np.linalg.norm(miller[myDir_id]) - myMatrix = np.array([myDir,np.cross(myPlane,myDir),myPlane]).T + myMatrix = np.array([myDir,np.cross(myPlane,myDir),myPlane]) otherPlane = miller[otherPlane_id]/ np.linalg.norm(miller[otherPlane_id]) otherDir = miller[otherDir_id]/ np.linalg.norm(miller[otherDir_id]) - otherMatrix = np.array([otherDir,np.cross(otherPlane,otherDir),otherPlane]).T + otherMatrix = np.array([otherDir,np.cross(otherPlane,otherDir),otherPlane]) - r['rotations'].append(Rotation.fromMatrix(np.dot(otherMatrix,myMatrix.T))) + r['rotations'].append(Rotation.fromMatrix(np.dot(otherMatrix.T,myMatrix))) return r From 5e7f9a223b55f9f8c56ba6fa35a0c46ae5db5b68 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 21 Oct 2019 23:17:58 +0200 Subject: [PATCH 04/78] should be a passive rotation --- 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 97464f9e6..fc601b608 100644 --- a/python/damask/orientation.py +++ b/python/damask/orientation.py @@ -1144,7 +1144,7 @@ class Orientation: def relatedOrientations(self,model): """List of orientations related by the given orientation relationship.""" r = self.lattice.relationOperations(model) - return [self.__class__(self.rotation*o,r['lattice']) for o in r['rotations']] + return [self.__class__(o*self.rotation,r['lattice']) for o in r['rotations']] def reduced(self): """Transform orientation to fall into fundamental zone according to symmetry.""" From 9b4252da68628d6f3bf5644882cdee51bf35087c Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 29 Nov 2019 16:53:40 +0100 Subject: [PATCH 05/78] smart handling of leading zeros --- processing/post/DADF5_postResults.py | 5 ++++- processing/post/DADF5_vtk_cells.py | 6 ++++-- processing/post/DADF5_vtk_points.py | 5 ++++- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/processing/post/DADF5_postResults.py b/processing/post/DADF5_postResults.py index a16ef147c..ab68fc76b 100755 --- a/processing/post/DADF5_postResults.py +++ b/processing/post/DADF5_postResults.py @@ -47,6 +47,8 @@ for filename in options.filenames: coords = np.concatenate((z[:,:,:,None],y[:,:,:,None],x[:,:,:,None]),axis = 3) + N_digits = int(np.floor(np.log10(int(results.increments[-1][3:]))))+1 + N_digits = 5 # hack to keep test intact for i,inc in enumerate(results.iter_visible('increments')): print('Output step {}/{}'.format(i+1,len(results.increments))) @@ -92,5 +94,6 @@ for filename in options.filenames: dirname = os.path.abspath(os.path.join(os.path.dirname(filename),options.dir)) if not os.path.isdir(dirname): os.mkdir(dirname,0o755) - file_out = '{}_{}.txt'.format(os.path.splitext(os.path.split(filename)[-1])[0],inc) + file_out = '{}_{}.txt'.format(os.path.splitext(os.path.split(filename)[-1])[0], + inc[3:].zfill(N_digits)) np.savetxt(os.path.join(dirname,file_out),data,header=header,comments='') diff --git a/processing/post/DADF5_vtk_cells.py b/processing/post/DADF5_vtk_cells.py index 1f5cc6686..58cb9771f 100755 --- a/processing/post/DADF5_vtk_cells.py +++ b/processing/post/DADF5_vtk_cells.py @@ -66,7 +66,7 @@ for filename in options.filenames: for i in f['/geometry/T_c']: grid.InsertNextCell(vtk.VTK_HEXAHEDRON,8,i-1) - + N_digits = int(np.floor(np.log10(int(results.increments[-1][3:]))))+1 for i,inc in enumerate(results.iter_visible('increments')): print('Output step {}/{}'.format(i+1,len(results.increments))) vtk_data = [] @@ -133,7 +133,9 @@ for filename in options.filenames: dirname = os.path.abspath(os.path.join(os.path.dirname(filename),options.dir)) if not os.path.isdir(dirname): os.mkdir(dirname,0o755) - file_out = '{}_{}.{}'.format(os.path.splitext(os.path.split(filename)[-1])[0],inc,writer.GetDefaultFileExtension()) + file_out = '{}_inc{}.{}'.format(os.path.splitext(os.path.split(filename)[-1])[0], + inc[3:].zfill(N_digits), + writer.GetDefaultFileExtension()) writer.SetCompressorTypeToZLib() writer.SetDataModeToBinary() diff --git a/processing/post/DADF5_vtk_points.py b/processing/post/DADF5_vtk_points.py index 87c1ad93e..9265cc3a0 100755 --- a/processing/post/DADF5_vtk_points.py +++ b/processing/post/DADF5_vtk_points.py @@ -52,6 +52,7 @@ for filename in options.filenames: Polydata.SetVerts(Vertices) Polydata.Modified() + N_digits = int(np.floor(np.log10(int(results.increments[-1][3:]))))+1 for i,inc in enumerate(results.iter_visible('increments')): print('Output step {}/{}'.format(i+1,len(results.increments))) vtk_data = [] @@ -111,7 +112,9 @@ for filename in options.filenames: dirname = os.path.abspath(os.path.join(os.path.dirname(filename),options.dir)) if not os.path.isdir(dirname): os.mkdir(dirname,0o755) - file_out = '{}_{}.{}'.format(os.path.splitext(os.path.split(filename)[-1])[0],inc,writer.GetDefaultFileExtension()) + file_out = '{}_inc{}.{}'.format(os.path.splitext(os.path.split(filename)[-1])[0], + inc[3:].zfill(N_digits), + writer.GetDefaultFileExtension()) writer.SetCompressorTypeToZLib() writer.SetDataModeToBinary() From dc3fc8f70cbd0fdb24af2d57d9bae294edba7366 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 29 Nov 2019 17:00:48 +0100 Subject: [PATCH 06/78] do not clutter with leading zeros --- python/damask/dadf5.py | 7 ++++--- src/results.f90 | 6 +++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/python/damask/dadf5.py b/python/damask/dadf5.py index d879946eb..ee497a9ae 100644 --- a/python/damask/dadf5.py +++ b/python/damask/dadf5.py @@ -30,7 +30,7 @@ class DADF5(): """ with h5py.File(filename,'r') as f: - if f.attrs['DADF5-major'] != 0 or not 2 <= f.attrs['DADF5-minor'] <= 3: + if f.attrs['DADF5-major'] != 0 or not 2 <= f.attrs['DADF5-minor'] <= 4: raise TypeError('Unsupported DADF5 version {} '.format(f.attrs['DADF5-version'])) self.structured = 'grid' in f['geometry'].attrs.keys() @@ -40,8 +40,9 @@ class DADF5(): self.size = f['geometry'].attrs['size'] r=re.compile('inc[0-9]+') - self.increments = [i for i in f.keys() if r.match(i)] - self.times = [round(f[i].attrs['time/s'],12) for i in self.increments] + increments_unsorted = {int(i[3:]):i for i in f.keys() if r.match(i)} + self.increments = [increments_unsorted[i] for i in sorted(increments_unsorted)] + self.times = [round(f[i].attrs['time/s'],12) for i in self.increments] self.Nmaterialpoints, self.Nconstituents = np.shape(f['mapping/cellResults/constituent']) self.materialpoints = [m.decode() for m in np.unique(f['mapping/cellResults/materialpoint']['Name'])] diff --git a/src/results.f90 b/src/results.f90 index 471f994d6..e77600d82 100644 --- a/src/results.f90 +++ b/src/results.f90 @@ -68,9 +68,9 @@ subroutine results_init write(6,'(a)') ' https://doi.org/10.1007/s40192-017-0084-5' resultsFile = HDF5_openFile(trim(getSolverJobName())//'.hdf5','w',.true.) - call HDF5_addAttribute(resultsFile,'DADF5-version',0.3_pReal) + call HDF5_addAttribute(resultsFile,'DADF5-version',0.4_pReal) call HDF5_addAttribute(resultsFile,'DADF5-major',0) - call HDF5_addAttribute(resultsFile,'DADF5-minor',3) + call HDF5_addAttribute(resultsFile,'DADF5-minor',4) call HDF5_addAttribute(resultsFile,'DAMASK',DAMASKVERSION) call get_command(commandLine) call HDF5_addAttribute(resultsFile,'call',trim(commandLine)) @@ -110,7 +110,7 @@ subroutine results_addIncrement(inc,time) real(pReal), intent(in) :: time character(len=pStringLen) :: incChar - write(incChar,'(i5.5)') inc ! allow up to 99999 increments + write(incChar,'(i10)') inc call HDF5_closeGroup(results_addGroup(trim('inc'//trim(adjustl(incChar))))) call results_setLink(trim('inc'//trim(adjustl(incChar))),'current') call HDF5_addAttribute(resultsFile,'time/s',time,trim('inc'//trim(adjustl(incChar)))) From e2b13a5ca3bb10042edc591edf994ecd3bae80d8 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 29 Nov 2019 19:32:18 +0100 Subject: [PATCH 07/78] using de-facto standard naming --- processing/post/DADF5_postResults.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/processing/post/DADF5_postResults.py b/processing/post/DADF5_postResults.py index ab68fc76b..1d05289cb 100755 --- a/processing/post/DADF5_postResults.py +++ b/processing/post/DADF5_postResults.py @@ -94,6 +94,6 @@ for filename in options.filenames: dirname = os.path.abspath(os.path.join(os.path.dirname(filename),options.dir)) if not os.path.isdir(dirname): os.mkdir(dirname,0o755) - file_out = '{}_{}.txt'.format(os.path.splitext(os.path.split(filename)[-1])[0], - inc[3:].zfill(N_digits)) + file_out = '{}_inc{}.txt'.format(os.path.splitext(os.path.split(filename)[-1])[0], + inc[3:].zfill(N_digits)) np.savetxt(os.path.join(dirname,file_out),data,header=header,comments='') From 4185fcb4c3f3c8505dfae9ca2d0386668337a195 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 29 Nov 2019 21:40:54 +0100 Subject: [PATCH 08/78] adjust to new naming --- python/damask/dadf5.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python/damask/dadf5.py b/python/damask/dadf5.py index ee497a9ae..77ac5458b 100644 --- a/python/damask/dadf5.py +++ b/python/damask/dadf5.py @@ -166,7 +166,7 @@ class DADF5(): end increment (included) """ - self.__manage_visible(['inc{:05d}'.format(i) for i in range(start,end+1)],'increments','set') + self.__manage_visible(['inc{}'.format(i) for i in range(start,end+1)],'increments','set') def add_by_increment(self,start,end): @@ -181,7 +181,7 @@ class DADF5(): end increment (included) """ - self.__manage_visible(['inc{:05d}'.format(i) for i in range(start,end+1)],'increments','add') + self.__manage_visible(['inc{}'.format(i) for i in range(start,end+1)],'increments','add') def del_by_increment(self,start,end): @@ -196,7 +196,7 @@ class DADF5(): end increment (included) """ - self.__manage_visible(['inc{:05d}'.format(i) for i in range(start,end+1)],'increments','del') + self.__manage_visible(['inc{}'.format(i) for i in range(start,end+1)],'increments','del') def iter_visible(self,what): From 354c0123a1bb84f40443b03992c569e71201ead1 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 30 Nov 2019 08:40:59 +0100 Subject: [PATCH 09/78] backward compatibility --- python/damask/dadf5.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/python/damask/dadf5.py b/python/damask/dadf5.py index 77ac5458b..7dddabfd4 100644 --- a/python/damask/dadf5.py +++ b/python/damask/dadf5.py @@ -30,7 +30,9 @@ class DADF5(): """ with h5py.File(filename,'r') as f: - if f.attrs['DADF5-major'] != 0 or not 2 <= f.attrs['DADF5-minor'] <= 4: + self.DADF5-major = f.attrs['DADF5-major'] + self.DADF5-minor = f.attrs['DADF5-minor'] + if self.DADF5-major != 0 or not 2 <= self.DADF5-minor <= 4: raise TypeError('Unsupported DADF5 version {} '.format(f.attrs['DADF5-version'])) self.structured = 'grid' in f['geometry'].attrs.keys() @@ -166,7 +168,10 @@ class DADF5(): end increment (included) """ - self.__manage_visible(['inc{}'.format(i) for i in range(start,end+1)],'increments','set') + if self.DADF5-minor >= 4: + self.__manage_visible([ 'inc{}'.format(i) for i in range(start,end+1)],'increments','set') + else: + self.__manage_visible(['inc{:05d}'.format(i) for i in range(start,end+1)],'increments','set') def add_by_increment(self,start,end): @@ -181,7 +186,10 @@ class DADF5(): end increment (included) """ - self.__manage_visible(['inc{}'.format(i) for i in range(start,end+1)],'increments','add') + if self.DADF5-minor >= 4: + self.__manage_visible([ 'inc{}'.format(i) for i in range(start,end+1)],'increments','add') + else: + self.__manage_visible(['inc{:05d}'.format(i) for i in range(start,end+1)],'increments','add') def del_by_increment(self,start,end): @@ -196,7 +204,10 @@ class DADF5(): end increment (included) """ - self.__manage_visible(['inc{}'.format(i) for i in range(start,end+1)],'increments','del') + if self.DADF5-minor >= 4: + self.__manage_visible([ 'inc{}'.format(i) for i in range(start,end+1)],'increments','del') + else: + self.__manage_visible(['inc{:05d}'.format(i) for i in range(start,end+1)],'increments','del') def iter_visible(self,what): From 8f77843b0f207ecf731d0f79e730cb4573c4ec99 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 30 Nov 2019 09:01:37 +0100 Subject: [PATCH 10/78] improved naming - clearer variable names - no '-' in attributes - single source of truth --- python/damask/dadf5.py | 17 +++++++++++------ src/results.f90 | 7 +++---- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/python/damask/dadf5.py b/python/damask/dadf5.py index 7dddabfd4..d03617752 100644 --- a/python/damask/dadf5.py +++ b/python/damask/dadf5.py @@ -30,9 +30,14 @@ class DADF5(): """ with h5py.File(filename,'r') as f: - self.DADF5-major = f.attrs['DADF5-major'] - self.DADF5-minor = f.attrs['DADF5-minor'] - if self.DADF5-major != 0 or not 2 <= self.DADF5-minor <= 4: + try: + self.version_major = f.attrs['DADF5_version_major'] + self.version_minor = f.attrs['DADF5_version_minor'] + except KeyError: + self.version_major = f.attrs['DADF5-major'] + self.version_minor = f.attrs['DADF5-minor'] + + if self.version_major != 0 or not 2 <= self.version_minor <= 4: raise TypeError('Unsupported DADF5 version {} '.format(f.attrs['DADF5-version'])) self.structured = 'grid' in f['geometry'].attrs.keys() @@ -168,7 +173,7 @@ class DADF5(): end increment (included) """ - if self.DADF5-minor >= 4: + if self.version_minor >= 4: self.__manage_visible([ 'inc{}'.format(i) for i in range(start,end+1)],'increments','set') else: self.__manage_visible(['inc{:05d}'.format(i) for i in range(start,end+1)],'increments','set') @@ -186,7 +191,7 @@ class DADF5(): end increment (included) """ - if self.DADF5-minor >= 4: + if self.version_minor >= 4: self.__manage_visible([ 'inc{}'.format(i) for i in range(start,end+1)],'increments','add') else: self.__manage_visible(['inc{:05d}'.format(i) for i in range(start,end+1)],'increments','add') @@ -204,7 +209,7 @@ class DADF5(): end increment (included) """ - if self.DADF5-minor >= 4: + if self.version_minor >= 4: self.__manage_visible([ 'inc{}'.format(i) for i in range(start,end+1)],'increments','del') else: self.__manage_visible(['inc{:05d}'.format(i) for i in range(start,end+1)],'increments','del') diff --git a/src/results.f90 b/src/results.f90 index e77600d82..a6b01790d 100644 --- a/src/results.f90 +++ b/src/results.f90 @@ -68,10 +68,9 @@ subroutine results_init write(6,'(a)') ' https://doi.org/10.1007/s40192-017-0084-5' resultsFile = HDF5_openFile(trim(getSolverJobName())//'.hdf5','w',.true.) - call HDF5_addAttribute(resultsFile,'DADF5-version',0.4_pReal) - call HDF5_addAttribute(resultsFile,'DADF5-major',0) - call HDF5_addAttribute(resultsFile,'DADF5-minor',4) - call HDF5_addAttribute(resultsFile,'DAMASK',DAMASKVERSION) + call HDF5_addAttribute(resultsFile,'DADF5_version_major',0) + call HDF5_addAttribute(resultsFile,'DADF5_version_minor',4) + call HDF5_addAttribute(resultsFile,'DAMASK_version',DAMASKVERSION) call get_command(commandLine) call HDF5_addAttribute(resultsFile,'call',trim(commandLine)) call HDF5_closeGroup(results_addGroup('mapping')) From 8189b50509962ce4a68bd1fbc85054a121e06c76 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 2 Dec 2019 12:58:23 +0100 Subject: [PATCH 11/78] same functionality but tested --- src/math.f90 | 27 --------------------------- src/plastic_nonlocal.f90 | 15 ++++++--------- 2 files changed, 6 insertions(+), 36 deletions(-) diff --git a/src/math.f90 b/src/math.f90 index 7eba379d2..6b83e17a3 100644 --- a/src/math.f90 +++ b/src/math.f90 @@ -838,33 +838,6 @@ pure function math_Voigt66to3333(m66) end function math_Voigt66to3333 -!-------------------------------------------------------------------------------------------------- -!> @brief action of a quaternion on a vector (rotate vector v with Q) -!> @details deprecated -!-------------------------------------------------------------------------------------------------- -pure function math_qRot(Q,v) - - real(pReal), dimension(4), intent(in) :: Q - real(pReal), dimension(3), intent(in) :: v - real(pReal), dimension(3) :: math_qRot - real(pReal), dimension(4,4) :: T - integer :: i, j - - do i = 1,4 - do j = 1,i - T(i,j) = Q(i) * Q(j) - enddo - enddo - - math_qRot = [-v(1)*(T(3,3)+T(4,4)) + v(2)*(T(3,2)-T(4,1)) + v(3)*(T(4,2)+T(3,1)), & - v(1)*(T(3,2)+T(4,1)) - v(2)*(T(2,2)+T(4,4)) + v(3)*(T(4,3)-T(2,1)), & - v(1)*(T(4,2)-T(3,1)) + v(2)*(T(4,3)+T(2,1)) - v(3)*(T(2,2)+T(3,3))] - - math_qRot = 2.0_pReal * math_qRot + v - -end function math_qRot - - !-------------------------------------------------------------------------------------------------- !> @brief rotation matrix from Bunge-Euler (3-1-3) angles (in radians) !> @details deprecated diff --git a/src/plastic_nonlocal.f90 b/src/plastic_nonlocal.f90 index 23bfb50aa..5469515dc 100644 --- a/src/plastic_nonlocal.f90 +++ b/src/plastic_nonlocal.f90 @@ -1836,8 +1836,6 @@ subroutine plastic_nonlocal_updateCompatibility(orientation,i,e) ns, & ! number of active slip systems s1, & ! slip system index (me) s2 ! slip system index (my neighbor) - real(pReal), dimension(4) :: & - absoluteMisorientation ! absolute misorientation (without symmetry) between me and my neighbor real(pReal), dimension(2,totalNslip(phase_plasticityInstance(material_phaseAt(1,e))),& totalNslip(phase_plasticityInstance(material_phaseAt(1,e))),& nIPneighbors) :: & @@ -1848,7 +1846,7 @@ subroutine plastic_nonlocal_updateCompatibility(orientation,i,e) nThresholdValues logical, dimension(totalNslip(phase_plasticityInstance(material_phaseAt(1,e)))) :: & belowThreshold - type(rotation) :: rot + type(rotation) :: mis Nneighbors = nIPneighbors ph = material_phaseAt(1,e) @@ -1914,18 +1912,17 @@ subroutine plastic_nonlocal_updateCompatibility(orientation,i,e) !* Finally the smallest compatibility value is decreased until the sum is exactly equal to one. !* All values below the threshold are set to zero. else - rot = orientation(1,i,e)%misorientation(orientation(1,neighbor_i,neighbor_e)) - absoluteMisorientation = rot%asQuaternion() + mis = orientation(1,i,e)%misorientation(orientation(1,neighbor_i,neighbor_e)) mySlipSystems: do s1 = 1,ns neighborSlipSystems: do s2 = 1,ns my_compatibility(1,s2,s1,n) = math_inner(prm%slip_normal(1:3,s1), & - math_qRot(absoluteMisorientation, prm%slip_normal(1:3,s2))) & + mis%rotate(prm%slip_normal(1:3,s2))) & * abs(math_inner(prm%slip_direction(1:3,s1), & - math_qRot(absoluteMisorientation, prm%slip_direction(1:3,s2)))) + mis%rotate(prm%slip_direction(1:3,s2)))) my_compatibility(2,s2,s1,n) = abs(math_inner(prm%slip_normal(1:3,s1), & - math_qRot(absoluteMisorientation, prm%slip_normal(1:3,s2)))) & + mis%rotate(prm%slip_normal(1:3,s2)))) & * abs(math_inner(prm%slip_direction(1:3,s1), & - math_qRot(absoluteMisorientation, prm%slip_direction(1:3,s2)))) + mis%rotate(prm%slip_direction(1:3,s2)))) enddo neighborSlipSystems my_compatibilitySum = 0.0_pReal From be099e38c2fcc451b6774ebe3da1b053d899e0f6 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 2 Dec 2019 16:22:27 +0100 Subject: [PATCH 12/78] might be of use --- src/rotations.f90 | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/rotations.f90 b/src/rotations.f90 index e042cff21..cd4a64547 100644 --- a/src/rotations.f90 +++ b/src/rotations.f90 @@ -64,6 +64,7 @@ module rotations procedure, public :: asRodrigues procedure, public :: asMatrix !------------------------------------------ + procedure, public :: fromQuaternion procedure, public :: fromEulers procedure, public :: fromAxisAngle procedure, public :: fromMatrix @@ -157,6 +158,18 @@ end function asHomochoric !--------------------------------------------------------------------------------------------------- ! Initialize rotation from different representations !--------------------------------------------------------------------------------------------------- +subroutine fromQuaternion(self,qu) + + class(rotation), intent(out) :: self + real(pReal), dimension(4), intent(in) :: qu + + if (dNeq(norm2(qu),1.0)) & + call IO_error(402,ext_msg='fromQuaternion') + + self%q = qu + +end subroutine fromQuaternion +!--------------------------------------------------------------------------------------------------- subroutine fromEulers(self,eu,degrees) class(rotation), intent(out) :: self From 83453d10ef25e079c562faed6082e3e13e7fe9bf Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 2 Dec 2019 16:37:22 +0100 Subject: [PATCH 13/78] use rotation class for consistent handling of rotations --- src/grid/DAMASK_grid.f90 | 24 ++++++++++-------------- src/grid/spectral_utilities.f90 | 3 ++- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/src/grid/DAMASK_grid.f90 b/src/grid/DAMASK_grid.f90 index e83cf3283..d71dcac18 100644 --- a/src/grid/DAMASK_grid.f90 +++ b/src/grid/DAMASK_grid.f90 @@ -28,7 +28,6 @@ program DAMASK_spectral use grid_damage_spectral use grid_thermal_spectral use results - use rotations implicit none @@ -78,7 +77,6 @@ program DAMASK_spectral character(len=6) :: loadcase_string character(len=1024) :: & incInfo - type(rotation) :: R type(tLoadCase), allocatable, dimension(:) :: loadCases !< array of all load cases type(tLoadCase) :: newLoadCase type(tSolutionState), allocatable, dimension(:) :: solres @@ -189,6 +187,7 @@ program DAMASK_spectral newLoadCase%ID(field) = FIELD_DAMAGE_ID endif damageActive + call newLoadCase%rot%fromEulers(real([0.0,0.0,0.0],pReal)) readIn: do i = 1, chunkPos(1) select case (IO_lc(IO_stringValue(line,chunkPos,i))) case('fdot','dotf','l','f') ! assign values for the deformation BC matrix @@ -244,14 +243,13 @@ program DAMASK_spectral do j = 1, 3 temp_valueVector(j) = IO_floatValue(line,chunkPos,i+k+j) enddo - call R%fromEulers(temp_valueVector(1:3),degrees=(l==1)) - newLoadCase%rotation = R%asMatrix() + call newLoadCase%rot%fromEulers(temp_valueVector(1:3),degrees=(l==1)) case('rotation','rot') ! assign values for the rotation matrix temp_valueVector = 0.0_pReal do j = 1, 9 temp_valueVector(j) = IO_floatValue(line,chunkPos,i+j) enddo - newLoadCase%rotation = math_9to33(temp_valueVector) + call newLoadCase%rot%fromMatrix(math_9to33(temp_valueVector)) end select enddo readIn @@ -295,14 +293,12 @@ program DAMASK_spectral endif enddo; write(6,'(/)',advance='no') enddo - if (any(abs(matmul(newLoadCase%rotation, & - transpose(newLoadCase%rotation))-math_I3) > & - reshape(spread(tol_math_check,1,9),[ 3,3]))& - .or. abs(math_det33(newLoadCase%rotation)) > & - 1.0_pReal + tol_math_check) errorID = 846 ! given rotation matrix contains strain - if (any(dNeq(newLoadCase%rotation, math_I3))) & + if (any(abs(matmul(newLoadCase%rot%asMatrix(), & + transpose(newLoadCase%rot%asMatrix()))-math_I3) > & + reshape(spread(tol_math_check,1,9),[ 3,3]))) errorID = 846 ! given rotation matrix contains strain + if (any(dNeq(newLoadCase%rot%asMatrix(), math_I3))) & write(6,'(2x,a,/,3(3(3x,f12.7,1x)/))',advance='no') 'rotation of loadframe:',& - transpose(newLoadCase%rotation) + transpose(newLoadCase%rot%asMatrix()) if (newLoadCase%time < 0.0_pReal) errorID = 834 ! negative time increment write(6,'(2x,a,f12.6)') 'time: ', newLoadCase%time if (newLoadCase%incs < 1) errorID = 835 ! non-positive incs count @@ -469,7 +465,7 @@ program DAMASK_spectral cutBack,guess,timeinc,timeIncOld,remainingLoadCaseTime, & deformation_BC = loadCases(currentLoadCase)%deformation, & stress_BC = loadCases(currentLoadCase)%stress, & - rotation_BC = loadCases(currentLoadCase)%rotation) + rotation_BC = loadCases(currentLoadCase)%rot%asMatrix()) case(FIELD_THERMAL_ID); call grid_thermal_spectral_forward(cutBack) case(FIELD_DAMAGE_ID); call grid_damage_spectral_forward(cutBack) @@ -488,7 +484,7 @@ program DAMASK_spectral solres(field) = mech_solution (& incInfo,timeinc,timeIncOld, & stress_BC = loadCases(currentLoadCase)%stress, & - rotation_BC = loadCases(currentLoadCase)%rotation) + rotation_BC = loadCases(currentLoadCase)%rot%asMatrix()) case(FIELD_THERMAL_ID) solres(field) = grid_thermal_spectral_solution(timeinc,timeIncOld) diff --git a/src/grid/spectral_utilities.f90 b/src/grid/spectral_utilities.f90 index 8b0e430f3..5107bd900 100644 --- a/src/grid/spectral_utilities.f90 +++ b/src/grid/spectral_utilities.f90 @@ -10,6 +10,7 @@ module spectral_utilities use prec use math + use rotations use IO use mesh_grid use numerics @@ -90,7 +91,7 @@ module spectral_utilities end type tBoundaryCondition type, public :: tLoadCase - real(pReal), dimension (3,3) :: rotation = math_I3 !< rotation of BC + type(rotation) :: rot !< rotation of BC type(tBoundaryCondition) :: stress, & !< stress BC deformation !< deformation BC (Fdot or L) real(pReal) :: time = 0.0_pReal !< length of increment From 8a9d3f8d6d48d579714b39d5901a44e70c732797 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 2 Dec 2019 20:06:58 +0100 Subject: [PATCH 14/78] avoid code duplication --- src/grid/DAMASK_grid.f90 | 4 +-- src/grid/grid_mech_FEM.f90 | 13 ++++----- src/grid/grid_mech_spectral_basic.f90 | 21 ++++++++------- src/grid/grid_mech_spectral_polarisation.f90 | 28 +++++++++++--------- src/grid/spectral_utilities.f90 | 3 ++- src/math.f90 | 14 ---------- src/rotations.f90 | 2 +- 7 files changed, 38 insertions(+), 47 deletions(-) diff --git a/src/grid/DAMASK_grid.f90 b/src/grid/DAMASK_grid.f90 index d71dcac18..51c97456b 100644 --- a/src/grid/DAMASK_grid.f90 +++ b/src/grid/DAMASK_grid.f90 @@ -465,7 +465,7 @@ program DAMASK_spectral cutBack,guess,timeinc,timeIncOld,remainingLoadCaseTime, & deformation_BC = loadCases(currentLoadCase)%deformation, & stress_BC = loadCases(currentLoadCase)%stress, & - rotation_BC = loadCases(currentLoadCase)%rot%asMatrix()) + rotation_BC = loadCases(currentLoadCase)%rot) case(FIELD_THERMAL_ID); call grid_thermal_spectral_forward(cutBack) case(FIELD_DAMAGE_ID); call grid_damage_spectral_forward(cutBack) @@ -484,7 +484,7 @@ program DAMASK_spectral solres(field) = mech_solution (& incInfo,timeinc,timeIncOld, & stress_BC = loadCases(currentLoadCase)%stress, & - rotation_BC = loadCases(currentLoadCase)%rot%asMatrix()) + rotation_BC = loadCases(currentLoadCase)%rot) case(FIELD_THERMAL_ID) solres(field) = grid_thermal_spectral_solution(timeinc,timeIncOld) diff --git a/src/grid/grid_mech_FEM.f90 b/src/grid/grid_mech_FEM.f90 index 0c3844fcf..be79af835 100644 --- a/src/grid/grid_mech_FEM.f90 +++ b/src/grid/grid_mech_FEM.f90 @@ -242,7 +242,8 @@ function grid_mech_FEM_solution(incInfoIn,timeinc,timeinc_old,stress_BC,rotation timeinc_old !< time increment of last successful increment type(tBoundaryCondition), intent(in) :: & stress_BC - real(pReal), dimension(3,3), intent(in) :: rotation_BC + type(rotation), intent(in) :: & + rotation_BC type(tSolutionState) :: & solution !-------------------------------------------------------------------------------------------------- @@ -254,7 +255,7 @@ function grid_mech_FEM_solution(incInfoIn,timeinc,timeinc_old,stress_BC,rotation !-------------------------------------------------------------------------------------------------- ! update stiffness (and gamma operator) - S = utilities_maskedCompliance(rotation_BC,stress_BC%maskLogical,C_volAvg) + S = utilities_maskedCompliance(rotation_BC%asMatrix(),stress_BC%maskLogical,C_volAvg) !-------------------------------------------------------------------------------------------------- ! set module wide available data params%stress_mask = stress_BC%maskFloat @@ -297,7 +298,7 @@ subroutine grid_mech_FEM_forward(cutBack,guess,timeinc,timeinc_old,loadCaseTime, type(tBoundaryCondition), intent(in) :: & stress_BC, & deformation_BC - real(pReal), dimension(3,3), intent(in) :: & + type(rotation), intent(in) :: & rotation_BC PetscErrorCode :: ierr PetscScalar, pointer, dimension(:,:,:,:) :: & @@ -482,7 +483,7 @@ subroutine formResidual(da_local,x_local, & trim(incInfo), ' @ Iteration ', itmin, '≤',totalIter+1, '≤', itmax if (iand(debug_level(debug_spectral),debug_spectralRotation) /= 0) & write(6,'(/,a,/,3(3(f12.7,1x)/))',advance='no') & - ' deformation gradient aim (lab) =', transpose(math_rotate_backward33(F_aim,params%rotation_BC)) + ' deformation gradient aim (lab) =', transpose(params%rotation_BC%rotTensor2(F_aim,active=.true.)) write(6,'(/,a,/,3(3(f12.7,1x)/))',advance='no') & ' deformation gradient aim =', transpose(F_aim) flush(6) @@ -498,7 +499,7 @@ subroutine formResidual(da_local,x_local, & x_elem(ctr,1:3) = x_scal(0:2,i+ii,j+jj,k+kk) enddo; enddo; enddo ii = i-xstart+1; jj = j-ystart+1; kk = k-zstart+1 - F(1:3,1:3,ii,jj,kk) = math_rotate_backward33(F_aim,params%rotation_BC) + transpose(matmul(BMat,x_elem)) + F(1:3,1:3,ii,jj,kk) = params%rotation_BC%rotTensor2(F_aim,active=.true.) + transpose(matmul(BMat,x_elem)) enddo; enddo; enddo call DMDAVecRestoreArrayF90(da_local,x_local,x_scal,ierr);CHKERRQ(ierr) @@ -506,7 +507,7 @@ subroutine formResidual(da_local,x_local, & ! evaluate constitutive response call Utilities_constitutiveResponse(P_current,& P_av,C_volAvg,devNull, & - F,params%timeinc,params%rotation_BC) + F,params%timeinc,params%rotation_BC%asMatrix()) call MPI_Allreduce(MPI_IN_PLACE,terminallyIll,1,MPI_LOGICAL,MPI_LOR,PETSC_COMM_WORLD,ierr) !-------------------------------------------------------------------------------------------------- diff --git a/src/grid/grid_mech_spectral_basic.f90 b/src/grid/grid_mech_spectral_basic.f90 index 3dc978dc6..74b56db61 100644 --- a/src/grid/grid_mech_spectral_basic.f90 +++ b/src/grid/grid_mech_spectral_basic.f90 @@ -212,7 +212,8 @@ function grid_mech_spectral_basic_solution(incInfoIn,timeinc,timeinc_old,stress_ timeinc_old !< time increment of last successful increment type(tBoundaryCondition), intent(in) :: & stress_BC - real(pReal), dimension(3,3), intent(in) :: rotation_BC + type(rotation), intent(in) :: & + rotation_BC type(tSolutionState) :: & solution !-------------------------------------------------------------------------------------------------- @@ -224,7 +225,7 @@ function grid_mech_spectral_basic_solution(incInfoIn,timeinc,timeinc_old,stress_ !-------------------------------------------------------------------------------------------------- ! update stiffness (and gamma operator) - S = utilities_maskedCompliance(rotation_BC,stress_BC%maskLogical,C_volAvg) + S = utilities_maskedCompliance(rotation_BC%asMatrix(),stress_BC%maskLogical,C_volAvg) if(num%update_gamma) call utilities_updateGamma(C_minMaxAvg) !-------------------------------------------------------------------------------------------------- @@ -269,7 +270,7 @@ subroutine grid_mech_spectral_basic_forward(cutBack,guess,timeinc,timeinc_old,lo type(tBoundaryCondition), intent(in) :: & stress_BC, & deformation_BC - real(pReal), dimension(3,3), intent(in) :: & + type(rotation), intent(in) :: & rotation_BC PetscErrorCode :: ierr PetscScalar, dimension(:,:,:,:), pointer :: F @@ -299,9 +300,9 @@ subroutine grid_mech_spectral_basic_forward(cutBack,guess,timeinc,timeinc_old,lo F_aimDot + deformation_BC%maskFloat * (deformation_BC%values - F_aim_lastInc)/loadCaseTime endif - Fdot = utilities_calculateRate(guess, & - F_lastInc,reshape(F,[3,3,grid(1),grid(2),grid3]),timeinc_old, & - math_rotate_backward33(F_aimDot,rotation_BC)) + Fdot = utilities_calculateRate(guess, & + F_lastInc,reshape(F,[3,3,grid(1),grid(2),grid3]),timeinc_old, & + rotation_BC%rotTensor2(F_aimDot,active=.true.)) F_lastInc = reshape(F,[3,3,grid(1),grid(2),grid3]) materialpoint_F0 = reshape(F, [3,3,1,product(grid(1:2))*grid3]) @@ -311,7 +312,7 @@ subroutine grid_mech_spectral_basic_forward(cutBack,guess,timeinc,timeinc_old,lo ! update average and local deformation gradients F_aim = F_aim_lastInc + F_aimDot * timeinc F = reshape(Utilities_forwardField(timeinc,F_lastInc,Fdot, & ! estimate of F at end of time+timeinc that matches rotated F_aim on average - math_rotate_backward33(F_aim,rotation_BC)),[9,grid(1),grid(2),grid3]) + rotation_BC%rotTensor2(F_aim,active=.true.)),[9,grid(1),grid(2),grid3]) call DMDAVecRestoreArrayF90(da,solution_vec,F,ierr); CHKERRQ(ierr) end subroutine grid_mech_spectral_basic_forward @@ -446,7 +447,7 @@ subroutine formResidual(in, F, & trim(incInfo), ' @ Iteration ', itmin, '≤',totalIter, '≤', itmax if (iand(debug_level(debug_spectral),debug_spectralRotation) /= 0) & write(6,'(/,a,/,3(3(f12.7,1x)/))',advance='no') & - ' deformation gradient aim (lab) =', transpose(math_rotate_backward33(F_aim,params%rotation_BC)) + ' deformation gradient aim (lab) =', transpose(params%rotation_BC%rotTensor2(F_aim,active=.true.)) write(6,'(/,a,/,3(3(f12.7,1x)/))',advance='no') & ' deformation gradient aim =', transpose(F_aim) flush(6) @@ -456,7 +457,7 @@ subroutine formResidual(in, F, & ! evaluate constitutive response call utilities_constitutiveResponse(residuum, & ! "residuum" gets field of first PK stress (to save memory) P_av,C_volAvg,C_minMaxAvg, & - F,params%timeinc,params%rotation_BC) + F,params%timeinc,params%rotation_BC%asMatrix()) call MPI_Allreduce(MPI_IN_PLACE,terminallyIll,1,MPI_LOGICAL,MPI_LOR,PETSC_COMM_WORLD,ierr) !-------------------------------------------------------------------------------------------------- @@ -471,7 +472,7 @@ subroutine formResidual(in, F, & tensorField_real(1:3,1:3,1:grid(1),1:grid(2),1:grid3) = residuum ! store fPK field for subsequent FFT forward transform call utilities_FFTtensorForward ! FFT forward of global "tensorField_real" err_div = Utilities_divergenceRMS() ! divRMS of tensorField_fourier for later use - call utilities_fourierGammaConvolution(math_rotate_backward33(deltaF_aim,params%rotation_BC)) ! convolution of Gamma and tensorField_fourier, with arg + call utilities_fourierGammaConvolution(params%rotation_BC%rotTensor2(deltaF_aim,active=.true.)) ! convolution of Gamma and tensorField_fourier call utilities_FFTtensorBackward ! FFT backward of global tensorField_fourier !-------------------------------------------------------------------------------------------------- diff --git a/src/grid/grid_mech_spectral_polarisation.f90 b/src/grid/grid_mech_spectral_polarisation.f90 index c1b5d79c9..5c5a9f10c 100644 --- a/src/grid/grid_mech_spectral_polarisation.f90 +++ b/src/grid/grid_mech_spectral_polarisation.f90 @@ -14,6 +14,7 @@ module grid_mech_spectral_polarisation use DAMASK_interface use HDF5_utilities use math + use rotations use spectral_utilities use IO use FEsolving @@ -222,12 +223,13 @@ function grid_mech_spectral_polarisation_solution(incInfoIn,timeinc,timeinc_old, ! input data for solution character(len=*), intent(in) :: & incInfoIn - real(pReal), intent(in) :: & + real(pReal), intent(in) :: & timeinc, & !< time increment of current solution timeinc_old !< time increment of last successful increment type(tBoundaryCondition), intent(in) :: & stress_BC - real(pReal), dimension(3,3), intent(in) :: rotation_BC + type(rotation), intent(in) :: & + rotation_BC type(tSolutionState) :: & solution !-------------------------------------------------------------------------------------------------- @@ -239,7 +241,7 @@ function grid_mech_spectral_polarisation_solution(incInfoIn,timeinc,timeinc_old, !-------------------------------------------------------------------------------------------------- ! update stiffness (and gamma operator) - S = utilities_maskedCompliance(rotation_BC,stress_BC%maskLogical,C_volAvg) + S = utilities_maskedCompliance(rotation_BC%asMatrix(),stress_BC%maskLogical,C_volAvg) if (num%update_gamma) then call utilities_updateGamma(C_minMaxAvg) C_scale = C_minMaxAvg @@ -288,7 +290,7 @@ subroutine grid_mech_spectral_polarisation_forward(cutBack,guess,timeinc,timeinc type(tBoundaryCondition), intent(in) :: & stress_BC, & deformation_BC - real(pReal), dimension(3,3), intent(in) ::& + type(rotation), intent(in) :: & rotation_BC PetscErrorCode :: ierr PetscScalar, dimension(:,:,:,:), pointer :: FandF_tau, F, F_tau @@ -324,10 +326,10 @@ subroutine grid_mech_spectral_polarisation_forward(cutBack,guess,timeinc,timeinc Fdot = utilities_calculateRate(guess, & F_lastInc,reshape(F,[3,3,grid(1),grid(2),grid3]),timeinc_old, & - math_rotate_backward33(F_aimDot,rotation_BC)) + rotation_BC%rotTensor2(F_aimDot,active=.true.)) F_tauDot = utilities_calculateRate(guess, & F_tau_lastInc,reshape(F_tau,[3,3,grid(1),grid(2),grid3]), timeinc_old, & - math_rotate_backward33(F_aimDot,rotation_BC)) + rotation_BC%rotTensor2(F_aimDot,active=.true.)) F_lastInc = reshape(F, [3,3,grid(1),grid(2),grid3]) F_tau_lastInc = reshape(F_tau,[3,3,grid(1),grid(2),grid3]) @@ -338,7 +340,7 @@ subroutine grid_mech_spectral_polarisation_forward(cutBack,guess,timeinc,timeinc ! update average and local deformation gradients F_aim = F_aim_lastInc + F_aimDot * timeinc F = reshape(utilities_forwardField(timeinc,F_lastInc,Fdot, & ! estimate of F at end of time+timeinc that matches rotated F_aim on average - math_rotate_backward33(F_aim,rotation_BC)),& + rotation_BC%rotTensor2(F_aim,active=.true.)),& [9,grid(1),grid(2),grid3]) if (guess) then F_tau = reshape(Utilities_forwardField(timeinc,F_tau_lastInc,F_taudot), & @@ -349,8 +351,8 @@ subroutine grid_mech_spectral_polarisation_forward(cutBack,guess,timeinc,timeinc F_lambda33 = math_mul3333xx33(S_scale,matmul(F_lambda33, & math_mul3333xx33(C_scale,& matmul(transpose(F_lambda33),& - F_lambda33)-math_I3))*0.5_pReal)& - + math_I3 + F_lambda33)-math_I3))*0.5_pReal) & + + math_I3 F_tau(1:9,i,j,k) = reshape(F_lambda33,[9])+F(1:9,i,j,k) enddo; enddo; enddo endif @@ -514,7 +516,7 @@ subroutine formResidual(in, FandF_tau, & trim(incInfo), ' @ Iteration ', itmin, '≤',totalIter, '≤', itmax if (iand(debug_level(debug_spectral),debug_spectralRotation) /= 0) & write(6,'(/,a,/,3(3(f12.7,1x)/))',advance='no') & - ' deformation gradient aim (lab) =', transpose(math_rotate_backward33(F_aim,params%rotation_BC)) + ' deformation gradient aim (lab) =', transpose(params%rotation_BC%rotTensor2(F_aim,active=.true.)) write(6,'(/,a,/,3(3(f12.7,1x)/))',advance='no') & ' deformation gradient aim =', transpose(F_aim) flush(6) @@ -533,7 +535,7 @@ subroutine formResidual(in, FandF_tau, & !-------------------------------------------------------------------------------------------------- ! doing convolution in Fourier space call utilities_FFTtensorForward - call utilities_fourierGammaConvolution(math_rotate_backward33(polarBeta*F_aim,params%rotation_BC)) + call utilities_fourierGammaConvolution(params%rotation_BC%rotTensor2(polarBeta*F_aim,active=.true.)) call utilities_FFTtensorBackward !-------------------------------------------------------------------------------------------------- @@ -544,14 +546,14 @@ subroutine formResidual(in, FandF_tau, & ! evaluate constitutive response call utilities_constitutiveResponse(residual_F, & ! "residuum" gets field of first PK stress (to save memory) P_av,C_volAvg,C_minMaxAvg, & - F - residual_F_tau/polarBeta,params%timeinc,params%rotation_BC) + F - residual_F_tau/polarBeta,params%timeinc,params%rotation_BC%asMatrix()) call MPI_Allreduce(MPI_IN_PLACE,terminallyIll,1,MPI_LOGICAL,MPI_LOR,PETSC_COMM_WORLD,ierr) !-------------------------------------------------------------------------------------------------- ! stress BC handling F_aim = F_aim - math_mul3333xx33(S, ((P_av - params%stress_BC))) ! S = 0.0 for no bc err_BC = maxval(abs((1.0_pReal-params%stress_mask) * math_mul3333xx33(C_scale,F_aim & - -math_rotate_forward33(F_av,params%rotation_BC)) + & + -params%rotation_BC%rotTensor2(F_av)) + & params%stress_mask * (P_av-params%stress_BC))) ! mask = 0.0 for no bc ! calculate divergence tensorField_real = 0.0_pReal diff --git a/src/grid/spectral_utilities.f90 b/src/grid/spectral_utilities.f90 index 5107bd900..7b826033b 100644 --- a/src/grid/spectral_utilities.f90 +++ b/src/grid/spectral_utilities.f90 @@ -104,7 +104,8 @@ module spectral_utilities end type tLoadCase type, public :: tSolutionParams !< @todo use here the type definition for a full loadcase - real(pReal), dimension(3,3) :: stress_mask, stress_BC, rotation_BC + real(pReal), dimension(3,3) :: stress_mask, stress_BC + type(rotation) :: rotation_BC real(pReal) :: timeinc real(pReal) :: timeincOld end type tSolutionParams diff --git a/src/math.f90 b/src/math.f90 index 6b83e17a3..bac2f8192 100644 --- a/src/math.f90 +++ b/src/math.f90 @@ -1315,20 +1315,6 @@ pure function math_rotate_forward33(tensor,R) end function math_rotate_forward33 -!-------------------------------------------------------------------------------------------------- -!> @brief rotate 33 tensor backward -!> @details deprecated -!-------------------------------------------------------------------------------------------------- -pure function math_rotate_backward33(tensor,R) - - real(pReal), dimension(3,3) :: math_rotate_backward33 - real(pReal), dimension(3,3), intent(in) :: tensor, R - - math_rotate_backward33 = matmul(transpose(R),matmul(tensor,R)) - -end function math_rotate_backward33 - - !-------------------------------------------------------------------------------------------------- !> @brief rotate 3333 tensor C'_ijkl=g_im*g_jn*g_ko*g_lp*C_mnop !> @details deprecated diff --git a/src/rotations.f90 b/src/rotations.f90 index cd4a64547..a4a0bac88 100644 --- a/src/rotations.f90 +++ b/src/rotations.f90 @@ -163,7 +163,7 @@ subroutine fromQuaternion(self,qu) class(rotation), intent(out) :: self real(pReal), dimension(4), intent(in) :: qu - if (dNeq(norm2(qu),1.0)) & + if (dNeq(norm2(qu),1.0_pReal)) & call IO_error(402,ext_msg='fromQuaternion') self%q = qu From f5292019e5820c0f7f9a3f43c342560e12e66368 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 2 Dec 2019 20:23:50 +0100 Subject: [PATCH 15/78] use rotation class --- src/grid/grid_mech_FEM.f90 | 7 ++-- src/grid/grid_mech_spectral_basic.f90 | 7 ++-- src/grid/grid_mech_spectral_polarisation.f90 | 7 ++-- src/grid/spectral_utilities.f90 | 26 ++++++++------- src/math.f90 | 35 -------------------- 5 files changed, 23 insertions(+), 59 deletions(-) diff --git a/src/grid/grid_mech_FEM.f90 b/src/grid/grid_mech_FEM.f90 index be79af835..e87e02d09 100644 --- a/src/grid/grid_mech_FEM.f90 +++ b/src/grid/grid_mech_FEM.f90 @@ -207,8 +207,7 @@ subroutine grid_mech_FEM_init call utilities_updateCoords(F) call utilities_constitutiveResponse(P_current,temp33_Real,C_volAvg,devNull, & ! stress field, stress avg, global average of stiffness and (min+max)/2 F, & ! target F - 0.0_pReal, & ! time increment - math_I3) ! no rotation of boundary condition + 0.0_pReal) ! time increment call DMDAVecRestoreArrayF90(mech_grid,solution_current,u_current,ierr) CHKERRQ(ierr) call DMDAVecRestoreArrayF90(mech_grid,solution_lastInc,u_lastInc,ierr) @@ -255,7 +254,7 @@ function grid_mech_FEM_solution(incInfoIn,timeinc,timeinc_old,stress_BC,rotation !-------------------------------------------------------------------------------------------------- ! update stiffness (and gamma operator) - S = utilities_maskedCompliance(rotation_BC%asMatrix(),stress_BC%maskLogical,C_volAvg) + S = utilities_maskedCompliance(rotation_BC,stress_BC%maskLogical,C_volAvg) !-------------------------------------------------------------------------------------------------- ! set module wide available data params%stress_mask = stress_BC%maskFloat @@ -507,7 +506,7 @@ subroutine formResidual(da_local,x_local, & ! evaluate constitutive response call Utilities_constitutiveResponse(P_current,& P_av,C_volAvg,devNull, & - F,params%timeinc,params%rotation_BC%asMatrix()) + F,params%timeinc,params%rotation_BC) call MPI_Allreduce(MPI_IN_PLACE,terminallyIll,1,MPI_LOGICAL,MPI_LOR,PETSC_COMM_WORLD,ierr) !-------------------------------------------------------------------------------------------------- diff --git a/src/grid/grid_mech_spectral_basic.f90 b/src/grid/grid_mech_spectral_basic.f90 index 74b56db61..36caabf90 100644 --- a/src/grid/grid_mech_spectral_basic.f90 +++ b/src/grid/grid_mech_spectral_basic.f90 @@ -173,8 +173,7 @@ subroutine grid_mech_spectral_basic_init call Utilities_updateCoords(reshape(F,shape(F_lastInc))) call Utilities_constitutiveResponse(P,temp33_Real,C_volAvg,C_minMaxAvg, & ! stress field, stress avg, global average of stiffness and (min+max)/2 reshape(F,shape(F_lastInc)), & ! target F - 0.0_pReal, & ! time increment - math_I3) ! no rotation of boundary condition + 0.0_pReal) ! time increment call DMDAVecRestoreArrayF90(da,solution_vec,F,ierr); CHKERRQ(ierr) ! deassociate pointer restartRead2: if (interface_restartInc > 0) then @@ -225,7 +224,7 @@ function grid_mech_spectral_basic_solution(incInfoIn,timeinc,timeinc_old,stress_ !-------------------------------------------------------------------------------------------------- ! update stiffness (and gamma operator) - S = utilities_maskedCompliance(rotation_BC%asMatrix(),stress_BC%maskLogical,C_volAvg) + S = utilities_maskedCompliance(rotation_BC,stress_BC%maskLogical,C_volAvg) if(num%update_gamma) call utilities_updateGamma(C_minMaxAvg) !-------------------------------------------------------------------------------------------------- @@ -457,7 +456,7 @@ subroutine formResidual(in, F, & ! evaluate constitutive response call utilities_constitutiveResponse(residuum, & ! "residuum" gets field of first PK stress (to save memory) P_av,C_volAvg,C_minMaxAvg, & - F,params%timeinc,params%rotation_BC%asMatrix()) + F,params%timeinc,params%rotation_BC) call MPI_Allreduce(MPI_IN_PLACE,terminallyIll,1,MPI_LOGICAL,MPI_LOR,PETSC_COMM_WORLD,ierr) !-------------------------------------------------------------------------------------------------- diff --git a/src/grid/grid_mech_spectral_polarisation.f90 b/src/grid/grid_mech_spectral_polarisation.f90 index 5c5a9f10c..07d9a5afc 100644 --- a/src/grid/grid_mech_spectral_polarisation.f90 +++ b/src/grid/grid_mech_spectral_polarisation.f90 @@ -187,8 +187,7 @@ subroutine grid_mech_spectral_polarisation_init call Utilities_updateCoords(reshape(F,shape(F_lastInc))) call Utilities_constitutiveResponse(P,temp33_Real,C_volAvg,C_minMaxAvg, & ! stress field, stress avg, global average of stiffness and (min+max)/2 reshape(F,shape(F_lastInc)), & ! target F - 0.0_pReal, & ! time increment - math_I3) ! no rotation of boundary condition + 0.0_pReal) ! time increment call DMDAVecRestoreArrayF90(da,solution_vec,FandF_tau,ierr); CHKERRQ(ierr) ! deassociate pointer restartRead2: if (interface_restartInc > 0) then @@ -241,7 +240,7 @@ function grid_mech_spectral_polarisation_solution(incInfoIn,timeinc,timeinc_old, !-------------------------------------------------------------------------------------------------- ! update stiffness (and gamma operator) - S = utilities_maskedCompliance(rotation_BC%asMatrix(),stress_BC%maskLogical,C_volAvg) + S = utilities_maskedCompliance(rotation_BC,stress_BC%maskLogical,C_volAvg) if (num%update_gamma) then call utilities_updateGamma(C_minMaxAvg) C_scale = C_minMaxAvg @@ -546,7 +545,7 @@ subroutine formResidual(in, FandF_tau, & ! evaluate constitutive response call utilities_constitutiveResponse(residual_F, & ! "residuum" gets field of first PK stress (to save memory) P_av,C_volAvg,C_minMaxAvg, & - F - residual_F_tau/polarBeta,params%timeinc,params%rotation_BC%asMatrix()) + F - residual_F_tau/polarBeta,params%timeinc,params%rotation_BC) call MPI_Allreduce(MPI_IN_PLACE,terminallyIll,1,MPI_LOGICAL,MPI_LOR,PETSC_COMM_WORLD,ierr) !-------------------------------------------------------------------------------------------------- diff --git a/src/grid/spectral_utilities.f90 b/src/grid/spectral_utilities.f90 index 7b826033b..a1265556a 100644 --- a/src/grid/spectral_utilities.f90 +++ b/src/grid/spectral_utilities.f90 @@ -686,10 +686,11 @@ end function utilities_curlRMS !-------------------------------------------------------------------------------------------------- function utilities_maskedCompliance(rot_BC,mask_stress,C) - real(pReal), dimension(3,3,3,3) :: utilities_maskedCompliance !< masked compliance - real(pReal), intent(in) , dimension(3,3,3,3) :: C !< current average stiffness - real(pReal), intent(in) , dimension(3,3) :: rot_BC !< rotation of load frame - logical, intent(in), dimension(3,3) :: mask_stress !< mask of stress BC + real(pReal), dimension(3,3,3,3) :: utilities_maskedCompliance !< masked compliance + real(pReal), intent(in), dimension(3,3,3,3) :: C !< current average stiffness + type(rotation), intent(in) :: rot_BC !< rotation of load frame + logical, intent(in), dimension(3,3) :: mask_stress !< mask of stress BC + integer :: j, k, m, n logical, dimension(9) :: mask_stressVector real(pReal), dimension(9,9) :: temp99_Real @@ -707,7 +708,7 @@ function utilities_maskedCompliance(rot_BC,mask_stress,C) allocate (c_reduced(size_reduced,size_reduced), source =0.0_pReal) allocate (s_reduced(size_reduced,size_reduced), source =0.0_pReal) allocate (sTimesC(size_reduced,size_reduced), source =0.0_pReal) - temp99_Real = math_3333to99(math_rotate_forward3333(C,rot_BC)) + temp99_Real = math_3333to99(rot_BC%rotTensor4(C)) if(debugGeneral) then write(6,'(/,a)') ' ... updating masked compliance ............................................' @@ -836,12 +837,12 @@ end subroutine utilities_fourierTensorDivergence subroutine utilities_constitutiveResponse(P,P_av,C_volAvg,C_minmaxAvg,& F,timeinc,rotation_BC) - real(pReal),intent(out), dimension(3,3,3,3) :: C_volAvg, C_minmaxAvg !< average stiffness - real(pReal),intent(out), dimension(3,3) :: P_av !< average PK stress - real(pReal),intent(out), dimension(3,3,grid(1),grid(2),grid3) :: P !< PK stress - real(pReal), intent(in), dimension(3,3,grid(1),grid(2),grid3) :: F !< deformation gradient target - real(pReal), intent(in) :: timeinc !< loading time - real(pReal), intent(in), dimension(3,3) :: rotation_BC !< rotation of load frame + real(pReal), intent(out), dimension(3,3,3,3) :: C_volAvg, C_minmaxAvg !< average stiffness + real(pReal), intent(out), dimension(3,3) :: P_av !< average PK stress + real(pReal), intent(out), dimension(3,3,grid(1),grid(2),grid3) :: P !< PK stress + real(pReal), intent(in), dimension(3,3,grid(1),grid(2),grid3) :: F !< deformation gradient target + real(pReal), intent(in) :: timeinc !< loading time + type(rotation), intent(in), optional :: rotation_BC !< rotation of load frame integer :: & @@ -863,7 +864,8 @@ subroutine utilities_constitutiveResponse(P,P_av,C_volAvg,C_minmaxAvg,& if (debugRotation) & write(6,'(/,a,/,3(3(2x,f12.4,1x)/))',advance='no') ' Piola--Kirchhoff stress (lab) / MPa =',& transpose(P_av)*1.e-6_pReal - P_av = math_rotate_forward33(P_av,rotation_BC) + if(present(rotation_BC)) & + P_av = rotation_BC%rotTensor2(P_av) write(6,'(/,a,/,3(3(2x,f12.4,1x)/))',advance='no') ' Piola--Kirchhoff stress / MPa =',& transpose(P_av)*1.e-6_pReal flush(6) diff --git a/src/math.f90 b/src/math.f90 index bac2f8192..0b06c9186 100644 --- a/src/math.f90 +++ b/src/math.f90 @@ -1301,41 +1301,6 @@ real(pReal) pure function math_areaTriangle(v1,v2,v3) end function math_areaTriangle -!-------------------------------------------------------------------------------------------------- -!> @brief rotate 33 tensor forward -!> @details deprecated -!-------------------------------------------------------------------------------------------------- -pure function math_rotate_forward33(tensor,R) - - real(pReal), dimension(3,3) :: math_rotate_forward33 - real(pReal), dimension(3,3), intent(in) :: tensor, R - - math_rotate_forward33 = matmul(R,matmul(tensor,transpose(R))) - -end function math_rotate_forward33 - - -!-------------------------------------------------------------------------------------------------- -!> @brief rotate 3333 tensor C'_ijkl=g_im*g_jn*g_ko*g_lp*C_mnop -!> @details deprecated -!-------------------------------------------------------------------------------------------------- -pure function math_rotate_forward3333(tensor,R) - - real(pReal), dimension(3,3,3,3) :: math_rotate_forward3333 - real(pReal), dimension(3,3), intent(in) :: R - real(pReal), dimension(3,3,3,3), intent(in) :: tensor - integer :: i,j,k,l,m,n,o,p - - math_rotate_forward3333 = 0.0_pReal - do i = 1,3;do j = 1,3;do k = 1,3;do l = 1,3 - do m = 1,3;do n = 1,3;do o = 1,3;do p = 1,3 - math_rotate_forward3333(i,j,k,l) = math_rotate_forward3333(i,j,k,l) & - + R(i,m) * R(j,n) * R(k,o) * R(l,p) * tensor(m,n,o,p) - enddo; enddo; enddo; enddo; enddo; enddo; enddo; enddo - -end function math_rotate_forward3333 - - !-------------------------------------------------------------------------------------------------- !> @brief limits a scalar value to a certain range (either one or two sided) ! Will return NaN if left > right From fecd4632b45f9949542306cfd311d9c001269550 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 4 Dec 2019 05:49:17 +0100 Subject: [PATCH 16/78] correct reporting of time --- python/damask/dadf5.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/damask/dadf5.py b/python/damask/dadf5.py index d03617752..4790a1b38 100644 --- a/python/damask/dadf5.py +++ b/python/damask/dadf5.py @@ -333,8 +333,8 @@ class DADF5(): """Return information on all active datasets in the file.""" message = '' with h5py.File(self.filename,'r') as f: - for s,i in enumerate(self.iter_visible('increments')): - message+='\n{} ({}s)\n'.format(i,self.times[s]) + for i in self.iter_visible('increments'): + message+='\n{} ({}s)\n'.format(i,self.times[self.increments.index(i)]) for o,p in zip(['constituents','materialpoints'],['con_physics','mat_physics']): for oo in self.iter_visible(o): message+=' {}\n'.format(oo) From 32ebcea207d23c10c76b8fa97a5fc1b0a281b500 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 4 Dec 2019 05:49:43 +0100 Subject: [PATCH 17/78] more tests --- python/tests/test_DADF5.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/python/tests/test_DADF5.py b/python/tests/test_DADF5.py index 5a6478f03..37c5a9e87 100644 --- a/python/tests/test_DADF5.py +++ b/python/tests/test_DADF5.py @@ -42,6 +42,22 @@ class TestDADF5: in_file = default.read_dataset(loc['sigma'],0) assert np.allclose(in_memory,in_file) + def test_add_determinant(self,default): + default.add_determinant('P') + loc = {'P': default.get_dataset_location('P'), + 'det(P)':default.get_dataset_location('det(P)')} + in_memory = np.linalg.det(default.read_dataset(loc['P'],0)) + in_file = default.read_dataset(loc['det(P)'],0) + assert np.allclose(in_memory,in_file) + + def test_add_norm(self,default): + default.add_norm('F',1) + loc = {'F': default.get_dataset_location('F'), + '|F|_1':default.get_dataset_location('|F|_1')} + in_memory = np.linalg.norm(default.read_dataset(loc['F'],0),ord=1,axis=(1,2),keepdims=True) + in_file = default.read_dataset(loc['|F|_1'],0) + assert np.allclose(in_memory,in_file) + def test_add_absolute(self,default): default.add_absolute('Fe') loc = {'Fe': default.get_dataset_location('Fe'), From 6c31e228553a3c453fba8905ed70f12a939307ea Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 4 Dec 2019 05:59:52 +0100 Subject: [PATCH 18/78] testing new style DADF5 file --- .../DADF5/12grains6x7x8_tensionY.hdf5 | Bin 1935952 -> 1935528 bytes python/tests/test_DADF5.py | 8 +++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/python/tests/reference/DADF5/12grains6x7x8_tensionY.hdf5 b/python/tests/reference/DADF5/12grains6x7x8_tensionY.hdf5 index caafce4784e2e9e3f29f8bd6dcad4e338a238153..39c17fadb5cc8fe724606eda02d7a62ac7ee8c6b 100644 GIT binary patch delta 19434 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 z

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 diff --git a/python/tests/test_DADF5.py b/python/tests/test_DADF5.py index 37c5a9e87..1dd93d003 100644 --- a/python/tests/test_DADF5.py +++ b/python/tests/test_DADF5.py @@ -23,7 +23,13 @@ def reference_dir(reference_dir_base): class TestDADF5: - + + def test_time_increments(self,default): + shape = default.read_dataset(default.get_dataset_location('F'),0).shape + default.set_by_time(0.0,20.0) + for i in default.iter_visible('increments'): + assert shape == default.read_dataset(default.get_dataset_location('F'),0).shape + def test_add_deviator(self,default): default.add_deviator('P') loc = {'P' :default.get_dataset_location('P'), From 6902d3dd0add631fda7dede02030bcfd59c94a4b Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 4 Dec 2019 06:04:06 +0100 Subject: [PATCH 19/78] repeated test better sort alphabetically --- python/tests/test_DADF5.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/python/tests/test_DADF5.py b/python/tests/test_DADF5.py index 1dd93d003..2235321b5 100644 --- a/python/tests/test_DADF5.py +++ b/python/tests/test_DADF5.py @@ -72,14 +72,6 @@ class TestDADF5: in_file = default.read_dataset(loc['|Fe|'],0) assert np.allclose(in_memory,in_file) - def test_add_determinant(self,default): - default.add_determinant('P') - loc = {'P': default.get_dataset_location('P'), - 'det(P)': default.get_dataset_location('det(P)')} - in_memory = np.linalg.det(default.read_dataset(loc['P'],0)).reshape(-1,1) - in_file = default.read_dataset(loc['det(P)'],0) - assert np.allclose(in_memory,in_file) - def test_add_spherical(self,default): default.add_spherical('P') loc = {'P': default.get_dataset_location('P'), From 285075bb6b35a0e6083223109fa0b056f19f8196 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 4 Dec 2019 06:15:32 +0100 Subject: [PATCH 20/78] ordered alphabetically --- python/damask/dadf5.py | 332 ++++++++++++++++++------------------- python/tests/test_DADF5.py | 33 ++-- 2 files changed, 183 insertions(+), 182 deletions(-) diff --git a/python/damask/dadf5.py b/python/damask/dadf5.py index 4790a1b38..5c23636db 100644 --- a/python/damask/dadf5.py +++ b/python/damask/dadf5.py @@ -437,6 +437,76 @@ class DADF5(): else: with h5py.File(self.filename,'r') as f: return f['geometry/x_c'][()] + + + def add_absolute(self,x): + """ + Add absolute value. + + Parameters + ---------- + x : str + Label of the dataset containing a scalar, vector, or tensor. + + """ + def __add_absolute(x): + + return { + 'data': np.abs(x['data']), + 'label': '|{}|'.format(x['label']), + 'meta': { + 'Unit': x['meta']['Unit'], + 'Description': 'Absolute value of {} ({})'.format(x['label'],x['meta']['Description']), + 'Creator': 'dadf5.py:add_abs v{}'.format(version) + } + } + + requested = [{'label':x,'arg':'x'}] + + self.__add_generic_pointwise(__add_absolute,requested) + + + def add_calculation(self,formula,label,unit='n/a',description=None,vectorized=True): + """ + Add result of a general formula. + + Parameters + ---------- + formula : str + Formula, refer to datasets by ‘#Label#‘. + label : str + Label of the dataset containing the result of the calculation. + unit : str, optional + Physical unit of the result. + description : str, optional + Human readable description of the result. + vectorized : bool, optional + Indicate whether the formula is written in vectorized form. Default is ‘True’. + + """ + if vectorized is not True: + raise NotImplementedError + + def __add_calculation(**kwargs): + + formula = kwargs['formula'] + for d in re.findall(r'#(.*?)#',formula): + formula = formula.replace('#{}#'.format(d),"kwargs['{}']['data']".format(d)) + + return { + 'data': eval(formula), + 'label': kwargs['label'], + 'meta': { + 'Unit': kwargs['unit'], + 'Description': '{} (formula: {})'.format(kwargs['description'],kwargs['formula']), + 'Creator': 'dadf5.py:add_calculation v{}'.format(version) + } + } + + requested = [{'label':d,'arg':d} for d in set(re.findall(r'#(.*?)#',formula))] # datasets used in the formula + pass_through = {'formula':formula,'label':label,'unit':unit,'description':description} + + self.__add_generic_pointwise(__add_calculation,requested,pass_through) def add_Cauchy(self,P='P',F='F'): @@ -470,6 +540,90 @@ class DADF5(): self.__add_generic_pointwise(__add_Cauchy,requested) + def add_determinant(self,x): + """ + Add the determinant of a tensor. + + Parameters + ---------- + x : str + Label of the dataset containing a tensor. + + """ + def __add_determinant(x): + + return { + 'data': np.linalg.det(x['data']), + 'label': 'det({})'.format(x['label']), + 'meta': { + 'Unit': x['meta']['Unit'], + 'Description': 'Determinant of tensor {} ({})'.format(x['label'],x['meta']['Description']), + 'Creator': 'dadf5.py:add_determinant v{}'.format(version) + } + } + + requested = [{'label':x,'arg':'x'}] + + self.__add_generic_pointwise(__add_determinant,requested) + + + def add_deviator(self,x): + """ + Add the deviatoric part of a tensor. + + Parameters + ---------- + x : str + Label of the dataset containing a tensor. + + """ + def __add_deviator(x): + + if not np.all(np.array(x['data'].shape[1:]) == np.array([3,3])): + raise ValueError + + return { + 'data': mechanics.deviatoric_part(x['data']), + 'label': 's_{}'.format(x['label']), + 'meta': { + 'Unit': x['meta']['Unit'], + 'Description': 'Deviator of tensor {} ({})'.format(x['label'],x['meta']['Description']), + 'Creator': 'dadf5.py:add_deviator v{}'.format(version) + } + } + + requested = [{'label':x,'arg':'x'}] + + self.__add_generic_pointwise(__add_deviator,requested) + + + def add_maximum_shear(self,x): + """ + Add maximum shear components of symmetric tensor. + + Parameters + ---------- + x : str + Label of the dataset containing a symmetric tensor. + + """ + def __add_maximum_shear(x): + + return { + 'data': mechanics.maximum_shear(x['data']), + 'label': 'max_shear({})'.format(x['label']), + 'meta': { + 'Unit': x['meta']['Unit'], + 'Description': 'Maximum shear component of of {} ({})'.format(x['label'],x['meta']['Description']), + 'Creator': 'dadf5.py:add_maximum_shear v{}'.format(version) + } + } + + requested = [{'label':x,'arg':'x'}] + + self.__add_generic_pointwise(__add_maximum_shear,requested) + + def add_Mises(self,x): """ Add the equivalent Mises stress or strain of a symmetric tensor. @@ -540,58 +694,33 @@ class DADF5(): self.__add_generic_pointwise(__add_norm,requested,{'ord':ord}) - def add_absolute(self,x): + def add_principal_components(self,x): """ - Add absolute value. - + Add principal components of symmetric tensor. + + The principal components are sorted in descending order, each repeated according to its multiplicity. + Parameters ---------- x : str - Label of the dataset containing a scalar, vector, or tensor. + Label of the dataset containing a symmetric tensor. """ - def __add_absolute(x): + def __add_principal_components(x): return { - 'data': np.abs(x['data']), - 'label': '|{}|'.format(x['label']), + 'data': mechanics.principal_components(x['data']), + 'label': 'lambda_{}'.format(x['label']), 'meta': { 'Unit': x['meta']['Unit'], - 'Description': 'Absolute value of {} ({})'.format(x['label'],x['meta']['Description']), - 'Creator': 'dadf5.py:add_abs v{}'.format(version) + 'Description': 'Pricipal components of {} ({})'.format(x['label'],x['meta']['Description']), + 'Creator': 'dadf5.py:add_principal_components v{}'.format(version) } } requested = [{'label':x,'arg':'x'}] - - self.__add_generic_pointwise(__add_absolute,requested) - - def add_determinant(self,x): - """ - Add the determinant of a tensor. - - Parameters - ---------- - x : str - Label of the dataset containing a tensor. - - """ - def __add_determinant(x): - - return { - 'data': np.linalg.det(x['data']), - 'label': 'det({})'.format(x['label']), - 'meta': { - 'Unit': x['meta']['Unit'], - 'Description': 'Determinant of tensor {} ({})'.format(x['label'],x['meta']['Description']), - 'Creator': 'dadf5.py:add_determinant v{}'.format(version) - } - } - - requested = [{'label':x,'arg':'x'}] - - self.__add_generic_pointwise(__add_determinant,requested) + self.__add_generic_pointwise(__add_principal_components,requested) def add_spherical(self,x): @@ -624,79 +753,6 @@ class DADF5(): self.__add_generic_pointwise(__add_spherical,requested) - def add_deviator(self,x): - """ - Add the deviatoric part of a tensor. - - Parameters - ---------- - x : str - Label of the dataset containing a tensor. - - """ - def __add_deviator(x): - - if not np.all(np.array(x['data'].shape[1:]) == np.array([3,3])): - raise ValueError - - return { - 'data': mechanics.deviatoric_part(x['data']), - 'label': 's_{}'.format(x['label']), - 'meta': { - 'Unit': x['meta']['Unit'], - 'Description': 'Deviator of tensor {} ({})'.format(x['label'],x['meta']['Description']), - 'Creator': 'dadf5.py:add_deviator v{}'.format(version) - } - } - - requested = [{'label':x,'arg':'x'}] - - self.__add_generic_pointwise(__add_deviator,requested) - - - def add_calculation(self,formula,label,unit='n/a',description=None,vectorized=True): - """ - Add result of a general formula. - - Parameters - ---------- - formula : str - Formula, refer to datasets by ‘#Label#‘. - label : str - Label of the dataset containing the result of the calculation. - unit : str, optional - Physical unit of the result. - description : str, optional - Human readable description of the result. - vectorized : bool, optional - Indicate whether the formula is written in vectorized form. Default is ‘True’. - - """ - if vectorized is not True: - raise NotImplementedError - - def __add_calculation(**kwargs): - - formula = kwargs['formula'] - for d in re.findall(r'#(.*?)#',formula): - formula = formula.replace('#{}#'.format(d),"kwargs['{}']['data']".format(d)) - - return { - 'data': eval(formula), - 'label': kwargs['label'], - 'meta': { - 'Unit': kwargs['unit'], - 'Description': '{} (formula: {})'.format(kwargs['description'],kwargs['formula']), - 'Creator': 'dadf5.py:add_calculation v{}'.format(version) - } - } - - requested = [{'label':d,'arg':d} for d in set(re.findall(r'#(.*?)#',formula))] # datasets used in the formula - pass_through = {'formula':formula,'label':label,'unit':unit,'description':description} - - self.__add_generic_pointwise(__add_calculation,requested,pass_through) - - def add_strain_tensor(self,F='F',t='U',m=0): """ Add strain tensor calculated from a deformation gradient. @@ -729,62 +785,6 @@ class DADF5(): requested = [{'label':F,'arg':'F'}] self.__add_generic_pointwise(__add_strain_tensor,requested,{'t':t,'m':m}) - - - def add_principal_components(self,x): - """ - Add principal components of symmetric tensor. - - The principal components are sorted in descending order, each repeated according to its multiplicity. - - Parameters - ---------- - x : str - Label of the dataset containing a symmetric tensor. - - """ - def __add_principal_components(x): - - return { - 'data': mechanics.principal_components(x['data']), - 'label': 'lambda_{}'.format(x['label']), - 'meta': { - 'Unit': x['meta']['Unit'], - 'Description': 'Pricipal components of {} ({})'.format(x['label'],x['meta']['Description']), - 'Creator': 'dadf5.py:add_principal_components v{}'.format(version) - } - } - - requested = [{'label':x,'arg':'x'}] - - self.__add_generic_pointwise(__add_principal_components,requested) - - - def add_maximum_shear(self,x): - """ - Add maximum shear components of symmetric tensor. - - Parameters - ---------- - x : str - Label of the dataset containing a symmetric tensor. - - """ - def __add_maximum_shear(x): - - return { - 'data': mechanics.maximum_shear(x['data']), - 'label': 'max_shear({})'.format(x['label']), - 'meta': { - 'Unit': x['meta']['Unit'], - 'Description': 'Maximum shear component of of {} ({})'.format(x['label'],x['meta']['Description']), - 'Creator': 'dadf5.py:add_maximum_shear v{}'.format(version) - } - } - - requested = [{'label':x,'arg':'x'}] - - self.__add_generic_pointwise(__add_maximum_shear,requested) def __add_generic_pointwise(self,func,datasets_requested,extra_args={}): diff --git a/python/tests/test_DADF5.py b/python/tests/test_DADF5.py index 2235321b5..8aa8ec174 100644 --- a/python/tests/test_DADF5.py +++ b/python/tests/test_DADF5.py @@ -28,14 +28,15 @@ class TestDADF5: shape = default.read_dataset(default.get_dataset_location('F'),0).shape default.set_by_time(0.0,20.0) for i in default.iter_visible('increments'): - assert shape == default.read_dataset(default.get_dataset_location('F'),0).shape + assert shape == default.read_dataset(default.get_dataset_location('F'),0).shape - def test_add_deviator(self,default): - default.add_deviator('P') - loc = {'P' :default.get_dataset_location('P'), - 's_P':default.get_dataset_location('s_P')} - in_memory = mechanics.deviatoric_part(default.read_dataset(loc['P'],0)) - in_file = default.read_dataset(loc['s_P'],0) + + def test_add_absolute(self,default): + default.add_absolute('Fe') + loc = {'Fe': default.get_dataset_location('Fe'), + '|Fe|': default.get_dataset_location('|Fe|')} + in_memory = np.abs(default.read_dataset(loc['Fe'],0)) + in_file = default.read_dataset(loc['|Fe|'],0) assert np.allclose(in_memory,in_file) def test_add_Cauchy(self,default): @@ -52,10 +53,18 @@ class TestDADF5: default.add_determinant('P') loc = {'P': default.get_dataset_location('P'), 'det(P)':default.get_dataset_location('det(P)')} - in_memory = np.linalg.det(default.read_dataset(loc['P'],0)) + in_memory = np.linalg.det(default.read_dataset(loc['P'],0)).reshape((-1,1)) in_file = default.read_dataset(loc['det(P)'],0) assert np.allclose(in_memory,in_file) + def test_add_deviator(self,default): + default.add_deviator('P') + loc = {'P' :default.get_dataset_location('P'), + 's_P':default.get_dataset_location('s_P')} + in_memory = mechanics.deviatoric_part(default.read_dataset(loc['P'],0)) + in_file = default.read_dataset(loc['s_P'],0) + assert np.allclose(in_memory,in_file) + def test_add_norm(self,default): default.add_norm('F',1) loc = {'F': default.get_dataset_location('F'), @@ -64,14 +73,6 @@ class TestDADF5: in_file = default.read_dataset(loc['|F|_1'],0) assert np.allclose(in_memory,in_file) - def test_add_absolute(self,default): - default.add_absolute('Fe') - loc = {'Fe': default.get_dataset_location('Fe'), - '|Fe|': default.get_dataset_location('|Fe|')} - in_memory = np.abs(default.read_dataset(loc['Fe'],0)) - in_file = default.read_dataset(loc['|Fe|'],0) - assert np.allclose(in_memory,in_file) - def test_add_spherical(self,default): default.add_spherical('P') loc = {'P': default.get_dataset_location('P'), From cb0d39eee6cb806e14eb2b3382a24611a4162ed5 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 4 Dec 2019 19:00:56 +0100 Subject: [PATCH 21/78] not needed anymore --- src/plastic_nonlocal.f90 | 40 +++++++++++++++++----------------------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/src/plastic_nonlocal.f90 b/src/plastic_nonlocal.f90 index 5469515dc..5a3f8c173 100644 --- a/src/plastic_nonlocal.f90 +++ b/src/plastic_nonlocal.f90 @@ -24,13 +24,10 @@ module plastic_nonlocal implicit none private - real(pReal), parameter, private :: & + real(pReal), parameter :: & KB = 1.38e-23_pReal !< Physical parameter, Boltzmann constant in J/Kelvin - - integer, dimension(:,:), allocatable, target, public :: & - plastic_nonlocal_sizePostResult !< size of each post result output - character(len=64), dimension(:,:), allocatable, target, public :: & + character(len=64), dimension(:,:), allocatable :: & plastic_nonlocal_output !< name of each post result output @@ -54,18 +51,18 @@ module plastic_nonlocal mob_scr_neg = 4 !< mobile screw positive ! BEGIN DEPRECATES - integer, dimension(:,:,:), allocatable, private :: & + integer, dimension(:,:,:), allocatable :: & iRhoU, & !< state indices for unblocked density iRhoB, & !< state indices for blocked density iRhoD, & !< state indices for dipole density iV, & !< state indices for dislcation velocities iD !< state indices for stable dipole height - integer, dimension(:), allocatable, private, protected :: & + integer, dimension(:), allocatable :: & totalNslip !< total number of active slip systems for each instance !END DEPRECATED - real(pReal), dimension(:,:,:,:,:,:), allocatable, private :: & - compatibility !< slip system compatibility between me and my neighbors + real(pReal), dimension(:,:,:,:,:,:), allocatable :: & + compatibility !< slip system compatibility between me and my neighbors enum, bind(c) enumerator :: & @@ -93,7 +90,7 @@ module plastic_nonlocal gamma_ID end enum - type, private :: tParameters !< container type for internal constitutive parameters + type :: tParameters !< container type for internal constitutive parameters real(pReal) :: & atomicVolume, & !< atomic volume Dsd0, & !< prefactor for self-diffusion coefficient @@ -143,19 +140,19 @@ module plastic_nonlocal interactionSlipSlip ,& !< coefficients for slip-slip interaction forestProjection_Edge, & !< matrix of forest projections of edge dislocations forestProjection_Screw !< matrix of forest projections of screw dislocations - real(pReal), dimension(:), allocatable, private :: & + real(pReal), dimension(:), allocatable :: & nonSchmidCoeff - real(pReal), dimension(:,:,:), allocatable, private :: & + real(pReal), dimension(:,:,:), allocatable :: & Schmid, & !< Schmid contribution nonSchmid_pos, & nonSchmid_neg !< combined projection of Schmid and non-Schmid contributions to the resolved shear stress (only for screws) integer :: & totalNslip - integer, dimension(:) ,allocatable , public:: & + integer, dimension(:) ,allocatable :: & Nslip,& colinearSystem !< colinear system to the active slip system (only valid for fcc!) - logical, private :: & + logical :: & shortRangeStressCorrection, & !< flag indicating the use of the short range stress correction by a excess density gradient term probabilisticMultiplication @@ -164,13 +161,13 @@ module plastic_nonlocal end type tParameters - type, private :: tNonlocalMicrostructure + type :: tNonlocalMicrostructure real(pReal), allocatable, dimension(:,:) :: & tau_pass, & tau_Back end type tNonlocalMicrostructure - type, private :: tNonlocalState + type :: tNonlocalState real(pReal), pointer, dimension(:,:) :: & rho, & ! < all dislocations rhoSgl, & @@ -196,16 +193,16 @@ module plastic_nonlocal v_scr_neg end type tNonlocalState - type(tNonlocalState), allocatable, dimension(:), private :: & + type(tNonlocalState), allocatable, dimension(:) :: & deltaState, & dotState, & state - type(tParameters), dimension(:), allocatable, private :: param !< containers of constitutive parameters (len Ninstance) + type(tParameters), dimension(:), allocatable :: param !< containers of constitutive parameters (len Ninstance) - type(tNonlocalMicrostructure), dimension(:), allocatable, private :: microstructure + type(tNonlocalMicrostructure), dimension(:), allocatable :: microstructure - integer(kind(undefined_ID)), dimension(:,:), allocatable, private :: & + integer(kind(undefined_ID)), dimension(:,:), allocatable :: & plastic_nonlocal_outputID !< ID of each post result output public :: & @@ -268,7 +265,6 @@ subroutine plastic_nonlocal_init allocate(deltaState(maxNinstances)) allocate(microstructure(maxNinstances)) - allocate(plastic_nonlocal_sizePostResult(maxval(phase_Noutput), maxNinstances), source=0) allocate(plastic_nonlocal_output(maxval(phase_Noutput), maxNinstances)) plastic_nonlocal_output = '' allocate(plastic_nonlocal_outputID(maxval(phase_Noutput), maxNinstances), source=undefined_ID) @@ -498,7 +494,6 @@ subroutine plastic_nonlocal_init if (outputID /= undefined_ID) then plastic_nonlocal_output(i,phase_plasticityInstance(p)) = outputs(i) - plastic_nonlocal_sizePostResult(i,phase_plasticityInstance(p)) = prm%totalNslip prm%outputID = [prm%outputID , outputID] endif @@ -524,7 +519,6 @@ subroutine plastic_nonlocal_init prm%totalNslip,0,0) plasticState(p)%nonlocal = .true. plasticState(p)%offsetDeltaState = 0 ! ToDo: state structure does not follow convention - plasticState(p)%sizePostResults = sum(plastic_nonlocal_sizePostResult(:,phase_plasticityInstance(p))) totalNslip(phase_plasticityInstance(p)) = prm%totalNslip From 137b235bc1d95e5fc13ea9acd487296cc097c055 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 7 Dec 2019 11:06:39 +0100 Subject: [PATCH 22/78] i0 format specifier easier then hand-written IO_intOut using variable pStringLen allows string assignment without length issues --- src/config.f90 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/config.f90 b/src/config.f90 index 00b473767..cffa9f644 100644 --- a/src/config.f90 +++ b/src/config.f90 @@ -27,7 +27,7 @@ module config config_numerics, & config_debug - character(len=64), dimension(:), allocatable, public, protected :: & + character(len=pStringLen), dimension(:), allocatable, public, protected :: & config_name_phase, & !< name of each phase config_name_homogenization, & !< name of each homogenization config_name_crystallite, & !< name of each crystallite setting @@ -54,7 +54,7 @@ subroutine config_init character(len=pStringLen), dimension(:), allocatable :: fileContent logical :: fileExists - write(6,'(/,a)') ' <<<+- config init -+>>>' + write(6,'(/,a)') ' <<<+- config init -+>>>'; flush(6) verbose = iand(debug_level(debug_material),debug_levelBasic) /= 0 @@ -214,7 +214,7 @@ end function read_materialConfig subroutine parse_materialConfig(sectionNames,part,line, & fileContent) - character(len=64), allocatable, dimension(:), intent(out) :: sectionNames + character(len=pStringLen), allocatable, dimension(:), intent(out) :: sectionNames type(tPartitionedStringList), allocatable, dimension(:), intent(inout) :: part character(len=pStringLen), intent(inout) :: line character(len=pStringLen), dimension(:), intent(in) :: fileContent @@ -222,7 +222,7 @@ subroutine parse_materialConfig(sectionNames,part,line, & integer, allocatable, dimension(:) :: partPosition !< position of [] tags + last line in section integer :: i, j logical :: echo - character(len=pStringLen) :: section_ID + character(len=pStringLen) :: sectionName echo = .false. @@ -246,8 +246,8 @@ subroutine parse_materialConfig(sectionNames,part,line, & partPosition = [partPosition, i] ! needed when actually storing content do i = 1, size(partPosition) -1 - write(section_ID,'('//IO_intOut(size(partPosition))//')') i - sectionNames(i) = trim(section_ID)//'_'//trim(adjustl(IO_getTag(fileContent(partPosition(i)),'[',']'))) + write(sectionName,'(i0,a,a)') i,'_',trim(IO_getTag(fileContent(partPosition(i)),'[',']')) + sectionNames(i) = sectionName do j = partPosition(i) + 1, partPosition(i+1) -1 call part(i)%add(trim(adjustl(fileContent(j)))) enddo From 7ecb0245ec030bcca7e48e1f3075330ae0a614f4 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 7 Dec 2019 11:10:48 +0100 Subject: [PATCH 23/78] simplified (use novel i0 format specifier) --- src/IO.f90 | 1 + src/grid/DAMASK_grid.f90 | 11 ++--------- src/mesh/DAMASK_FEM.f90 | 11 ++--------- 3 files changed, 5 insertions(+), 18 deletions(-) diff --git a/src/IO.f90 b/src/IO.f90 index a585fc7c4..8973860c2 100644 --- a/src/IO.f90 +++ b/src/IO.f90 @@ -544,6 +544,7 @@ end function IO_lc !-------------------------------------------------------------------------------------------------- !> @brief returns format string for integer values without leading zeros +!> @details deprecated, use '(i0)' format specifier !-------------------------------------------------------------------------------------------------- pure function IO_intOut(intToPrint) diff --git a/src/grid/DAMASK_grid.f90 b/src/grid/DAMASK_grid.f90 index e83cf3283..b6b415b5e 100644 --- a/src/grid/DAMASK_grid.f90 +++ b/src/grid/DAMASK_grid.f90 @@ -443,19 +443,12 @@ program DAMASK_spectral !-------------------------------------------------------------------------------------------------- ! report begin of new step write(6,'(/,a)') ' ###########################################################################' - write(6,'(1x,a,es12.5'//& - ',a,'//IO_intOut(inc) //',a,'//IO_intOut(loadCases(currentLoadCase)%incs)//& - ',a,'//IO_intOut(stepFraction) //',a,'//IO_intOut(subStepFactor**cutBackLevel)//& - ',a,'//IO_intOut(currentLoadCase)//',a,'//IO_intOut(size(loadCases))//')') & + write(6,'(1x,a,es12.5,6(a,i0))') & 'Time', time, & 's: Increment ', inc,'/',loadCases(currentLoadCase)%incs,& '-', stepFraction,'/',subStepFactor**cutBackLevel,& ' of load case ', currentLoadCase,'/',size(loadCases) - write(incInfo,& - '(a,'//IO_intOut(totalIncsCounter)//& - ',a,'//IO_intOut(sum(loadCases%incs))//& - ',a,'//IO_intOut(stepFraction)//& - ',a,'//IO_intOut(subStepFactor**cutBackLevel)//')') & + write(incInfo,'(4(a,i0))') & 'Increment ',totalIncsCounter,'/',sum(loadCases%incs),& '-', stepFraction,'/',subStepFactor**cutBackLevel flush(6) diff --git a/src/mesh/DAMASK_FEM.f90 b/src/mesh/DAMASK_FEM.f90 index 3d4c332a0..5ebcbe217 100644 --- a/src/mesh/DAMASK_FEM.f90 +++ b/src/mesh/DAMASK_FEM.f90 @@ -296,19 +296,12 @@ program DAMASK_FEM !-------------------------------------------------------------------------------------------------- ! report begin of new step write(6,'(/,a)') ' ###########################################################################' - write(6,'(1x,a,es12.5'//& - ',a,'//IO_intOut(inc)//',a,'//IO_intOut(loadCases(currentLoadCase)%incs)//& - ',a,'//IO_intOut(stepFraction)//',a,'//IO_intOut(subStepFactor**cutBackLevel)//& - ',a,'//IO_intOut(currentLoadCase)//',a,'//IO_intOut(size(loadCases))//')') & + write(6,'(1x,a,es12.5,6(a,i0))')& 'Time', time, & 's: Increment ', inc, '/', loadCases(currentLoadCase)%incs,& '-', stepFraction, '/', subStepFactor**cutBackLevel,& ' of load case ', currentLoadCase,'/',size(loadCases) - write(incInfo,& - '(a,'//IO_intOut(totalIncsCounter)//& - ',a,'//IO_intOut(sum(loadCases%incs))//& - ',a,'//IO_intOut(stepFraction)//& - ',a,'//IO_intOut(subStepFactor**cutBackLevel)//')') & + write(incInfo,'(4(a,i0))') & 'Increment ',totalIncsCounter,'/',sum(loadCases%incs),& '-',stepFraction, '/', subStepFactor**cutBackLevel flush(6) From 0f4f415c5be0ce182c4608eab98dae8f1471f847 Mon Sep 17 00:00:00 2001 From: Test User Date: Sat, 7 Dec 2019 13:47:55 +0100 Subject: [PATCH 24/78] [skip ci] updated version information after successful test of v2.0.3-1218-g5a6111ec --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index ae832e588..88e96b85c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v2.0.3-1177-ga41871e2 +v2.0.3-1218-g5a6111ec From 23944de6de8d0ae0882c17c74fc80f64d847ecbc Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 7 Dec 2019 15:20:04 +0100 Subject: [PATCH 25/78] less variables for better readability --- src/CPFEM2.f90 | 98 ++++++++++++++++++++++++-------------------------- 1 file changed, 46 insertions(+), 52 deletions(-) diff --git a/src/CPFEM2.f90 b/src/CPFEM2.f90 index 7123602f8..4575b9caa 100644 --- a/src/CPFEM2.f90 +++ b/src/CPFEM2.f90 @@ -42,7 +42,7 @@ contains !-------------------------------------------------------------------------------------------------- -!> @brief call (thread safe) all module initializations +!> @brief call all module initializations !-------------------------------------------------------------------------------------------------- subroutine CPFEM_initAll @@ -70,29 +70,24 @@ subroutine CPFEM_initAll end subroutine CPFEM_initAll + !-------------------------------------------------------------------------------------------------- !> @brief allocate the arrays defined in module CPFEM and initialize them !-------------------------------------------------------------------------------------------------- subroutine CPFEM_init - integer :: ph,homog - character(len=1024) :: rankStr, PlasticItem, HomogItem - integer(HID_T) :: fileHandle, groupPlasticID, groupHomogID + integer :: i + integer(HID_T) :: fileHandle, groupHandle + character(len=pStringLen) :: fileName, datasetName - write(6,'(/,a)') ' <<<+- CPFEM init -+>>>' - flush(6) + write(6,'(/,a)') ' <<<+- CPFEM init -+>>>'; flush(6) - ! *** restore the last converged values of each essential variable if (interface_restartInc > 0) then - if (iand(debug_level(debug_CPFEM), debug_levelExtensive) /= 0) then - write(6,'(a)') '<< CPFEM >> restored state variables of last converged step from hdf5 file' - flush(6) - endif - - write(rankStr,'(a1,i0)')'_',worldrank + write(6,'(/,a,i0,a)') ' reading restart information of increment ', interface_restartInc, ' from file' - fileHandle = HDF5_openFile(trim(getSolverJobName())//trim(rankStr)//'.hdf5') - + write(fileName,'(a,i0,a)') trim(getSolverJobName())//'_',worldrank,'.hdf5' + fileHandle = HDF5_openFile(fileName) + call HDF5_read(fileHandle,crystallite_F0, 'F') call HDF5_read(fileHandle,crystallite_Fp0,'Fp') call HDF5_read(fileHandle,crystallite_Fi0,'Fi') @@ -100,19 +95,19 @@ subroutine CPFEM_init call HDF5_read(fileHandle,crystallite_Li0,'Li') call HDF5_read(fileHandle,crystallite_S0, 'S') - groupPlasticID = HDF5_openGroup(fileHandle,'constituent') - do ph = 1,size(phase_plasticity) - write(PlasticItem,*) ph,'_' - call HDF5_read(groupPlasticID,plasticState(ph)%state0,trim(PlasticItem)//'omega_plastic') + groupHandle = HDF5_openGroup(fileHandle,'constituent') + do i = 1,size(phase_plasticity) + write(datasetName,'(i0,a)') i,'_omega_plastic' + call HDF5_read(groupHandle,plasticState(i)%state,datasetName) enddo - call HDF5_closeGroup(groupPlasticID) - - groupHomogID = HDF5_openGroup(fileHandle,'materialpoint') - do homog = 1, material_Nhomogenization - write(HomogItem,*) homog,'_' - call HDF5_read(groupHomogID,homogState(homog)%state0, trim(HomogItem)//'omega_homogenization') + call HDF5_closeGroup(groupHandle) + + groupHandle = HDF5_openGroup(fileHandle,'materialpoint') + do i = 1, material_Nhomogenization + write(datasetName,'(i0,a)') i,'_omega_homogenization' + call HDF5_read(groupHandle,homogState(i)%state,datasetName) enddo - call HDF5_closeGroup(groupHomogID) + call HDF5_closeGroup(groupHandle) call HDF5_closeFile(fileHandle) endif @@ -126,7 +121,7 @@ end subroutine CPFEM_init !-------------------------------------------------------------------------------------------------- subroutine CPFEM_forward - integer :: i, homog, mySource + integer :: i, j if (iand(debug_level(debug_CPFEM), debug_levelBasic) /= 0) & write(6,'(a)') '<< CPFEM >> aging states' @@ -142,32 +137,31 @@ subroutine CPFEM_forward plasticState(i)%state0 = plasticState(i)%state enddo do i = 1, size(sourceState) - do mySource = 1,phase_Nsources(i) - sourceState(i)%p(mySource)%state0 = sourceState(i)%p(mySource)%state + do j = 1,phase_Nsources(i) + sourceState(i)%p(j)%state0 = sourceState(i)%p(j)%state enddo; enddo - do homog = 1, material_Nhomogenization - homogState (homog)%state0 = homogState (homog)%state - thermalState (homog)%state0 = thermalState (homog)%state - damageState (homog)%state0 = damageState (homog)%state + do i = 1, material_Nhomogenization + homogState (i)%state0 = homogState (i)%state + thermalState(i)%state0 = thermalState(i)%state + damageState (i)%state0 = damageState (i)%state enddo end subroutine CPFEM_forward !-------------------------------------------------------------------------------------------------- -!> @brief Write current constitutive variables for restart to file. +!> @brief Write current restart information (Field and constitutive data) to file. !-------------------------------------------------------------------------------------------------- subroutine CPFEM_restartWrite - integer :: ph, homog - character(len=32) :: rankStr, PlasticItem, HomogItem - integer(HID_T) :: fileHandle, groupPlastic, groupHomog + integer :: i + integer(HID_T) :: fileHandle, groupHandle + character(len=pStringLen) :: fileName, datasetName - - write(6,'(a)') ' writing constitutive data required for restart to file';flush(6) + write(6,'(a)') ' writing field and constitutive data required for restart to file';flush(6) - write(rankStr,'(a1,i0)')'_',worldrank - fileHandle = HDF5_openFile(trim(getSolverJobName())//trim(rankStr)//'.hdf5','a') + write(fileName,'(a,i0,a)') trim(getSolverJobName())//'_',worldrank,'.hdf5' + fileHandle = HDF5_openFile(fileName,'a') call HDF5_write(fileHandle,crystallite_partionedF,'F') call HDF5_write(fileHandle,crystallite_Fp, 'Fp') @@ -176,19 +170,19 @@ subroutine CPFEM_restartWrite call HDF5_write(fileHandle,crystallite_Li, 'Li') call HDF5_write(fileHandle,crystallite_S, 'S') - groupPlastic = HDF5_addGroup(fileHandle,'constituent') - do ph = 1,size(phase_plasticity) - write(PlasticItem,*) ph,'_' - call HDF5_write(groupPlastic,plasticState(ph)%state,trim(PlasticItem)//'omega_plastic') + groupHandle = HDF5_addGroup(fileHandle,'constituent') + do i = 1,size(phase_plasticity) + write(datasetName,'(i0,a)') i,'_omega_plastic' + call HDF5_write(groupHandle,plasticState(i)%state,datasetName) enddo - call HDF5_closeGroup(groupPlastic) + call HDF5_closeGroup(groupHandle) - groupHomog = HDF5_addGroup(fileHandle,'materialpoint') - do homog = 1, material_Nhomogenization - write(HomogItem,*) homog,'_' - call HDF5_write(groupHomog,homogState(homog)%state,trim(HomogItem)//'omega_homogenization') + groupHandle = HDF5_addGroup(fileHandle,'materialpoint') + do i = 1, material_Nhomogenization + write(datasetName,'(i0,a)') i,'_omega_homogenization' + call HDF5_write(groupHandle,homogState(i)%state,datasetName) enddo - call HDF5_closeGroup(groupHomog) + call HDF5_closeGroup(groupHandle) call HDF5_closeFile(fileHandle) @@ -209,7 +203,7 @@ subroutine CPFEM_results(inc,time) call crystallite_results call homogenization_results call discretization_results - call results_removeLink('current') ! ToDo: put this into closeJobFile + call results_removeLink('current') ! ToDo: put this into closeJobFile? call results_closeJobFile end subroutine CPFEM_results From 4eacc1d16d08f942b28c823a39aed1a15ef27617 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 7 Dec 2019 15:24:45 +0100 Subject: [PATCH 26/78] polishing --- src/grid/DAMASK_grid.f90 | 8 ++--- src/grid/grid_mech_FEM.f90 | 34 +++++++++----------- src/grid/grid_mech_spectral_basic.f90 | 32 +++++++++--------- src/grid/grid_mech_spectral_polarisation.f90 | 34 +++++++++----------- src/grid/spectral_utilities.f90 | 2 +- src/mesh/DAMASK_FEM.f90 | 8 ++--- 6 files changed, 54 insertions(+), 64 deletions(-) diff --git a/src/grid/DAMASK_grid.f90 b/src/grid/DAMASK_grid.f90 index b6b415b5e..45e62bab7 100644 --- a/src/grid/DAMASK_grid.f90 +++ b/src/grid/DAMASK_grid.f90 @@ -105,7 +105,7 @@ program DAMASK_spectral !-------------------------------------------------------------------------------------------------- ! init DAMASK (all modules) call CPFEM_initAll - write(6,'(/,a)') ' <<<+- DAMASK_spectral init -+>>>' + write(6,'(/,a)') ' <<<+- DAMASK_spectral init -+>>>'; flush(6) write(6,'(/,a)') ' Shanthraj et al., Handbook of Mechanics of Materials, 2019' write(6,'(a)') ' https://doi.org/10.1007/978-981-10-6855-3_80' @@ -533,11 +533,9 @@ program DAMASK_spectral cutBackLevel = max(0, cutBackLevel - 1) ! try half number of subincs next inc if (all(solres(:)%converged)) then - write(6,'(/,a,'//IO_intOut(totalIncsCounter)//',a)') & ! report converged inc - ' increment ', totalIncsCounter, ' converged' + write(6,'(/,a,i0,a)') ' increment ', totalIncsCounter, ' converged' else - write(6,'(/,a,'//IO_intOut(totalIncsCounter)//',a)') & ! report non-converged inc - ' increment ', totalIncsCounter, ' NOT converged' + write(6,'(/,a,i0,a)') ' increment ', totalIncsCounter, ' NOT converged' endif; flush(6) if (mod(inc,loadCases(currentLoadCase)%outputFrequency) == 0) then ! at output frequency diff --git a/src/grid/grid_mech_FEM.f90 b/src/grid/grid_mech_FEM.f90 index 0c3844fcf..1c3447ebd 100644 --- a/src/grid/grid_mech_FEM.f90 +++ b/src/grid/grid_mech_FEM.f90 @@ -96,15 +96,15 @@ subroutine grid_mech_FEM_init 1.0_pReal,-1.0_pReal,-1.0_pReal,-1.0_pReal, & 1.0_pReal, 1.0_pReal, 1.0_pReal, 1.0_pReal], [4,8]) PetscErrorCode :: ierr - integer :: rank - integer(HID_T) :: fileHandle, groupHandle - character(len=1024) :: rankStr + integer :: rank + integer(HID_T) :: fileHandle, groupHandle + character(len=pStringLen) :: fileName real(pReal), dimension(3,3,3,3) :: devNull PetscScalar, pointer, dimension(:,:,:,:) :: & u_current,u_lastInc - write(6,'(/,a)') ' <<<+- grid_mech_FEM init -+>>>' - + write(6,'(/,a)') ' <<<+- grid_mech_FEM init -+>>>'; flush(6) + !-------------------------------------------------------------------------------------------------- ! set default and user defined options for PETSc call PETScOptionsInsertString(PETSC_NULL_OPTIONS,'-mech_snes_type newtonls -mech_ksp_type fgmres & @@ -184,11 +184,10 @@ subroutine grid_mech_FEM_init !-------------------------------------------------------------------------------------------------- ! init fields restartRead: if (interface_restartInc > 0) then - write(6,'(/,a,'//IO_intOut(interface_restartInc)//',a)') & - 'reading values of increment ', interface_restartInc, ' from file' + write(6,'(/,a,i0,a)') ' reading restart data of increment ', interface_restartInc, ' from file' - write(rankStr,'(a1,i0)')'_',worldrank - fileHandle = HDF5_openFile(trim(getSolverJobName())//trim(rankStr)//'.hdf5') + write(fileName,'(a,a,i0,a)') trim(getSolverJobName()),'_',worldrank,'.hdf5' + fileHandle = HDF5_openFile(fileName) groupHandle = HDF5_openGroup(fileHandle,'solver') call HDF5_read(groupHandle,F_aim, 'F_aim') @@ -215,8 +214,7 @@ subroutine grid_mech_FEM_init CHKERRQ(ierr) restartRead2: if (interface_restartInc > 0) then - write(6,'(/,a,'//IO_intOut(interface_restartInc)//',a)') & - 'reading more values of increment ', interface_restartInc, ' from file' + write(6,'(/,a,i0,a)') ' reading more restart data of increment ', interface_restartInc, ' from file' call HDF5_read(groupHandle,C_volAvg, 'C_volAvg') call HDF5_read(groupHandle,C_volAvgLastInc,'C_volAvgLastInc') @@ -355,7 +353,7 @@ end subroutine grid_mech_FEM_forward !-------------------------------------------------------------------------------------------------- !> @brief Age !-------------------------------------------------------------------------------------------------- -subroutine grid_mech_FEM_updateCoords() +subroutine grid_mech_FEM_updateCoords call utilities_updateCoords(F) @@ -365,20 +363,20 @@ end subroutine grid_mech_FEM_updateCoords !-------------------------------------------------------------------------------------------------- !> @brief Write current solver and constitutive data for restart to file !-------------------------------------------------------------------------------------------------- -subroutine grid_mech_FEM_restartWrite() +subroutine grid_mech_FEM_restartWrite PetscErrorCode :: ierr + integer(HID_T) :: fileHandle, groupHandle PetscScalar, dimension(:,:,:,:), pointer :: u_current,u_lastInc - integer(HID_T) :: fileHandle, groupHandle - character(len=32) :: rankStr + character(len=pStringLen) :: fileName call DMDAVecGetArrayF90(mech_grid,solution_current,u_current,ierr); CHKERRQ(ierr) call DMDAVecGetArrayF90(mech_grid,solution_lastInc,u_lastInc,ierr); CHKERRQ(ierr) - write(6,'(a)') ' writing solver data required for restart to file';flush(6) + write(6,'(a)') ' writing solver data required for restart to file'; flush(6) - write(rankStr,'(a1,i0)')'_',worldrank - fileHandle = HDF5_openFile(trim(getSolverJobName())//trim(rankStr)//'.hdf5','w') + write(fileName,'(a,a,i0,a)') trim(getSolverJobName()),'_',worldrank,'.hdf5' + fileHandle = HDF5_openFile(fileName,'w') groupHandle = HDF5_addGroup(fileHandle,'solver') call HDF5_write(groupHandle,F_aim, 'F_aim') diff --git a/src/grid/grid_mech_spectral_basic.f90 b/src/grid/grid_mech_spectral_basic.f90 index 3dc978dc6..1f61de1a9 100644 --- a/src/grid/grid_mech_spectral_basic.f90 +++ b/src/grid/grid_mech_spectral_basic.f90 @@ -94,11 +94,11 @@ subroutine grid_mech_spectral_basic_init PetscScalar, pointer, dimension(:,:,:,:) :: & F ! pointer to solution data PetscInt, dimension(worldsize) :: localK - integer(HID_T) :: fileHandle, groupHandle - integer :: fileUnit - character(len=1024) :: rankStr + integer(HID_T) :: fileHandle, groupHandle + integer :: fileUnit + character(len=pStringLen) :: fileName - write(6,'(/,a)') ' <<<+- grid_mech_spectral_basic init -+>>>' + write(6,'(/,a)') ' <<<+- grid_mech_spectral_basic init -+>>>'; flush(6) write(6,'(/,a)') ' Eisenlohr et al., International Journal of Plasticity 46:37–53, 2013' write(6,'(a)') ' https://doi.org/10.1016/j.ijplas.2012.09.012' @@ -151,11 +151,10 @@ subroutine grid_mech_spectral_basic_init call DMDAVecGetArrayF90(da,solution_vec,F,ierr); CHKERRQ(ierr) ! places pointer on PETSc data restartRead: if (interface_restartInc > 0) then - write(6,'(/,a,'//IO_intOut(interface_restartInc)//',a)') & - ' reading values of increment ', interface_restartInc, ' from file' + write(6,'(/,a,i0,a)') ' reading restart data of increment ', interface_restartInc, ' from file' - write(rankStr,'(a1,i0)')'_',worldrank - fileHandle = HDF5_openFile(trim(getSolverJobName())//trim(rankStr)//'.hdf5') + write(fileName,'(a,a,i0,a)') trim(getSolverJobName()),'_',worldrank,'.hdf5' + fileHandle = HDF5_openFile(fileName) groupHandle = HDF5_openGroup(fileHandle,'solver') call HDF5_read(groupHandle,F_aim, 'F_aim') @@ -178,8 +177,7 @@ subroutine grid_mech_spectral_basic_init call DMDAVecRestoreArrayF90(da,solution_vec,F,ierr); CHKERRQ(ierr) ! deassociate pointer restartRead2: if (interface_restartInc > 0) then - write(6,'(/,a,'//IO_intOut(interface_restartInc)//',a)') & - 'reading more values of increment ', interface_restartInc, ' from file' + write(6,'(/,a,i0,a)') ' reading more restart data of increment ', interface_restartInc, ' from file' call HDF5_read(groupHandle,C_volAvg, 'C_volAvg') call HDF5_read(groupHandle,C_volAvgLastInc,'C_volAvgLastInc') @@ -320,7 +318,7 @@ end subroutine grid_mech_spectral_basic_forward !-------------------------------------------------------------------------------------------------- !> @brief Age !-------------------------------------------------------------------------------------------------- -subroutine grid_mech_spectral_basic_updateCoords() +subroutine grid_mech_spectral_basic_updateCoords PetscErrorCode :: ierr PetscScalar, dimension(:,:,:,:), pointer :: F @@ -335,19 +333,19 @@ end subroutine grid_mech_spectral_basic_updateCoords !-------------------------------------------------------------------------------------------------- !> @brief Write current solver and constitutive data for restart to file !-------------------------------------------------------------------------------------------------- -subroutine grid_mech_spectral_basic_restartWrite() +subroutine grid_mech_spectral_basic_restartWrite PetscErrorCode :: ierr + integer(HID_T) :: fileHandle, groupHandle PetscScalar, dimension(:,:,:,:), pointer :: F - integer(HID_T) :: fileHandle, groupHandle - character(len=32) :: rankStr + character(len=pStringLen) :: fileName call DMDAVecGetArrayF90(da,solution_vec,F,ierr); CHKERRQ(ierr) - write(6,'(a)') ' writing solver data required for restart to file';flush(6) + write(6,'(a)') ' writing solver data required for restart to file'; flush(6) - write(rankStr,'(a1,i0)')'_',worldrank - fileHandle = HDF5_openFile(trim(getSolverJobName())//trim(rankStr)//'.hdf5','w') + write(fileName,'(a,a,i0,a)') trim(getSolverJobName()),'_',worldrank,'.hdf5' + fileHandle = HDF5_openFile(fileName,'w') groupHandle = HDF5_addGroup(fileHandle,'solver') call HDF5_write(groupHandle,F_aim, 'F_aim') diff --git a/src/grid/grid_mech_spectral_polarisation.f90 b/src/grid/grid_mech_spectral_polarisation.f90 index c1b5d79c9..20ca8d69d 100644 --- a/src/grid/grid_mech_spectral_polarisation.f90 +++ b/src/grid/grid_mech_spectral_polarisation.f90 @@ -102,11 +102,11 @@ subroutine grid_mech_spectral_polarisation_init F, & ! specific (sub)pointer F_tau ! specific (sub)pointer PetscInt, dimension(worldsize) :: localK - integer(HID_T) :: fileHandle, groupHandle - integer :: fileUnit - character(len=1024) :: rankStr + integer(HID_T) :: fileHandle, groupHandle + integer :: fileUnit + character(len=pStringLen) :: fileName - write(6,'(/,a)') ' <<<+- grid_mech_spectral_polarisation init -+>>>' + write(6,'(/,a)') ' <<<+- grid_mech_spectral_polarisation init -+>>>'; flush(6) write(6,'(/,a)') ' Shanthraj et al., International Journal of Plasticity 66:31–45, 2015' write(6,'(a)') ' https://doi.org/10.1016/j.ijplas.2014.02.006' @@ -160,11 +160,10 @@ subroutine grid_mech_spectral_polarisation_init F_tau => FandF_tau(9:17,:,:,:) restartRead: if (interface_restartInc > 0) then - write(6,'(/,a,'//IO_intOut(interface_restartInc)//',a)') & - ' reading values of increment ', interface_restartInc, ' from file' - - write(rankStr,'(a1,i0)')'_',worldrank - fileHandle = HDF5_openFile(trim(getSolverJobName())//trim(rankStr)//'.hdf5') + write(6,'(/,a,i0,a)') ' reading restart data of increment ', interface_restartInc, ' from file' + + write(fileName,'(a,a,i0,a)') trim(getSolverJobName()),'_',worldrank,'.hdf5' + fileHandle = HDF5_openFile(fileName) groupHandle = HDF5_openGroup(fileHandle,'solver') call HDF5_read(groupHandle,F_aim, 'F_aim') @@ -191,8 +190,7 @@ subroutine grid_mech_spectral_polarisation_init call DMDAVecRestoreArrayF90(da,solution_vec,FandF_tau,ierr); CHKERRQ(ierr) ! deassociate pointer restartRead2: if (interface_restartInc > 0) then - write(6,'(/,a,'//IO_intOut(interface_restartInc)//',a)') & - ' reading more values of increment ', interface_restartInc, ' from file' + write(6,'(/,a,i0,a)') ' reading more restart data of increment ', interface_restartInc, ' from file' call HDF5_read(groupHandle,C_volAvg, 'C_volAvg') call HDF5_read(groupHandle,C_volAvgLastInc,'C_volAvgLastInc') @@ -363,7 +361,7 @@ end subroutine grid_mech_spectral_polarisation_forward !-------------------------------------------------------------------------------------------------- !> @brief Age !-------------------------------------------------------------------------------------------------- -subroutine grid_mech_spectral_polarisation_updateCoords() +subroutine grid_mech_spectral_polarisation_updateCoords PetscErrorCode :: ierr PetscScalar, dimension(:,:,:,:), pointer :: FandF_tau @@ -378,21 +376,21 @@ end subroutine grid_mech_spectral_polarisation_updateCoords !-------------------------------------------------------------------------------------------------- !> @brief Write current solver and constitutive data for restart to file !-------------------------------------------------------------------------------------------------- -subroutine grid_mech_spectral_polarisation_restartWrite() +subroutine grid_mech_spectral_polarisation_restartWrite PetscErrorCode :: ierr + integer(HID_T) :: fileHandle, groupHandle PetscScalar, dimension(:,:,:,:), pointer :: FandF_tau, F, F_tau - integer(HID_T) :: fileHandle, groupHandle - character(len=32) :: rankStr + character(len=pStringLen) :: fileName call DMDAVecGetArrayF90(da,solution_vec,FandF_tau,ierr); CHKERRQ(ierr) F => FandF_tau(0: 8,:,:,:) F_tau => FandF_tau(9:17,:,:,:) - write(6,'(a)') ' writing solver data required for restart to file';flush(6) + write(6,'(a)') ' writing solver data required for restart to file'; flush(6) - write(rankStr,'(a1,i0)')'_',worldrank - fileHandle = HDF5_openFile(trim(getSolverJobName())//trim(rankStr)//'.hdf5','w') + write(fileName,'(a,a,i0,a)') trim(getSolverJobName()),'_',worldrank,'.hdf5' + fileHandle = HDF5_openFile(fileName,'w') groupHandle = HDF5_addGroup(fileHandle,'solver') call HDF5_write(groupHandle,F_aim, 'F_aim') diff --git a/src/grid/spectral_utilities.f90 b/src/grid/spectral_utilities.f90 index 8b0e430f3..6aba32c76 100644 --- a/src/grid/spectral_utilities.f90 +++ b/src/grid/spectral_utilities.f90 @@ -1119,7 +1119,7 @@ subroutine utilities_saveReferenceStiffness fileUnit if (worldrank == 0) then - write(6,'(a)') ' writing reference stiffness data required for restart to file';flush(6) + write(6,'(a)') ' writing reference stiffness data required for restart to file'; flush(6) fileUnit = IO_open_jobFile_binary('C_ref','w') write(fileUnit) C_ref close(fileUnit) diff --git a/src/mesh/DAMASK_FEM.f90 b/src/mesh/DAMASK_FEM.f90 index 5ebcbe217..cd0bcacb1 100644 --- a/src/mesh/DAMASK_FEM.f90 +++ b/src/mesh/DAMASK_FEM.f90 @@ -73,7 +73,7 @@ program DAMASK_FEM !-------------------------------------------------------------------------------------------------- ! init DAMASK (all modules) call CPFEM_initAll - write(6,'(/,a)') ' <<<+- DAMASK_FEM init -+>>>' + write(6,'(/,a)') ' <<<+- DAMASK_FEM init -+>>>'; flush(6) ! reading basic information from load case file and allocate data structure containing load cases call DMGetDimension(geomMesh,dimPlex,ierr); CHKERRA(ierr) !< dimension of mesh (2D or 3D) @@ -366,11 +366,9 @@ program DAMASK_FEM cutBackLevel = max(0, cutBackLevel - 1) ! try half number of subincs next inc if (all(solres(:)%converged)) then - write(6,'(/,a,'//IO_intOut(totalIncsCounter)//',a)') & ! report converged inc - ' increment ', totalIncsCounter, ' converged' + write(6,'(/,a,i0,a)') ' increment ', totalIncsCounter, ' converged' else - write(6,'(/,a,'//IO_intOut(totalIncsCounter)//',a)') & ! report non-converged inc - ' increment ', totalIncsCounter, ' NOT converged' + write(6,'(/,a,i0,a)') ' increment ', totalIncsCounter, ' NOT converged' endif; flush(6) if (mod(inc,loadCases(currentLoadCase)%outputFrequency) == 0) then ! at output frequency From a6e636a1c3e12615c2b2f2a5e958c3c781a48733 Mon Sep 17 00:00:00 2001 From: Test User Date: Sat, 7 Dec 2019 19:50:17 +0100 Subject: [PATCH 27/78] [skip ci] updated version information after successful test of v2.0.3-1228-g3e269f04 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 88e96b85c..35ae2dc0f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v2.0.3-1218-g5a6111ec +v2.0.3-1228-g3e269f04 From fbe2228ade08ed3dce995f8ed9f35fb71cadefb2 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 7 Dec 2019 20:22:55 +0100 Subject: [PATCH 28/78] avoid string length mismatch --- src/results.f90 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/results.f90 b/src/results.f90 index 93355b6c4..03277ab38 100644 --- a/src/results.f90 +++ b/src/results.f90 @@ -453,9 +453,9 @@ end subroutine results_writeScalarDataset_rotation !-------------------------------------------------------------------------------------------------- subroutine results_mapping_constituent(phaseAt,memberAt,label) - integer, dimension(:,:), intent(in) :: phaseAt !< phase section at (constituent,element) - integer, dimension(:,:,:), intent(in) :: memberAt !< phase member at (constituent,IP,element) - character(len=64), dimension(:), intent(in) :: label !< label of each phase section + integer, dimension(:,:), intent(in) :: phaseAt !< phase section at (constituent,element) + integer, dimension(:,:,:), intent(in) :: memberAt !< phase member at (constituent,IP,element) + character(len=pStringLen), dimension(:), intent(in) :: label !< label of each phase section integer, dimension(size(memberAt,1),size(memberAt,2),size(memberAt,3)) :: & phaseAt_perIP, & @@ -588,9 +588,9 @@ end subroutine results_mapping_constituent !-------------------------------------------------------------------------------------------------- subroutine results_mapping_materialpoint(homogenizationAt,memberAt,label) - integer, dimension(:), intent(in) :: homogenizationAt !< homogenization section at (element) - integer, dimension(:,:), intent(in) :: memberAt !< homogenization member at (IP,element) - character(len=64), dimension(:), intent(in) :: label !< label of each homogenization section + integer, dimension(:), intent(in) :: homogenizationAt !< homogenization section at (element) + integer, dimension(:,:), intent(in) :: memberAt !< homogenization member at (IP,element) + character(len=pStringLen), dimension(:), intent(in) :: label !< label of each homogenization section integer, dimension(size(memberAt,1),size(memberAt,2)) :: & homogenizationAt_perIP, & From c2e91ae5e1381ebaf1bfec5f65b5220eb7fb85b5 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 8 Dec 2019 20:52:05 +0100 Subject: [PATCH 29/78] copy and paste error, wrong array was set --- src/CPFEM2.f90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CPFEM2.f90 b/src/CPFEM2.f90 index 4575b9caa..9edb61d33 100644 --- a/src/CPFEM2.f90 +++ b/src/CPFEM2.f90 @@ -98,14 +98,14 @@ subroutine CPFEM_init groupHandle = HDF5_openGroup(fileHandle,'constituent') do i = 1,size(phase_plasticity) write(datasetName,'(i0,a)') i,'_omega_plastic' - call HDF5_read(groupHandle,plasticState(i)%state,datasetName) + call HDF5_read(groupHandle,plasticState(i)%state0,datasetName) enddo call HDF5_closeGroup(groupHandle) groupHandle = HDF5_openGroup(fileHandle,'materialpoint') do i = 1, material_Nhomogenization write(datasetName,'(i0,a)') i,'_omega_homogenization' - call HDF5_read(groupHandle,homogState(i)%state,datasetName) + call HDF5_read(groupHandle,homogState(i)%state0,datasetName) enddo call HDF5_closeGroup(groupHandle) From 53cb59fc474134d9aeedde79f0fe041267ef70c6 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 8 Dec 2019 21:29:26 +0100 Subject: [PATCH 30/78] use pytest instead of hand-written test class --- .gitlab-ci.yml | 7 ------- python/damask/orientation.py | 2 +- python/tests/test_Rotation.py | 18 ++++++++++++------ 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6e82561c5..d4c6923d9 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -115,13 +115,6 @@ Pytest: - release ################################################################################################### -OrientationRelationship: - stage: preprocessing - script: OrientationRelationship/test.py - except: - - master - - release - Pre_SeedGeneration: stage: preprocessing script: PreProcessing_SeedGeneration/test.py diff --git a/python/damask/orientation.py b/python/damask/orientation.py index fc601b608..65318f169 100644 --- a/python/damask/orientation.py +++ b/python/damask/orientation.py @@ -1025,7 +1025,7 @@ class Lattice: https://doi.org/10.1016/j.actamat.2004.11.021 """ - models={'KS':self.KS, 'GT':self.GT, "GT'":self.GTprime, + models={'KS':self.KS, 'GT':self.GT, 'GT_prime':self.GTprime, 'NW':self.NW, 'Pitsch': self.Pitsch, 'Bain':self.Bain} try: relationship = models[model] diff --git a/python/tests/test_Rotation.py b/python/tests/test_Rotation.py index 72956c013..79d674bcd 100644 --- a/python/tests/test_Rotation.py +++ b/python/tests/test_Rotation.py @@ -2,6 +2,7 @@ import pytest import numpy as np from damask import Rotation +from damask import Orientation n = 1000 @@ -18,38 +19,43 @@ class TestRotation: assert np.allclose(rot.asQuaternion(), Rotation.fromEulers(rot.asEulers()).asQuaternion()) - def test_AxisAngle(self,default): for rot in default: assert np.allclose(rot.asEulers(), Rotation.fromAxisAngle(rot.asAxisAngle()).asEulers()) - def test_Matrix(self,default): for rot in default: assert np.allclose(rot.asAxisAngle(), Rotation.fromMatrix(rot.asMatrix()).asAxisAngle()) - def test_Rodriques(self,default): for rot in default: assert np.allclose(rot.asMatrix(), Rotation.fromRodrigues(rot.asRodrigues()).asMatrix()) - def test_Homochoric(self,default): for rot in default: assert np.allclose(rot.asRodrigues(), Rotation.fromHomochoric(rot.asHomochoric()).asRodrigues()) - def test_Cubochoric(self,default): for rot in default: assert np.allclose(rot.asHomochoric(), Rotation.fromCubochoric(rot.asCubochoric()).asHomochoric()) - def test_Quaternion(self,default): for rot in default: assert np.allclose(rot.asCubochoric(), Rotation.fromQuaternion(rot.asQuaternion()).asCubochoric()) + + + @pytest.mark.parametrize('model',['Bain','KS','GT','GT_prime','NW','Pitsch']) + @pytest.mark.parametrize('lattice',['fcc','bcc']) + def test_relationship_forward_backward(self,model,lattice): + ori = Orientation(Rotation.fromRandom(),lattice) + for i,r in enumerate(ori.relatedOrientations(model)): + ori2 = r.relatedOrientations(model)[i] + misorientation = ori.rotation.misorientation(ori2.rotation) + assert misorientation.asAxisAngle(degrees=True)[3]<1.0e-5 + From fa9ee6b11679f1ecd91027573c0167359bef6062 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 8 Dec 2019 21:48:32 +0100 Subject: [PATCH 31/78] using reference results for orientation relationships --- python/tests/reference/Rotation/bcc_Bain.txt | 5 ++++ python/tests/reference/Rotation/bcc_GT.txt | 26 +++++++++++++++++++ .../tests/reference/Rotation/bcc_GT_prime.txt | 26 +++++++++++++++++++ python/tests/reference/Rotation/bcc_KS.txt | 26 +++++++++++++++++++ python/tests/reference/Rotation/bcc_NW.txt | 14 ++++++++++ .../tests/reference/Rotation/bcc_Pitsch.txt | 14 ++++++++++ python/tests/reference/Rotation/fcc_Bain.txt | 5 ++++ python/tests/reference/Rotation/fcc_GT.txt | 26 +++++++++++++++++++ .../tests/reference/Rotation/fcc_GT_prime.txt | 26 +++++++++++++++++++ python/tests/reference/Rotation/fcc_KS.txt | 26 +++++++++++++++++++ python/tests/reference/Rotation/fcc_NW.txt | 14 ++++++++++ .../tests/reference/Rotation/fcc_Pitsch.txt | 14 ++++++++++ python/tests/test_Rotation.py | 18 +++++++++++++ 13 files changed, 240 insertions(+) create mode 100644 python/tests/reference/Rotation/bcc_Bain.txt create mode 100644 python/tests/reference/Rotation/bcc_GT.txt create mode 100644 python/tests/reference/Rotation/bcc_GT_prime.txt create mode 100644 python/tests/reference/Rotation/bcc_KS.txt create mode 100644 python/tests/reference/Rotation/bcc_NW.txt create mode 100644 python/tests/reference/Rotation/bcc_Pitsch.txt create mode 100644 python/tests/reference/Rotation/fcc_Bain.txt create mode 100644 python/tests/reference/Rotation/fcc_GT.txt create mode 100644 python/tests/reference/Rotation/fcc_GT_prime.txt create mode 100644 python/tests/reference/Rotation/fcc_KS.txt create mode 100644 python/tests/reference/Rotation/fcc_NW.txt create mode 100644 python/tests/reference/Rotation/fcc_Pitsch.txt diff --git a/python/tests/reference/Rotation/bcc_Bain.txt b/python/tests/reference/Rotation/bcc_Bain.txt new file mode 100644 index 000000000..e1675cd32 --- /dev/null +++ b/python/tests/reference/Rotation/bcc_Bain.txt @@ -0,0 +1,5 @@ +1 header +1_Eulers 2_Eulers 3_Eulers +0.0 45.00000000000001 0.0 +90.0 45.00000000000001 270.0 +45.00000000000001 0.0 0.0 diff --git a/python/tests/reference/Rotation/bcc_GT.txt b/python/tests/reference/Rotation/bcc_GT.txt new file mode 100644 index 000000000..b4bfd5d8f --- /dev/null +++ b/python/tests/reference/Rotation/bcc_GT.txt @@ -0,0 +1,26 @@ +1 header +1_Eulers 2_Eulers 3_Eulers +283.60440567265294 9.976439066337804 33.24637065555936 +167.8261034151001 43.397849654402556 183.40022280897963 +262.1156357053931 43.82007387041961 104.07478363123654 +103.604405672653 9.976439066337804 213.24637065555936 +347.8261034151001 43.39784965440255 3.400222808979685 +82.11563570539313 43.82007387041961 284.0747836312365 +76.39559432734703 9.976439066337806 326.75362934444064 +192.17389658489986 43.397849654402556 176.59977719102034 +97.88436429460687 43.82007387041961 255.92521636876344 +256.395594327347 9.976439066337804 146.75362934444064 +12.173896584899929 43.39784965440254 356.59977719102034 +277.8843642946069 43.82007387041961 75.92521636876346 +102.17389658489992 43.39784965440254 266.59977719102034 +346.395594327347 9.976439066337804 56.75362934444064 +7.884364294606862 43.82007387041961 345.9252163687635 +282.17389658489986 43.39784965440254 86.59977719102032 +166.39559432734703 9.976439066337804 236.75362934444058 +187.88436429460683 43.82007387041961 165.92521636876344 +257.8261034151001 43.39784965440255 93.40022280897969 +13.604405672652977 9.976439066337804 303.24637065555936 +352.1156357053931 43.82007387041961 14.074783631236542 +77.82610341510008 43.397849654402556 273.4002228089796 +193.60440567265297 9.976439066337806 123.24637065555939 +153.65751914298576 65.6559553854118 185.90444335627936 diff --git a/python/tests/reference/Rotation/bcc_GT_prime.txt b/python/tests/reference/Rotation/bcc_GT_prime.txt new file mode 100644 index 000000000..73c3bb6b3 --- /dev/null +++ b/python/tests/reference/Rotation/bcc_GT_prime.txt @@ -0,0 +1,26 @@ +1 header +1_Eulers 2_Eulers 3_Eulers +303.24637065555936 9.976439066337804 13.604405672652977 +165.92521636876344 43.82007387041961 187.88436429460683 +266.59977719102034 43.39784965440254 102.17389658489992 +123.24637065555939 9.976439066337804 193.604405672653 +345.9252163687635 43.82007387041961 7.884364294606862 +86.59977719102032 43.39784965440254 282.17389658489986 +56.75362934444064 9.976439066337804 346.395594327347 +194.07478363123653 43.82007387041961 172.11563570539317 +93.40022280897969 43.39784965440255 257.8261034151001 +236.75362934444058 9.976439066337804 166.39559432734697 +14.074783631236542 43.82007387041961 352.1156357053931 +273.4002228089796 43.397849654402556 77.82610341510008 +104.07478363123654 43.82007387041961 262.1156357053931 +326.75362934444064 9.976439066337806 76.39559432734703 +3.400222808979685 43.39784965440255 347.8261034151001 +284.0747836312365 43.82007387041961 82.11563570539313 +146.75362934444064 9.976439066337804 256.395594327347 +183.40022280897963 43.397849654402556 167.8261034151001 +255.92521636876344 43.82007387041961 97.88436429460687 +33.24637065555936 9.976439066337804 283.60440567265294 +26.291675350407385 65.60048732963618 354.34378938496315 +75.92521636876346 43.82007387041961 277.8843642946069 +213.24637065555936 9.976439066337804 103.604405672653 +176.59977719102034 43.397849654402556 192.17389658489986 diff --git a/python/tests/reference/Rotation/bcc_KS.txt b/python/tests/reference/Rotation/bcc_KS.txt new file mode 100644 index 000000000..0add535bb --- /dev/null +++ b/python/tests/reference/Rotation/bcc_KS.txt @@ -0,0 +1,26 @@ +1 header +1_Eulers 2_Eulers 3_Eulers +335.7965716606702 10.528779365509317 65.79657166067024 +228.77270547567446 80.40593177313953 85.64260312151849 +131.22729452432552 80.40593177313954 4.357396878481506 +24.20342833932977 10.52877936550932 24.20342833932976 +221.95489158457983 85.70366403943002 80.37863910890589 +138.04510841542015 85.70366403943004 9.621360891094124 +131.22729452432552 80.40593177313953 94.35739687848151 +24.203428339329765 10.52877936550932 114.20342833932976 +221.95489158457983 85.70366403943004 170.37863910890587 +138.04510841542015 85.70366403943004 99.62136089109411 +335.7965716606702 10.52877936550932 155.79657166067025 +228.77270547567448 80.40593177313954 175.6426031215185 +335.7965716606702 10.52877936550932 335.7965716606702 +228.77270547567448 80.40593177313954 355.6426031215185 +131.2272945243255 80.40593177313954 274.35739687848144 +24.203428339329747 10.52877936550932 294.2034283393298 +221.95489158457985 85.70366403943004 350.3786391089059 +138.04510841542015 85.70366403943004 279.6213608910941 +41.95489158457986 94.29633596056998 9.621360891094133 +318.04510841542015 94.29633596056996 80.37863910890589 +155.79657166067025 169.4712206344907 24.203428339329754 +48.77270547567448 99.59406822686046 4.357396878481504 +311.2272945243255 99.59406822686046 85.64260312151852 +204.20342833932975 169.4712206344907 65.79657166067024 diff --git a/python/tests/reference/Rotation/bcc_NW.txt b/python/tests/reference/Rotation/bcc_NW.txt new file mode 100644 index 000000000..8d3dfbe84 --- /dev/null +++ b/python/tests/reference/Rotation/bcc_NW.txt @@ -0,0 +1,14 @@ +1 header +1_Eulers 2_Eulers 3_Eulers +225.41555594321144 83.13253115922213 83.08266205989301 +134.58444405678856 83.13253115922211 6.917337940107012 +4.702125169424418e-15 9.735610317245317 45.0 +134.58444405678856 83.13253115922213 276.91733794010696 +225.4155559432114 83.13253115922213 353.082662059893 +0.0 9.735610317245317 315.0 +134.58444405678858 83.13253115922213 96.91733794010702 +225.41555594321142 83.13253115922213 173.082662059893 +0.0 9.735610317245317 135.0 +260.40196970123213 45.81931182053556 283.6387072794765 +260.40196970123213 45.81931182053556 283.6387072794765 +180.0 99.73561031724535 225.0 diff --git a/python/tests/reference/Rotation/bcc_Pitsch.txt b/python/tests/reference/Rotation/bcc_Pitsch.txt new file mode 100644 index 000000000..dc9926ca1 --- /dev/null +++ b/python/tests/reference/Rotation/bcc_Pitsch.txt @@ -0,0 +1,14 @@ +1 header +1_Eulers 2_Eulers 3_Eulers +6.9173379401070045 83.13253115922213 44.58444405678856 +45.0 89.99999999999999 279.7356103172453 +166.36129272052352 45.819311820535574 279.59803029876787 +83.08266205989301 83.13253115922213 225.41555594321144 +256.3612927205235 45.819311820535574 189.59803029876787 +315.0 90.0 9.735610317245369 +186.917337940107 83.13253115922213 224.58444405678856 +315.0 90.0 80.26438968275463 +13.638707279476478 45.81931182053557 260.40196970123213 +263.082662059893 83.13253115922213 45.415555943211444 +103.63870727947646 45.819311820535574 170.40196970123213 +224.99999999999997 90.0 170.26438968275465 diff --git a/python/tests/reference/Rotation/fcc_Bain.txt b/python/tests/reference/Rotation/fcc_Bain.txt new file mode 100644 index 000000000..2c12eecc9 --- /dev/null +++ b/python/tests/reference/Rotation/fcc_Bain.txt @@ -0,0 +1,5 @@ +1 header +1_Eulers 2_Eulers 3_Eulers +180.0 45.00000000000001 180.0 +270.0 45.00000000000001 90.0 +315.0 0.0 0.0 diff --git a/python/tests/reference/Rotation/fcc_GT.txt b/python/tests/reference/Rotation/fcc_GT.txt new file mode 100644 index 000000000..e695d0d6f --- /dev/null +++ b/python/tests/reference/Rotation/fcc_GT.txt @@ -0,0 +1,26 @@ +1 header +1_Eulers 2_Eulers 3_Eulers +146.75362934444064 9.976439066337804 256.395594327347 +356.59977719102034 43.39784965440254 12.173896584899929 +75.92521636876346 43.82007387041961 277.8843642946069 +326.75362934444064 9.976439066337806 76.39559432734703 +176.59977719102034 43.397849654402556 192.17389658489986 +255.92521636876344 43.82007387041961 97.88436429460687 +213.24637065555936 9.976439066337804 103.604405672653 +3.400222808979685 43.39784965440255 347.8261034151001 +284.0747836312365 43.82007387041961 82.11563570539313 +33.24637065555936 9.976439066337804 283.60440567265294 +183.40022280897963 43.397849654402556 167.8261034151001 +104.07478363123654 43.82007387041961 262.1156357053931 +273.4002228089796 43.397849654402556 77.82610341510008 +123.24637065555939 9.976439066337806 193.60440567265297 +194.07478363123653 43.82007387041961 172.11563570539317 +93.40022280897969 43.39784965440255 257.8261034151001 +303.24637065555936 9.976439066337804 13.604405672652977 +14.074783631236542 43.82007387041961 352.1156357053931 +86.59977719102032 43.39784965440254 282.17389658489986 +236.75362934444058 9.976439066337804 166.39559432734703 +165.92521636876344 43.82007387041961 187.88436429460683 +266.59977719102034 43.39784965440254 102.17389658489992 +56.75362934444064 9.976439066337804 346.395594327347 +354.0955566437206 65.6559553854118 26.342480857014277 diff --git a/python/tests/reference/Rotation/fcc_GT_prime.txt b/python/tests/reference/Rotation/fcc_GT_prime.txt new file mode 100644 index 000000000..7df7cb6c1 --- /dev/null +++ b/python/tests/reference/Rotation/fcc_GT_prime.txt @@ -0,0 +1,26 @@ +1 header +1_Eulers 2_Eulers 3_Eulers +166.39559432734697 9.976439066337804 236.75362934444058 +352.1156357053931 43.82007387041961 14.074783631236542 +77.82610341510008 43.397849654402556 273.4002228089796 +346.395594327347 9.976439066337804 56.75362934444064 +172.11563570539317 43.82007387041961 194.07478363123653 +257.8261034151001 43.39784965440255 93.40022280897969 +193.604405672653 9.976439066337804 123.24637065555939 +7.884364294606862 43.82007387041961 345.9252163687635 +282.17389658489986 43.39784965440254 86.59977719102032 +13.604405672652977 9.976439066337804 303.24637065555936 +187.88436429460683 43.82007387041961 165.92521636876344 +102.17389658489992 43.39784965440254 266.59977719102034 +277.8843642946069 43.82007387041961 75.92521636876346 +103.604405672653 9.976439066337804 213.24637065555936 +192.17389658489986 43.397849654402556 176.59977719102034 +97.88436429460687 43.82007387041961 255.92521636876344 +283.60440567265294 9.976439066337804 33.24637065555936 +12.173896584899929 43.39784965440254 356.59977719102034 +82.11563570539313 43.82007387041961 284.0747836312365 +256.395594327347 9.976439066337804 146.75362934444064 +185.65621061503683 65.60048732963617 153.70832464959264 +262.1156357053931 43.82007387041961 104.07478363123654 +76.39559432734703 9.976439066337806 326.75362934444064 +347.8261034151001 43.39784965440255 3.400222808979685 diff --git a/python/tests/reference/Rotation/fcc_KS.txt b/python/tests/reference/Rotation/fcc_KS.txt new file mode 100644 index 000000000..3a6e30358 --- /dev/null +++ b/python/tests/reference/Rotation/fcc_KS.txt @@ -0,0 +1,26 @@ +1 header +1_Eulers 2_Eulers 3_Eulers +114.20342833932975 10.52877936550932 204.20342833932972 +94.3573968784815 80.40593177313954 311.22729452432543 +175.6426031215185 80.40593177313954 48.77270547567447 +155.79657166067025 10.52877936550932 155.79657166067025 +99.62136089109411 85.70366403943004 318.04510841542015 +170.37863910890587 85.70366403943002 41.954891584579855 +85.64260312151852 80.40593177313954 48.77270547567448 +65.79657166067024 10.52877936550932 155.79657166067025 +9.621360891094124 85.70366403943004 318.04510841542015 +80.37863910890587 85.70366403943004 41.95489158457987 +24.203428339329758 10.52877936550932 204.20342833932975 +4.357396878481486 80.40593177313954 311.2272945243255 +204.20342833932972 10.52877936550932 204.20342833932972 +184.35739687848147 80.40593177313954 311.2272945243255 +265.64260312151845 80.40593177313953 48.77270547567449 +245.79657166067025 10.528779365509317 155.79657166067025 +189.62136089109413 85.70366403943004 318.04510841542015 +260.3786391089059 85.70366403943002 41.954891584579855 +170.37863910890587 94.29633596056996 138.04510841542015 +99.62136089109411 94.29633596056998 221.95489158457983 +155.79657166067025 169.4712206344907 24.203428339329754 +175.64260312151848 99.59406822686046 131.22729452432552 +94.35739687848151 99.59406822686046 228.77270547567446 +114.20342833932975 169.4712206344907 335.7965716606702 diff --git a/python/tests/reference/Rotation/fcc_NW.txt b/python/tests/reference/Rotation/fcc_NW.txt new file mode 100644 index 000000000..bf3631db0 --- /dev/null +++ b/python/tests/reference/Rotation/fcc_NW.txt @@ -0,0 +1,14 @@ +1 header +1_Eulers 2_Eulers 3_Eulers +96.91733794010702 83.13253115922213 314.5844440567886 +173.082662059893 83.13253115922211 45.41555594321143 +135.0 9.735610317245317 180.0 +263.082662059893 83.13253115922213 45.415555943211444 +186.91733794010702 83.13253115922211 314.5844440567886 +224.99999999999997 9.735610317245317 180.0 +83.082662059893 83.13253115922213 45.415555943211444 +6.917337940106983 83.13253115922211 314.5844440567886 +45.0 9.73561031724532 180.0 +256.36129272052347 45.81931182053556 279.59803029876775 +256.36129272052347 45.81931182053556 279.59803029876775 +315.0 99.73561031724536 0.0 diff --git a/python/tests/reference/Rotation/fcc_Pitsch.txt b/python/tests/reference/Rotation/fcc_Pitsch.txt new file mode 100644 index 000000000..a2369f0a4 --- /dev/null +++ b/python/tests/reference/Rotation/fcc_Pitsch.txt @@ -0,0 +1,14 @@ +1 header +1_Eulers 2_Eulers 3_Eulers +135.41555594321144 83.13253115922213 173.082662059893 +260.26438968275465 90.0 135.0 +260.40196970123213 45.81931182053557 13.638707279476478 +314.5844440567886 83.13253115922213 96.91733794010702 +350.40196970123213 45.81931182053557 283.6387072794765 +170.26438968275465 90.0 224.99999999999997 +315.4155559432114 83.13253115922213 353.08266205989304 +99.73561031724536 90.0 225.0 +279.59803029876787 45.819311820535574 166.36129272052352 +134.58444405678856 83.13253115922213 276.91733794010696 +9.598030298767851 45.819311820535574 76.36129272052355 +9.735610317245369 90.0 315.0 diff --git a/python/tests/test_Rotation.py b/python/tests/test_Rotation.py index 79d674bcd..a4dc7c61d 100644 --- a/python/tests/test_Rotation.py +++ b/python/tests/test_Rotation.py @@ -1,6 +1,9 @@ +import os + import pytest import numpy as np +import damask from damask import Rotation from damask import Orientation @@ -11,6 +14,11 @@ def default(): """A set of n random rotations.""" return [Rotation.fromRandom() for r in range(n)] +@pytest.fixture +def reference_dir(reference_dir_base): + """Directory containing reference results.""" + return os.path.join(reference_dir_base,'Rotation') + class TestRotation: @@ -59,3 +67,13 @@ class TestRotation: misorientation = ori.rotation.misorientation(ori2.rotation) assert misorientation.asAxisAngle(degrees=True)[3]<1.0e-5 + @pytest.mark.parametrize('model',['Bain','KS','GT','GT_prime','NW','Pitsch']) + @pytest.mark.parametrize('lattice',['fcc','bcc']) + def test_relationship_reference(self,update,reference_dir,model,lattice): + reference = os.path.join(reference_dir,'{}_{}.txt'.format(lattice,model)) + ori = Orientation(Rotation(),lattice) + eu = np.array([o.rotation.asEulers(degrees=True) for o in ori.relatedOrientations(model)]) + if update: + table = damask.Table(eu,{'Eulers':(3,)}) + table.to_ASCII(reference) + assert np.allclose(eu,damask.Table.from_ASCII(reference).get('Eulers')) From 5a9173ccf446b80dec3fdc755b8e035a77a347b4 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sun, 8 Dec 2019 21:57:07 +0100 Subject: [PATCH 32/78] might simplify plotting in MTEX --- python/tests/reference/Rotation/bcc_Bain.txt | 8 +-- python/tests/reference/Rotation/bcc_GT.txt | 50 +++++++++---------- .../tests/reference/Rotation/bcc_GT_prime.txt | 50 +++++++++---------- python/tests/reference/Rotation/bcc_KS.txt | 50 +++++++++---------- python/tests/reference/Rotation/bcc_NW.txt | 26 +++++----- .../tests/reference/Rotation/bcc_Pitsch.txt | 26 +++++----- python/tests/reference/Rotation/fcc_Bain.txt | 8 +-- python/tests/reference/Rotation/fcc_GT.txt | 50 +++++++++---------- .../tests/reference/Rotation/fcc_GT_prime.txt | 50 +++++++++---------- python/tests/reference/Rotation/fcc_KS.txt | 50 +++++++++---------- python/tests/reference/Rotation/fcc_NW.txt | 26 +++++----- .../tests/reference/Rotation/fcc_Pitsch.txt | 26 +++++----- python/tests/test_Rotation.py | 2 + 13 files changed, 212 insertions(+), 210 deletions(-) diff --git a/python/tests/reference/Rotation/bcc_Bain.txt b/python/tests/reference/Rotation/bcc_Bain.txt index e1675cd32..e0bc4f6c7 100644 --- a/python/tests/reference/Rotation/bcc_Bain.txt +++ b/python/tests/reference/Rotation/bcc_Bain.txt @@ -1,5 +1,5 @@ 1 header -1_Eulers 2_Eulers 3_Eulers -0.0 45.00000000000001 0.0 -90.0 45.00000000000001 270.0 -45.00000000000001 0.0 0.0 +1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos +0.0 45.00000000000001 0.0 1 1 +90.0 45.00000000000001 270.0 1 2 +45.00000000000001 0.0 0.0 1 3 diff --git a/python/tests/reference/Rotation/bcc_GT.txt b/python/tests/reference/Rotation/bcc_GT.txt index b4bfd5d8f..d1fe2e1c8 100644 --- a/python/tests/reference/Rotation/bcc_GT.txt +++ b/python/tests/reference/Rotation/bcc_GT.txt @@ -1,26 +1,26 @@ 1 header -1_Eulers 2_Eulers 3_Eulers -283.60440567265294 9.976439066337804 33.24637065555936 -167.8261034151001 43.397849654402556 183.40022280897963 -262.1156357053931 43.82007387041961 104.07478363123654 -103.604405672653 9.976439066337804 213.24637065555936 -347.8261034151001 43.39784965440255 3.400222808979685 -82.11563570539313 43.82007387041961 284.0747836312365 -76.39559432734703 9.976439066337806 326.75362934444064 -192.17389658489986 43.397849654402556 176.59977719102034 -97.88436429460687 43.82007387041961 255.92521636876344 -256.395594327347 9.976439066337804 146.75362934444064 -12.173896584899929 43.39784965440254 356.59977719102034 -277.8843642946069 43.82007387041961 75.92521636876346 -102.17389658489992 43.39784965440254 266.59977719102034 -346.395594327347 9.976439066337804 56.75362934444064 -7.884364294606862 43.82007387041961 345.9252163687635 -282.17389658489986 43.39784965440254 86.59977719102032 -166.39559432734703 9.976439066337804 236.75362934444058 -187.88436429460683 43.82007387041961 165.92521636876344 -257.8261034151001 43.39784965440255 93.40022280897969 -13.604405672652977 9.976439066337804 303.24637065555936 -352.1156357053931 43.82007387041961 14.074783631236542 -77.82610341510008 43.397849654402556 273.4002228089796 -193.60440567265297 9.976439066337806 123.24637065555939 -153.65751914298576 65.6559553854118 185.90444335627936 +1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos +283.60440567265294 9.976439066337804 33.24637065555936 1 1 +167.8261034151001 43.397849654402556 183.40022280897963 1 2 +262.1156357053931 43.82007387041961 104.07478363123654 1 3 +103.604405672653 9.976439066337804 213.24637065555936 1 4 +347.8261034151001 43.39784965440255 3.400222808979685 1 5 +82.11563570539313 43.82007387041961 284.0747836312365 1 6 +76.39559432734703 9.976439066337806 326.75362934444064 1 7 +192.17389658489986 43.397849654402556 176.59977719102034 1 8 +97.88436429460687 43.82007387041961 255.92521636876344 1 9 +256.395594327347 9.976439066337804 146.75362934444064 1 10 +12.173896584899929 43.39784965440254 356.59977719102034 1 11 +277.8843642946069 43.82007387041961 75.92521636876346 1 12 +102.17389658489992 43.39784965440254 266.59977719102034 1 13 +346.395594327347 9.976439066337804 56.75362934444064 1 14 +7.884364294606862 43.82007387041961 345.9252163687635 1 15 +282.17389658489986 43.39784965440254 86.59977719102032 1 16 +166.39559432734703 9.976439066337804 236.75362934444058 1 17 +187.88436429460683 43.82007387041961 165.92521636876344 1 18 +257.8261034151001 43.39784965440255 93.40022280897969 1 19 +13.604405672652977 9.976439066337804 303.24637065555936 1 20 +352.1156357053931 43.82007387041961 14.074783631236542 1 21 +77.82610341510008 43.397849654402556 273.4002228089796 1 22 +193.60440567265297 9.976439066337806 123.24637065555939 1 23 +153.65751914298576 65.6559553854118 185.90444335627936 1 24 diff --git a/python/tests/reference/Rotation/bcc_GT_prime.txt b/python/tests/reference/Rotation/bcc_GT_prime.txt index 73c3bb6b3..42f32bcbb 100644 --- a/python/tests/reference/Rotation/bcc_GT_prime.txt +++ b/python/tests/reference/Rotation/bcc_GT_prime.txt @@ -1,26 +1,26 @@ 1 header -1_Eulers 2_Eulers 3_Eulers -303.24637065555936 9.976439066337804 13.604405672652977 -165.92521636876344 43.82007387041961 187.88436429460683 -266.59977719102034 43.39784965440254 102.17389658489992 -123.24637065555939 9.976439066337804 193.604405672653 -345.9252163687635 43.82007387041961 7.884364294606862 -86.59977719102032 43.39784965440254 282.17389658489986 -56.75362934444064 9.976439066337804 346.395594327347 -194.07478363123653 43.82007387041961 172.11563570539317 -93.40022280897969 43.39784965440255 257.8261034151001 -236.75362934444058 9.976439066337804 166.39559432734697 -14.074783631236542 43.82007387041961 352.1156357053931 -273.4002228089796 43.397849654402556 77.82610341510008 -104.07478363123654 43.82007387041961 262.1156357053931 -326.75362934444064 9.976439066337806 76.39559432734703 -3.400222808979685 43.39784965440255 347.8261034151001 -284.0747836312365 43.82007387041961 82.11563570539313 -146.75362934444064 9.976439066337804 256.395594327347 -183.40022280897963 43.397849654402556 167.8261034151001 -255.92521636876344 43.82007387041961 97.88436429460687 -33.24637065555936 9.976439066337804 283.60440567265294 -26.291675350407385 65.60048732963618 354.34378938496315 -75.92521636876346 43.82007387041961 277.8843642946069 -213.24637065555936 9.976439066337804 103.604405672653 -176.59977719102034 43.397849654402556 192.17389658489986 +1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos +303.24637065555936 9.976439066337804 13.604405672652977 1 1 +165.92521636876344 43.82007387041961 187.88436429460683 1 2 +266.59977719102034 43.39784965440254 102.17389658489992 1 3 +123.24637065555939 9.976439066337804 193.604405672653 1 4 +345.9252163687635 43.82007387041961 7.884364294606862 1 5 +86.59977719102032 43.39784965440254 282.17389658489986 1 6 +56.75362934444064 9.976439066337804 346.395594327347 1 7 +194.07478363123653 43.82007387041961 172.11563570539317 1 8 +93.40022280897969 43.39784965440255 257.8261034151001 1 9 +236.75362934444058 9.976439066337804 166.39559432734697 1 10 +14.074783631236542 43.82007387041961 352.1156357053931 1 11 +273.4002228089796 43.397849654402556 77.82610341510008 1 12 +104.07478363123654 43.82007387041961 262.1156357053931 1 13 +326.75362934444064 9.976439066337806 76.39559432734703 1 14 +3.400222808979685 43.39784965440255 347.8261034151001 1 15 +284.0747836312365 43.82007387041961 82.11563570539313 1 16 +146.75362934444064 9.976439066337804 256.395594327347 1 17 +183.40022280897963 43.397849654402556 167.8261034151001 1 18 +255.92521636876344 43.82007387041961 97.88436429460687 1 19 +33.24637065555936 9.976439066337804 283.60440567265294 1 20 +26.291675350407385 65.60048732963618 354.34378938496315 1 21 +75.92521636876346 43.82007387041961 277.8843642946069 1 22 +213.24637065555936 9.976439066337804 103.604405672653 1 23 +176.59977719102034 43.397849654402556 192.17389658489986 1 24 diff --git a/python/tests/reference/Rotation/bcc_KS.txt b/python/tests/reference/Rotation/bcc_KS.txt index 0add535bb..34b393358 100644 --- a/python/tests/reference/Rotation/bcc_KS.txt +++ b/python/tests/reference/Rotation/bcc_KS.txt @@ -1,26 +1,26 @@ 1 header -1_Eulers 2_Eulers 3_Eulers -335.7965716606702 10.528779365509317 65.79657166067024 -228.77270547567446 80.40593177313953 85.64260312151849 -131.22729452432552 80.40593177313954 4.357396878481506 -24.20342833932977 10.52877936550932 24.20342833932976 -221.95489158457983 85.70366403943002 80.37863910890589 -138.04510841542015 85.70366403943004 9.621360891094124 -131.22729452432552 80.40593177313953 94.35739687848151 -24.203428339329765 10.52877936550932 114.20342833932976 -221.95489158457983 85.70366403943004 170.37863910890587 -138.04510841542015 85.70366403943004 99.62136089109411 -335.7965716606702 10.52877936550932 155.79657166067025 -228.77270547567448 80.40593177313954 175.6426031215185 -335.7965716606702 10.52877936550932 335.7965716606702 -228.77270547567448 80.40593177313954 355.6426031215185 -131.2272945243255 80.40593177313954 274.35739687848144 -24.203428339329747 10.52877936550932 294.2034283393298 -221.95489158457985 85.70366403943004 350.3786391089059 -138.04510841542015 85.70366403943004 279.6213608910941 -41.95489158457986 94.29633596056998 9.621360891094133 -318.04510841542015 94.29633596056996 80.37863910890589 -155.79657166067025 169.4712206344907 24.203428339329754 -48.77270547567448 99.59406822686046 4.357396878481504 -311.2272945243255 99.59406822686046 85.64260312151852 -204.20342833932975 169.4712206344907 65.79657166067024 +1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos +335.7965716606702 10.528779365509317 65.79657166067024 1 1 +228.77270547567446 80.40593177313953 85.64260312151849 1 2 +131.22729452432552 80.40593177313954 4.357396878481506 1 3 +24.20342833932977 10.52877936550932 24.20342833932976 1 4 +221.95489158457983 85.70366403943002 80.37863910890589 1 5 +138.04510841542015 85.70366403943004 9.621360891094124 1 6 +131.22729452432552 80.40593177313953 94.35739687848151 1 7 +24.203428339329765 10.52877936550932 114.20342833932976 1 8 +221.95489158457983 85.70366403943004 170.37863910890587 1 9 +138.04510841542015 85.70366403943004 99.62136089109411 1 10 +335.7965716606702 10.52877936550932 155.79657166067025 1 11 +228.77270547567448 80.40593177313954 175.6426031215185 1 12 +335.7965716606702 10.52877936550932 335.7965716606702 1 13 +228.77270547567448 80.40593177313954 355.6426031215185 1 14 +131.2272945243255 80.40593177313954 274.35739687848144 1 15 +24.203428339329747 10.52877936550932 294.2034283393298 1 16 +221.95489158457985 85.70366403943004 350.3786391089059 1 17 +138.04510841542015 85.70366403943004 279.6213608910941 1 18 +41.95489158457986 94.29633596056998 9.621360891094133 1 19 +318.04510841542015 94.29633596056996 80.37863910890589 1 20 +155.79657166067025 169.4712206344907 24.203428339329754 1 21 +48.77270547567448 99.59406822686046 4.357396878481504 1 22 +311.2272945243255 99.59406822686046 85.64260312151852 1 23 +204.20342833932975 169.4712206344907 65.79657166067024 1 24 diff --git a/python/tests/reference/Rotation/bcc_NW.txt b/python/tests/reference/Rotation/bcc_NW.txt index 8d3dfbe84..76e7c6182 100644 --- a/python/tests/reference/Rotation/bcc_NW.txt +++ b/python/tests/reference/Rotation/bcc_NW.txt @@ -1,14 +1,14 @@ 1 header -1_Eulers 2_Eulers 3_Eulers -225.41555594321144 83.13253115922213 83.08266205989301 -134.58444405678856 83.13253115922211 6.917337940107012 -4.702125169424418e-15 9.735610317245317 45.0 -134.58444405678856 83.13253115922213 276.91733794010696 -225.4155559432114 83.13253115922213 353.082662059893 -0.0 9.735610317245317 315.0 -134.58444405678858 83.13253115922213 96.91733794010702 -225.41555594321142 83.13253115922213 173.082662059893 -0.0 9.735610317245317 135.0 -260.40196970123213 45.81931182053556 283.6387072794765 -260.40196970123213 45.81931182053556 283.6387072794765 -180.0 99.73561031724535 225.0 +1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos +225.41555594321144 83.13253115922213 83.08266205989301 1 1 +134.58444405678856 83.13253115922211 6.917337940107012 1 2 +4.702125169424418e-15 9.735610317245317 45.0 1 3 +134.58444405678856 83.13253115922213 276.91733794010696 1 4 +225.4155559432114 83.13253115922213 353.082662059893 1 5 +0.0 9.735610317245317 315.0 1 6 +134.58444405678858 83.13253115922213 96.91733794010702 1 7 +225.41555594321142 83.13253115922213 173.082662059893 1 8 +0.0 9.735610317245317 135.0 1 9 +260.40196970123213 45.81931182053556 283.6387072794765 1 10 +260.40196970123213 45.81931182053556 283.6387072794765 1 11 +180.0 99.73561031724535 225.0 1 12 diff --git a/python/tests/reference/Rotation/bcc_Pitsch.txt b/python/tests/reference/Rotation/bcc_Pitsch.txt index dc9926ca1..ef28bbb4d 100644 --- a/python/tests/reference/Rotation/bcc_Pitsch.txt +++ b/python/tests/reference/Rotation/bcc_Pitsch.txt @@ -1,14 +1,14 @@ 1 header -1_Eulers 2_Eulers 3_Eulers -6.9173379401070045 83.13253115922213 44.58444405678856 -45.0 89.99999999999999 279.7356103172453 -166.36129272052352 45.819311820535574 279.59803029876787 -83.08266205989301 83.13253115922213 225.41555594321144 -256.3612927205235 45.819311820535574 189.59803029876787 -315.0 90.0 9.735610317245369 -186.917337940107 83.13253115922213 224.58444405678856 -315.0 90.0 80.26438968275463 -13.638707279476478 45.81931182053557 260.40196970123213 -263.082662059893 83.13253115922213 45.415555943211444 -103.63870727947646 45.819311820535574 170.40196970123213 -224.99999999999997 90.0 170.26438968275465 +1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos +6.9173379401070045 83.13253115922213 44.58444405678856 1 1 +45.0 89.99999999999999 279.7356103172453 1 2 +166.36129272052352 45.819311820535574 279.59803029876787 1 3 +83.08266205989301 83.13253115922213 225.41555594321144 1 4 +256.3612927205235 45.819311820535574 189.59803029876787 1 5 +315.0 90.0 9.735610317245369 1 6 +186.917337940107 83.13253115922213 224.58444405678856 1 7 +315.0 90.0 80.26438968275463 1 8 +13.638707279476478 45.81931182053557 260.40196970123213 1 9 +263.082662059893 83.13253115922213 45.415555943211444 1 10 +103.63870727947646 45.819311820535574 170.40196970123213 1 11 +224.99999999999997 90.0 170.26438968275465 1 12 diff --git a/python/tests/reference/Rotation/fcc_Bain.txt b/python/tests/reference/Rotation/fcc_Bain.txt index 2c12eecc9..876cf3888 100644 --- a/python/tests/reference/Rotation/fcc_Bain.txt +++ b/python/tests/reference/Rotation/fcc_Bain.txt @@ -1,5 +1,5 @@ 1 header -1_Eulers 2_Eulers 3_Eulers -180.0 45.00000000000001 180.0 -270.0 45.00000000000001 90.0 -315.0 0.0 0.0 +1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos +180.0 45.00000000000001 180.0 1 1 +270.0 45.00000000000001 90.0 1 2 +315.0 0.0 0.0 1 3 diff --git a/python/tests/reference/Rotation/fcc_GT.txt b/python/tests/reference/Rotation/fcc_GT.txt index e695d0d6f..b91a80c46 100644 --- a/python/tests/reference/Rotation/fcc_GT.txt +++ b/python/tests/reference/Rotation/fcc_GT.txt @@ -1,26 +1,26 @@ 1 header -1_Eulers 2_Eulers 3_Eulers -146.75362934444064 9.976439066337804 256.395594327347 -356.59977719102034 43.39784965440254 12.173896584899929 -75.92521636876346 43.82007387041961 277.8843642946069 -326.75362934444064 9.976439066337806 76.39559432734703 -176.59977719102034 43.397849654402556 192.17389658489986 -255.92521636876344 43.82007387041961 97.88436429460687 -213.24637065555936 9.976439066337804 103.604405672653 -3.400222808979685 43.39784965440255 347.8261034151001 -284.0747836312365 43.82007387041961 82.11563570539313 -33.24637065555936 9.976439066337804 283.60440567265294 -183.40022280897963 43.397849654402556 167.8261034151001 -104.07478363123654 43.82007387041961 262.1156357053931 -273.4002228089796 43.397849654402556 77.82610341510008 -123.24637065555939 9.976439066337806 193.60440567265297 -194.07478363123653 43.82007387041961 172.11563570539317 -93.40022280897969 43.39784965440255 257.8261034151001 -303.24637065555936 9.976439066337804 13.604405672652977 -14.074783631236542 43.82007387041961 352.1156357053931 -86.59977719102032 43.39784965440254 282.17389658489986 -236.75362934444058 9.976439066337804 166.39559432734703 -165.92521636876344 43.82007387041961 187.88436429460683 -266.59977719102034 43.39784965440254 102.17389658489992 -56.75362934444064 9.976439066337804 346.395594327347 -354.0955566437206 65.6559553854118 26.342480857014277 +1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos +146.75362934444064 9.976439066337804 256.395594327347 1 1 +356.59977719102034 43.39784965440254 12.173896584899929 1 2 +75.92521636876346 43.82007387041961 277.8843642946069 1 3 +326.75362934444064 9.976439066337806 76.39559432734703 1 4 +176.59977719102034 43.397849654402556 192.17389658489986 1 5 +255.92521636876344 43.82007387041961 97.88436429460687 1 6 +213.24637065555936 9.976439066337804 103.604405672653 1 7 +3.400222808979685 43.39784965440255 347.8261034151001 1 8 +284.0747836312365 43.82007387041961 82.11563570539313 1 9 +33.24637065555936 9.976439066337804 283.60440567265294 1 10 +183.40022280897963 43.397849654402556 167.8261034151001 1 11 +104.07478363123654 43.82007387041961 262.1156357053931 1 12 +273.4002228089796 43.397849654402556 77.82610341510008 1 13 +123.24637065555939 9.976439066337806 193.60440567265297 1 14 +194.07478363123653 43.82007387041961 172.11563570539317 1 15 +93.40022280897969 43.39784965440255 257.8261034151001 1 16 +303.24637065555936 9.976439066337804 13.604405672652977 1 17 +14.074783631236542 43.82007387041961 352.1156357053931 1 18 +86.59977719102032 43.39784965440254 282.17389658489986 1 19 +236.75362934444058 9.976439066337804 166.39559432734703 1 20 +165.92521636876344 43.82007387041961 187.88436429460683 1 21 +266.59977719102034 43.39784965440254 102.17389658489992 1 22 +56.75362934444064 9.976439066337804 346.395594327347 1 23 +354.0955566437206 65.6559553854118 26.342480857014277 1 24 diff --git a/python/tests/reference/Rotation/fcc_GT_prime.txt b/python/tests/reference/Rotation/fcc_GT_prime.txt index 7df7cb6c1..1d6f171c4 100644 --- a/python/tests/reference/Rotation/fcc_GT_prime.txt +++ b/python/tests/reference/Rotation/fcc_GT_prime.txt @@ -1,26 +1,26 @@ 1 header -1_Eulers 2_Eulers 3_Eulers -166.39559432734697 9.976439066337804 236.75362934444058 -352.1156357053931 43.82007387041961 14.074783631236542 -77.82610341510008 43.397849654402556 273.4002228089796 -346.395594327347 9.976439066337804 56.75362934444064 -172.11563570539317 43.82007387041961 194.07478363123653 -257.8261034151001 43.39784965440255 93.40022280897969 -193.604405672653 9.976439066337804 123.24637065555939 -7.884364294606862 43.82007387041961 345.9252163687635 -282.17389658489986 43.39784965440254 86.59977719102032 -13.604405672652977 9.976439066337804 303.24637065555936 -187.88436429460683 43.82007387041961 165.92521636876344 -102.17389658489992 43.39784965440254 266.59977719102034 -277.8843642946069 43.82007387041961 75.92521636876346 -103.604405672653 9.976439066337804 213.24637065555936 -192.17389658489986 43.397849654402556 176.59977719102034 -97.88436429460687 43.82007387041961 255.92521636876344 -283.60440567265294 9.976439066337804 33.24637065555936 -12.173896584899929 43.39784965440254 356.59977719102034 -82.11563570539313 43.82007387041961 284.0747836312365 -256.395594327347 9.976439066337804 146.75362934444064 -185.65621061503683 65.60048732963617 153.70832464959264 -262.1156357053931 43.82007387041961 104.07478363123654 -76.39559432734703 9.976439066337806 326.75362934444064 -347.8261034151001 43.39784965440255 3.400222808979685 +1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos +166.39559432734697 9.976439066337804 236.75362934444058 1 1 +352.1156357053931 43.82007387041961 14.074783631236542 1 2 +77.82610341510008 43.397849654402556 273.4002228089796 1 3 +346.395594327347 9.976439066337804 56.75362934444064 1 4 +172.11563570539317 43.82007387041961 194.07478363123653 1 5 +257.8261034151001 43.39784965440255 93.40022280897969 1 6 +193.604405672653 9.976439066337804 123.24637065555939 1 7 +7.884364294606862 43.82007387041961 345.9252163687635 1 8 +282.17389658489986 43.39784965440254 86.59977719102032 1 9 +13.604405672652977 9.976439066337804 303.24637065555936 1 10 +187.88436429460683 43.82007387041961 165.92521636876344 1 11 +102.17389658489992 43.39784965440254 266.59977719102034 1 12 +277.8843642946069 43.82007387041961 75.92521636876346 1 13 +103.604405672653 9.976439066337804 213.24637065555936 1 14 +192.17389658489986 43.397849654402556 176.59977719102034 1 15 +97.88436429460687 43.82007387041961 255.92521636876344 1 16 +283.60440567265294 9.976439066337804 33.24637065555936 1 17 +12.173896584899929 43.39784965440254 356.59977719102034 1 18 +82.11563570539313 43.82007387041961 284.0747836312365 1 19 +256.395594327347 9.976439066337804 146.75362934444064 1 20 +185.65621061503683 65.60048732963617 153.70832464959264 1 21 +262.1156357053931 43.82007387041961 104.07478363123654 1 22 +76.39559432734703 9.976439066337806 326.75362934444064 1 23 +347.8261034151001 43.39784965440255 3.400222808979685 1 24 diff --git a/python/tests/reference/Rotation/fcc_KS.txt b/python/tests/reference/Rotation/fcc_KS.txt index 3a6e30358..93fdcf07e 100644 --- a/python/tests/reference/Rotation/fcc_KS.txt +++ b/python/tests/reference/Rotation/fcc_KS.txt @@ -1,26 +1,26 @@ 1 header -1_Eulers 2_Eulers 3_Eulers -114.20342833932975 10.52877936550932 204.20342833932972 -94.3573968784815 80.40593177313954 311.22729452432543 -175.6426031215185 80.40593177313954 48.77270547567447 -155.79657166067025 10.52877936550932 155.79657166067025 -99.62136089109411 85.70366403943004 318.04510841542015 -170.37863910890587 85.70366403943002 41.954891584579855 -85.64260312151852 80.40593177313954 48.77270547567448 -65.79657166067024 10.52877936550932 155.79657166067025 -9.621360891094124 85.70366403943004 318.04510841542015 -80.37863910890587 85.70366403943004 41.95489158457987 -24.203428339329758 10.52877936550932 204.20342833932975 -4.357396878481486 80.40593177313954 311.2272945243255 -204.20342833932972 10.52877936550932 204.20342833932972 -184.35739687848147 80.40593177313954 311.2272945243255 -265.64260312151845 80.40593177313953 48.77270547567449 -245.79657166067025 10.528779365509317 155.79657166067025 -189.62136089109413 85.70366403943004 318.04510841542015 -260.3786391089059 85.70366403943002 41.954891584579855 -170.37863910890587 94.29633596056996 138.04510841542015 -99.62136089109411 94.29633596056998 221.95489158457983 -155.79657166067025 169.4712206344907 24.203428339329754 -175.64260312151848 99.59406822686046 131.22729452432552 -94.35739687848151 99.59406822686046 228.77270547567446 -114.20342833932975 169.4712206344907 335.7965716606702 +1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos +114.20342833932975 10.52877936550932 204.20342833932972 1 1 +94.3573968784815 80.40593177313954 311.22729452432543 1 2 +175.6426031215185 80.40593177313954 48.77270547567447 1 3 +155.79657166067025 10.52877936550932 155.79657166067025 1 4 +99.62136089109411 85.70366403943004 318.04510841542015 1 5 +170.37863910890587 85.70366403943002 41.954891584579855 1 6 +85.64260312151852 80.40593177313954 48.77270547567448 1 7 +65.79657166067024 10.52877936550932 155.79657166067025 1 8 +9.621360891094124 85.70366403943004 318.04510841542015 1 9 +80.37863910890587 85.70366403943004 41.95489158457987 1 10 +24.203428339329758 10.52877936550932 204.20342833932975 1 11 +4.357396878481486 80.40593177313954 311.2272945243255 1 12 +204.20342833932972 10.52877936550932 204.20342833932972 1 13 +184.35739687848147 80.40593177313954 311.2272945243255 1 14 +265.64260312151845 80.40593177313953 48.77270547567449 1 15 +245.79657166067025 10.528779365509317 155.79657166067025 1 16 +189.62136089109413 85.70366403943004 318.04510841542015 1 17 +260.3786391089059 85.70366403943002 41.954891584579855 1 18 +170.37863910890587 94.29633596056996 138.04510841542015 1 19 +99.62136089109411 94.29633596056998 221.95489158457983 1 20 +155.79657166067025 169.4712206344907 24.203428339329754 1 21 +175.64260312151848 99.59406822686046 131.22729452432552 1 22 +94.35739687848151 99.59406822686046 228.77270547567446 1 23 +114.20342833932975 169.4712206344907 335.7965716606702 1 24 diff --git a/python/tests/reference/Rotation/fcc_NW.txt b/python/tests/reference/Rotation/fcc_NW.txt index bf3631db0..e041ec0b0 100644 --- a/python/tests/reference/Rotation/fcc_NW.txt +++ b/python/tests/reference/Rotation/fcc_NW.txt @@ -1,14 +1,14 @@ 1 header -1_Eulers 2_Eulers 3_Eulers -96.91733794010702 83.13253115922213 314.5844440567886 -173.082662059893 83.13253115922211 45.41555594321143 -135.0 9.735610317245317 180.0 -263.082662059893 83.13253115922213 45.415555943211444 -186.91733794010702 83.13253115922211 314.5844440567886 -224.99999999999997 9.735610317245317 180.0 -83.082662059893 83.13253115922213 45.415555943211444 -6.917337940106983 83.13253115922211 314.5844440567886 -45.0 9.73561031724532 180.0 -256.36129272052347 45.81931182053556 279.59803029876775 -256.36129272052347 45.81931182053556 279.59803029876775 -315.0 99.73561031724536 0.0 +1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos +96.91733794010702 83.13253115922213 314.5844440567886 1 1 +173.082662059893 83.13253115922211 45.41555594321143 1 2 +135.0 9.735610317245317 180.0 1 3 +263.082662059893 83.13253115922213 45.415555943211444 1 4 +186.91733794010702 83.13253115922211 314.5844440567886 1 5 +224.99999999999997 9.735610317245317 180.0 1 6 +83.082662059893 83.13253115922213 45.415555943211444 1 7 +6.917337940106983 83.13253115922211 314.5844440567886 1 8 +45.0 9.73561031724532 180.0 1 9 +256.36129272052347 45.81931182053556 279.59803029876775 1 10 +256.36129272052347 45.81931182053556 279.59803029876775 1 11 +315.0 99.73561031724536 0.0 1 12 diff --git a/python/tests/reference/Rotation/fcc_Pitsch.txt b/python/tests/reference/Rotation/fcc_Pitsch.txt index a2369f0a4..aa0c32365 100644 --- a/python/tests/reference/Rotation/fcc_Pitsch.txt +++ b/python/tests/reference/Rotation/fcc_Pitsch.txt @@ -1,14 +1,14 @@ 1 header -1_Eulers 2_Eulers 3_Eulers -135.41555594321144 83.13253115922213 173.082662059893 -260.26438968275465 90.0 135.0 -260.40196970123213 45.81931182053557 13.638707279476478 -314.5844440567886 83.13253115922213 96.91733794010702 -350.40196970123213 45.81931182053557 283.6387072794765 -170.26438968275465 90.0 224.99999999999997 -315.4155559432114 83.13253115922213 353.08266205989304 -99.73561031724536 90.0 225.0 -279.59803029876787 45.819311820535574 166.36129272052352 -134.58444405678856 83.13253115922213 276.91733794010696 -9.598030298767851 45.819311820535574 76.36129272052355 -9.735610317245369 90.0 315.0 +1_Eulers 2_Eulers 3_Eulers 1_pos 2_pos +135.41555594321144 83.13253115922213 173.082662059893 1 1 +260.26438968275465 90.0 135.0 1 2 +260.40196970123213 45.81931182053557 13.638707279476478 1 3 +314.5844440567886 83.13253115922213 96.91733794010702 1 4 +350.40196970123213 45.81931182053557 283.6387072794765 1 5 +170.26438968275465 90.0 224.99999999999997 1 6 +315.4155559432114 83.13253115922213 353.08266205989304 1 7 +99.73561031724536 90.0 225.0 1 8 +279.59803029876787 45.819311820535574 166.36129272052352 1 9 +134.58444405678856 83.13253115922213 276.91733794010696 1 10 +9.598030298767851 45.819311820535574 76.36129272052355 1 11 +9.735610317245369 90.0 315.0 1 12 diff --git a/python/tests/test_Rotation.py b/python/tests/test_Rotation.py index a4dc7c61d..08d543554 100644 --- a/python/tests/test_Rotation.py +++ b/python/tests/test_Rotation.py @@ -74,6 +74,8 @@ class TestRotation: ori = Orientation(Rotation(),lattice) eu = np.array([o.rotation.asEulers(degrees=True) for o in ori.relatedOrientations(model)]) if update: + coords = np.array([(1,i+1) for i,x in enumerate(eu)]) table = damask.Table(eu,{'Eulers':(3,)}) + table.add('pos',coords) table.to_ASCII(reference) assert np.allclose(eu,damask.Table.from_ASCII(reference).get('Eulers')) From 1fcbc356114e833653eb430b718d55032693d21c Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 9 Dec 2019 05:25:22 +0100 Subject: [PATCH 33/78] untested python2.7 code complicated code. Easier to re-implement from scratch if really needed --- processing/misc/yieldSurface.py | 1431 ------------------------- processing/misc/yieldSurfaceFast.py | 1513 --------------------------- 2 files changed, 2944 deletions(-) delete mode 100755 processing/misc/yieldSurface.py delete mode 100755 processing/misc/yieldSurfaceFast.py diff --git a/processing/misc/yieldSurface.py b/processing/misc/yieldSurface.py deleted file mode 100755 index 28f52062f..000000000 --- a/processing/misc/yieldSurface.py +++ /dev/null @@ -1,1431 +0,0 @@ -#!/usr/bin/env python2.7 -# -*- coding: UTF-8 no BOM -*- - -import threading,time,os -import numpy as np -from optparse import OptionParser -import damask -from damask.util import leastsqBound - -scriptName = os.path.splitext(os.path.basename(__file__))[0] -scriptID = ' '.join([scriptName,damask.version]) - -def runFit(exponent, eqStress, dimension, criterion): - global threads, myFit, myLoad - global fitResidual - global Guess, dDim - - dDim = dimension - 3 - nParas = len(fitCriteria[criterion]['bound'][dDim]) - nExpo = fitCriteria[criterion]['nExpo'] - - if exponent > 0.0: # User defined exponents - nParas = nParas-nExpo - fitCriteria[criterion]['bound'][dDim] = fitCriteria[criterion]['bound'][dDim][:nParas] - - for i in range(nParas): - temp = fitCriteria[criterion]['bound'][dDim][i] - if fitCriteria[criterion]['bound'][dDim][i] == (None,None): - Guess.append(1.0) - else: - g = (temp[0]+temp[1])/2.0 - if g == 0: g = temp[1]*0.5 - Guess.append(g) - - myLoad = Loadcase(options.load[0],options.load[1],options.load[2], - nSet = 10, dimension = dimension, vegter = options.criterion=='vegter') - - - myFit = Criterion(exponent,eqStress, dimension, criterion) - for t in range(options.threads): - threads.append(myThread(t)) - threads[t].start() - - for t in range(options.threads): - threads[t].join() - damask.util.croak('Residuals') - damask.util.croak(fitResidual) - -def principalStresses(sigmas): - """ - Computes principal stresses (i.e. eigenvalues) for a set of Cauchy stresses. - - sorted in descending order. - """ - lambdas=np.zeros(0,'d') - for i in range(np.shape(sigmas)[1]): - eigenvalues = np.linalg.eigvalsh(sym6toT33(sigmas[:,i])) - lambdas = np.append(lambdas,np.sort(eigenvalues)[::-1]) #append eigenvalues in descending order - lambdas = np.transpose(lambdas.reshape(np.shape(sigmas)[1],3)) - return lambdas - -def principalStress(p): - I = invariant(p) - - I1s3I2= (I[0]**2 - 3.0*I[1])**0.5 - numer = 2.0*I[0]**3 - 9.0*I[0]*I[1] + 27.0*I[2] - denom = 2.0*I1s3I2**3 - cs = numer/denom - - phi = np.arccos(cs)/3.0 - t1 = I[0]/3.0; t2 = 2.0/3.0*I1s3I2 - return np.array( [t1 + t2*np.cos(phi), - t1 + t2*np.cos(phi+np.pi*2.0/3.0), - t1 + t2*np.cos(phi+np.pi*4.0/3.0)]) - -def principalStrs_Der(p, s, dim, Karafillis=False): - """Derivative of principal stress with respect to stress""" - third = 1.0/3.0 - third2 = 2.0*third - - I = invariant(p) - I1s3I2= np.sqrt(I[0]**2 - 3.0*I[1]) - numer = 2.0*I[0]**3 - 9.0*I[0]*I[1] + 27.0*I[2] - denom = 2.0*I1s3I2**3 - cs = numer/denom - phi = np.arccos(cs)/3.0 - - dphidcs = -third/np.sqrt(1.0 - cs**2) - dcsddenom = 0.5*numer*(-1.5)*I1s3I2**(-5.0) - dcsdI1 = (6.0*I[0]**2 - 9.0*I[1])*denom + dcsddenom*(2.0*I[0]) - dcsdI2 = ( - 9.0*I[0])*denom + dcsddenom*(-3.0) - dcsdI3 = 27.0*denom - dphidI1, dphidI2, dphidI3 = dphidcs*dcsdI1, dphidcs*dcsdI2, dphidcs*dcsdI3 - - dI1s3I2dI1 = I[0]/I1s3I2 - dI1s3I2dI2 = -1.5/I1s3I2 - tcoeff = third2*I1s3I2 - - dSidIj = lambda theta : ( tcoeff*(-np.sin(theta))*dphidI1 + third2*dI1s3I2dI1*np.cos(theta) + third, - tcoeff*(-np.sin(theta))*dphidI2 + third2*dI1s3I2dI2*np.cos(theta), - tcoeff*(-np.sin(theta))*dphidI3) - dSdI = np.array([dSidIj(phi),dSidIj(phi+np.pi*2.0/3.0),dSidIj(phi+np.pi*4.0/3.0)]) # i=1,2,3; j=1,2,3 - -# calculate the derivation of principal stress with regards to the anisotropic coefficients - one = np.ones_like(s); zero = np.zeros_like(s); num = len(s) - dIdp = np.array([[one, one, one, zero, zero, zero], - [p[1]+p[2], p[2]+p[0], p[0]+p[1], -2.0*p[3], -2.0*p[4], -2.0*p[5]], - [p[1]*p[2]-p[4]**2, p[2]*p[0]-p[5]**2, p[0]*p[1]-p[3]**2, - -2.0*p[3]*p[2]+2.0*p[4]*p[5], -2.0*p[4]*p[0]+2.0*p[5]*p[3], -2.0*p[5]*p[1]+2.0*p[3]*p[4]] ]) - if Karafillis: - dpdc = np.array([[zero,s[0]-s[2],s[0]-s[1]], [s[1]-s[2],zero,s[1]-s[0]], [s[2]-s[1],s[2]-s[0],zero]])/3.0 - dSdp = np.array([np.dot(dSdI[:,:,i],dIdp[:,:,i]).T for i in range(num)]).T - if dim == 2: - temp = np.vstack([dSdp[:,3]*s[3]]).T.reshape(num,1,3).T - else: - temp = np.vstack([dSdp[:,3]*s[3],dSdp[:,4]*s[4],dSdp[:,5]*s[5]]).T.reshape(num,3,3).T - - return np.concatenate((np.array([np.dot(dSdp[:,0:3,i], dpdc[:,:,i]).T for i in range(num)]).T, - temp), axis=1) - else: - if dim == 2: - dIdc=np.array([[-dIdp[i,0]*s[1], -dIdp[i,1]*s[0], -dIdp[i,1]*s[2], - -dIdp[i,2]*s[1], -dIdp[i,2]*s[0], -dIdp[i,0]*s[2], - dIdp[i,3]*s[3] ] for i in range(3)]) - else: - dIdc=np.array([[-dIdp[i,0]*s[1], -dIdp[i,1]*s[0], -dIdp[i,1]*s[2], - -dIdp[i,2]*s[1], -dIdp[i,2]*s[0], -dIdp[i,0]*s[2], - dIdp[i,3]*s[3], dIdp[i,4]*s[4], dIdp[i,5]*s[5] ] for i in range(3)]) - return np.array([np.dot(dSdI[:,:,i],dIdc[:,:,i]).T for i in range(num)]).T - -def invariant(sigmas): - I = np.zeros(3) - s11,s22,s33,s12,s23,s31 = sigmas - I[0] = s11 + s22 + s33 - I[1] = s11*s22 + s22*s33 + s33*s11 - s12**2 - s23**2 - s31**2 - I[2] = s11*s22*s33 + 2.0*s12*s23*s31 - s12**2*s33 - s23**2*s11 - s31**2*s22 - return I - -def math_ln(x): - return np.log(x + 1.0e-32) - -def sym6toT33(sym6): - """Shape the symmetric stress tensor(6) into (3,3)""" - return np.array([[sym6[0],sym6[3],sym6[5]], - [sym6[3],sym6[1],sym6[4]], - [sym6[5],sym6[4],sym6[2]]]) - -def t33toSym6(t33): - """Shape the stress tensor(3,3) into symmetric (6)""" - return np.array([ t33[0,0], - t33[1,1], - t33[2,2], - (t33[0,1] + t33[1,0])/2.0, # 0 3 5 - (t33[1,2] + t33[2,1])/2.0, # * 1 4 - (t33[2,0] + t33[0,2])/2.0,]) # * * 2 - -class Criteria(object): - def __init__(self, criterion, uniaxialStress,exponent, dimension): - self.stress0 = uniaxialStress - if exponent < 0.0: # Fitting exponent m - self.mFix = [False, exponent] - else: # fixed exponent m - self.mFix = [True, exponent] - self.func = fitCriteria[criterion]['func'] - self.criteria = criterion - self.dim = dimension - def fun(self, paras, ydata, sigmas): - return self.func(self.stress0, paras, sigmas,self.mFix,self.criteria,self.dim) - def jac(self, paras, ydata, sigmas): - return self.func(self.stress0, paras, sigmas,self.mFix,self.criteria,self.dim,Jac=True) - -class Vegter(object): - """Vegter yield criterion""" - - def __init__(self, refPts, refNormals,nspace=11): - self.refPts, self.refNormals = self._getRefPointsNormals(refPts, refNormals) - self.hingePts = self._getHingePoints() - self.nspace = nspace - def _getRefPointsNormals(self,refPtsQtr,refNormalsQtr): - if len(refPtsQtr) == 12: - refPts = refPtsQtr - refNormals = refNormalsQtr - else: - refPts = np.empty([13,2]) - refNormals = np.empty([13,2]) - refPts[12] = refPtsQtr[0] - refNormals[12] = refNormalsQtr[0] - for i in range(3): - refPts[i] = refPtsQtr[i] - refPts[i+3] = refPtsQtr[3-i][::-1] - refPts[i+6] =-refPtsQtr[i] - refPts[i+9] =-refPtsQtr[3-i][::-1] - refNormals[i] = refNormalsQtr[i] - refNormals[i+3] = refNormalsQtr[3-i][::-1] - refNormals[i+6] =-refNormalsQtr[i] - refNormals[i+9] =-refNormalsQtr[3-i][::-1] - return refPts,refNormals - - def _getHingePoints(self): - """ - Calculate the hinge point B according to the reference points A,C and the normals n,m - - refPoints = np.array([[p1_x, p1_y], [p2_x, p2_y]]); - refNormals = np.array([[n1_x, n1_y], [n2_x, n2_y]]) - """ - def hingPoint(points, normals): - A1 = points[0][0]; A2 = points[0][1] - C1 = points[1][0]; C2 = points[1][1] - n1 = normals[0][0]; n2 = normals[0][1] - m1 = normals[1][0]; m2 = normals[1][1] - B1 = (m2*(n1*A1 + n2*A2) - n2*(m1*C1 + m2*C2))/(n1*m2-m1*n2) - B2 = (n1*(m1*C1 + m2*C2) - m1*(n1*A1 + n2*A2))/(n1*m2-m1*n2) - return np.array([B1,B2]) - return np.array([hingPoint(self.refPts[i:i+2],self.refNormals[i:i+2]) for i in range(len(self.refPts)-1)]) - - def getBezier(self): - def bezier(R,H): - b = [] - for mu in np.linspace(0.0,1.0,self.nspace): - b.append(np.array(R[0]*np.ones_like(mu) + 2.0*mu*(H - R[0]) + mu**2*(R[0]+R[1] - 2.0*H))) - return b - return np.array([bezier(self.refPts[i:i+2],self.hingePts[i]) for i in range(len(self.refPts)-1)]) - -def VetgerCriterion(stress,lankford, rhoBi0, theta=0.0): - """0-pure shear; 1-uniaxial; 2-plane strain; 3-equi-biaxial""" - def getFourierParas(r): - # get the value after Fourier transformation - nset = len(r) - lmatrix = np.empty([nset,nset]) - theta = np.linspace(0.0,np.pi/2,nset) - for i,th in enumerate(theta): - lmatrix[i] = np.array([np.cos(2*j*th) for j in range(nset)]) - return np.linalg.solve(lmatrix, r) - - nps = len(stress) - if nps%4 != 0: - damask.util.croak('Warning: the number of stress points is uncorrect, stress points of %s are missing in set %i'%( - ['eq-biaxial, plane strain & uniaxial', 'eq-biaxial & plane strain','eq-biaxial'][nps%4-1],nps/4+1)) - else: - nset = nps/4 - strsSet = stress.reshape(nset,4,2) - refPts = np.empty([4,2]) - - fouriercoeffs = np.array([np.cos(2.0*i*theta) for i in range(nset)]) - for i in range(2): - refPts[3,i] = sum(strsSet[:,3,i])/nset - for j in range(3): - refPts[j,i] = np.dot(getFourierParas(strsSet[:,j,i]), fouriercoeffs) - - -def Tresca(eqStress=None, #not needed/supported - paras=None, - sigmas=None, - mFix=None, #not needed/supported - criteria=None, #not needed/supported - dim=3, - Jac=False): - """ - Tresca yield criterion - - the fitted parameter is paras(sigma0) - """ - if not Jac: - lambdas = principalStresses(sigmas) - r = np.amax(np.array([abs(lambdas[2,:]-lambdas[1,:]),\ - abs(lambdas[1,:]-lambdas[0,:]),\ - abs(lambdas[0,:]-lambdas[2,:])]),0) - paras - return r.ravel() - else: - return -np.ones(len(sigmas)) - -def Cazacu_Barlat(eqStress=None, - paras=None, - sigmas=None, - mFix=None,#not needed/supported - criteria=None, - dim=3, #2D also possible - Jac=False): - """ - Cazacu-Barlat (CB) yield criterion - - the fitted parameters are: - a1,a2,a3,a6; b1,b2,b3,b4,b5,b10; c for plane stress - a1,a2,a3,a4,a5,a6; b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11; c: for general case - mFix is ignored - """ - s11,s22,s33,s12,s23,s31 = sigmas - if dim == 2: - (a1,a2,a3,a4), (b1,b2,b3,b4,b5,b10), c = paras[0:4],paras[4:10],paras[10] - a5 = a6 = b6 = b7 = b8 = b9 = b11 = 0.0 - s33 = s23 = s31 = np.zeros_like(s11) - else: - (a1,a2,a3,a4,a5,a6), (b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11), c = paras[0:6],paras[6:17],paras[17] - - s1_2, s2_2, s3_2, s12_2, s23_2, s31_2 = np.array([s11,s22,s33,s12,s23,s31])**2 - s1_3, s2_3, s3_3, s123, s321 = s11*s1_2, s22*s2_2, s33*s3_2,s11*s22*s33, s12*s23*s31 - d12_2,d23_2,d31_2 = (s11-s22)**2, (s22-s33)**2, (s33-s11)**2 - - J20 = ( a1*d12_2 + a2*d23_2 + a3*d31_2 )/6.0 + a4*s12_2 + a5*s23_2 + a6*s31_2 - J30 = ( (b1 +b2 )*s1_3 + (b3 +b4 )*s2_3 + ( b1+b4-b2 + b1+b4-b3 )*s3_3 )/27.0- \ - ( (b1*s22+b2*s33)*s1_2 + (b3*s33+b4*s11)*s2_2 + ((b1+b4-b2)*s11 + (b1+b4-b3)*s22)*s3_2 )/9.0 + \ - ( (b1+b4)*s123/9.0 + b11*s321 )*2.0 - \ - ( ( 2.0*b9 *s22 - b8*s33 - (2.0*b9 -b8)*s11 )*s31_2 + - ( 2.0*b10*s33 - b5*s22 - (2.0*b10-b5)*s11 )*s12_2 + - ( (b6+b7)*s11 - b6*s22 - b7*s33 )*s23_2 - )/3.0 - f0 = J20**3 - c*J30**2 - r = f0**(1.0/6.0)*np.sqrt(3.0)/eqStress - - if not Jac: - return (r - 1.0).ravel() - else: - drdf = r/f0/6.0 - dj2, dj3 = drdf*3.0*J20**2, -drdf*2.0*J30*c - jc = -drdf*J30**2 - - ja1,ja2,ja3 = dj2*d12_2/6.0, dj2*d23_2/6.0, dj2*d31_2/6.0 - ja4,ja5,ja6 = dj2*s12_2, dj2*s23_2, dj2*s31_2 - jb1 = dj3*( (s1_3 + 2.0*s3_3)/27.0 - s22*s1_2/9.0 - (s11+s22)*s3_2/9.0 + s123/4.5 ) - jb2 = dj3*( (s1_3 - s3_3)/27.0 - s33*s1_2/9.0 + s11 *s3_2/9.0 ) - jb3 = dj3*( (s2_3 - s3_3)/27.0 - s33*s2_2/9.0 + s22 *s3_2/9.0 ) - jb4 = dj3*( (s2_3 + 2.0*s3_3)/27.0 - s11*s2_2/9.0 - (s11+s22)*s3_2/9.0 + s123/4.5 ) - - jb5, jb10 = dj3*(s22 - s11)*s12_2/3.0, dj3*(s11 - s33)*s12_2/1.5 - jb6, jb7 = dj3*(s22 - s11)*s23_2/3.0, dj3*(s33 - s11)*s23_2/3.0 - jb8, jb9 = dj3*(s33 - s11)*s31_2/3.0, dj3*(s11 - s22)*s31_2/1.5 - jb11 = dj3*s321*2.0 - if dim == 2: - return np.vstack((ja1,ja2,ja3,ja4,jb1,jb2,jb3,jb4,jb5,jb10,jc)).T - else: - return np.vstack((ja1,ja2,ja3,ja4,ja5,ja6,jb1,jb2,jb3,jb4,jb5,jb6,jb7,jb8,jb9,jb10,jb11,jc)).T - -def Drucker(eqStress=None,#not needed/supported - paras=None, - sigmas=None, - mFix=None, #not needed/supported - criteria=None, - dim=3, - Jac=False): - """ - Drucker yield criterion - - the fitted parameters are - sigma0, C_D for Drucker(p=1); - sigma0, C_D, p for general Drucker - eqStress, mFix are invalid inputs - """ - if criteria == 'drucker': - sigma0, C_D= paras - p = 1.0 - else: - sigma0, C_D = paras[0:2] - if mFix[0]: p = mFix[1] - else: p = paras[-1] - I = invariant(sigmas) - J = np.zeros([3]) - J[1] = I[0]**2/3.0 - I[1] - J[2] = I[0]**3/13.5 - I[0]*I[1]/3.0 + I[2] - J2_3p = J[1]**(3.0*p) - J3_2p = J[2]**(2.0*p) - left = J2_3p - C_D*J3_2p - r = left**(1.0/(6.0*p))*3.0**0.5/sigma0 - - if not Jac: - return (r - 1.0).ravel() - else: - drdl = r/left/(6.0*p) - if criteria == 'drucker': - return np.vstack((-r/sigma0, -drdl*J3_2p)).T - else: - dldp = 3.0*J2_3p*math_ln(J[1]) - 2.0*C_D*J3_2p*math_ln(J[2]) - jp = drdl*dldp + r*math_ln(left)/(-6.0*p*p) - - if mFix[0]: return np.vstack((-r/sigma0, -drdl*J3_2p)).T - else: return np.vstack((-r/sigma0, -drdl*J3_2p, jp)).T - -def Hill1948(eqStress=None,#not needed/supported - paras=None, - sigmas=None, - mFix=None, #not needed/supported - criteria=None,#not needed/supported - dim=3, - Jac=False): - """ - Hill 1948 yield criterion - - the fitted parameters are: - F, G, H, L, M, N for 3D - F, G, H, N for 2D - """ - s11,s22,s33,s12,s23,s31 = sigmas - if dim == 2: # plane stress - jac = np.array([ s22**2, s11**2, (s11-s22)**2, 2.0*s12**2]) - else: # general case - jac = np.array([(s22-s33)**2,(s33-s11)**2,(s11-s22)**2, 2.0*s23**2,2.0*s31**2,2.0*s12**2]) - - if not Jac: - return (np.dot(paras,jac)/2.0-0.5).ravel() - else: - return jac.T - -def Hill1979(eqStress=None,#not needed/supported - paras=None, - sigmas=None, - mFix=None, - criteria=None,#not needed/supported - dim=3, - Jac=False): - """ - Hill 1979 yield criterion - - the fitted parameters are: f,g,h,a,b,c,m - """ - if mFix[0]: - m = mFix[1] - else: - m = paras[-1] - - coeff = paras[0:6] - s = principalStresses(sigmas) - diffs = np.array([s[1]-s[2], s[2]-s[0], s[0]-s[1],\ - 2.0*s[0]-s[1]-s[2], 2.0*s[1]-s[2]-s[0], 2.0*s[2]-s[0]-s[1]])**2 - - diffsm = diffs**(m/2.0) - left = np.dot(coeff,diffsm) - r = (0.5*left)**(1.0/m)/eqStress #left = base**mi - - if not Jac: - return (r-1.0).ravel() - else: - drdl, dldm = r/left/m, np.dot(coeff,diffsm*math_ln(diffs))*0.5 - jm = drdl*dldm + r*math_ln(0.5*left)*(-1.0/m/m) #/(-m**2) - - if mFix[0]: return np.vstack((drdl*diffsm)).T - else: return np.vstack((drdl*diffsm, jm)).T - -def Hosford(eqStress=None, - paras=None, - sigmas=None, - mFix=None, - criteria=None, - dim=3, - Jac=False): - """ - Hosford family criteria - - the fitted parameters are: - von Mises: sigma0 - Hershey: (1) sigma0, a, when a is not fixed; (2) sigma0, when a is fixed - general Hosford: (1) F,G,H, a, when a is not fixed; (2) F,G,H, when a is fixed - """ - if criteria == 'vonmises': - sigma0 = paras - coeff = np.ones(3) - a = 2.0 - elif criteria == 'hershey': - sigma0 = paras[0] - coeff = np.ones(3) - if mFix[0]: a = mFix[1] - else: a = paras[1] - else: - sigma0 = eqStress - coeff = paras[0:3] - if mFix[0]: a = mFix[1] - else: a = paras[3] - - s = principalStresses(sigmas) - diffs = np.array([s[1]-s[2], s[2]-s[0], s[0]-s[1]])**2 - diffsm = diffs**(a/2.0) - left = np.dot(coeff,diffsm) - r = (0.5*left)**(1.0/a)/sigma0 - - if not Jac: - return (r-1.0).ravel() - else: - if criteria == 'vonmises': # von Mises - return -r/sigma0 - else: - drdl, dlda = r/left/a, np.dot(coeff,diffsm*math_ln(diffs))*0.5 - ja = drdl*dlda + r*math_ln(0.5*left)*(-1.0/a/a) - if criteria == 'hershey': # Hershey - if mFix[0]: return -r/sigma0 - else: return np.vstack((-r/sigma0, ja)).T - else: # Anisotropic Hosford - if mFix[0]: return np.vstack((drdl*diffsm)).T - else: return np.vstack((drdl*diffsm, ja)).T - -def Barlat1989(eqStress=None, - paras=None, - sigmas=None, - mFix=None, - criteria=None, - dim=3, - Jac=False): - """ - Barlat-Lian 1989 yield criteria - - the fitted parameters are: - Anisotropic: a, h, p, m; m is optional - """ - a, h, p = paras[0:3] - if mFix[0]: m = mFix[1] - else: m = paras[-1] - - c = 2.0-a - s11,s22,s12 = sigmas[0], sigmas[1], sigmas[3] - k1,k2 = 0.5*(s11 + h*s22), (0.25*(s11 - h*s22)**2 + (p*s12)**2)**0.5 - fs = np.array([ (k1+k2)**2, (k1-k2)**2, 4.0*k2**2 ]); fm = fs**(m/2.0) - left = np.dot(np.array([a,a,c]),fm) - r = (0.5*left)**(1.0/m)/eqStress - - if not Jac: - return (r-1.0).ravel() - else: - dk1dh = 0.5*s22 - dk2dh, dk2dp = 0.25*(s11-h*s22)*(-s22)/k2, p*s12**2/k2 - dlda, dldc = fm[0]+fm[1], fm[2] - fm1 = fs**(m/2.0-1.0)*m - dldk1, dldk2 = a*fm1[0]*(k1+k2)+a*fm1[1]*(k1-k2), a*fm1[0]*(k1+k2)-a*fm1[1]*(k1-k2)+c*fm1[2]*k2*4.0 - drdl, drdm = r/m/left, r*math_ln(0.5*left)*(-1.0/m/m) - dldm = np.dot(np.array([a,a,c]),fm*math_ln(fs))*0.5 - - ja,jc = drdl*dlda, drdl*dldc - jh,jp = drdl*(dldk1*dk1dh + dldk2*dk2dh), drdl*dldk2*dk2dp - jm = drdl*dldm + drdm - - if mFix[0]: return np.vstack((ja,jc,jh,jp)).T - else: return np.vstack((ja,jc,jh,jp,jm)).T - -def Barlat1991(eqStress, paras, sigmas, mFix, criteria, dim, Jac=False): - """ - Barlat 1991 criteria - - the fitted parameters are: - Anisotropic: a, b, c, f, g, h, m for 3D - a, b, c, h, m for plane stress - m is optional - """ - if dim == 2: coeff = paras[0:4] # plane stress - else: coeff = paras[0:6] # general case - if mFix[0]: m = mFix[1] - else: m = paras[-1] - - s11,s22,s33,s12,s23,s31 = sigmas - if dim == 2: - dXdx = np.array([s22,-s11,s11-s22,s12]) - A,B,C,H = np.array(coeff)[:,None]*dXdx; F=G=0.0 - else: - dXdx = np.array([s22-s33,s33-s11,s11-s22,s23,s31,s12]) - A,B,C,F,G,H = np.array(coeff)[:,None]*dXdx - - I2 = (F*F + G*G + H*H)/3.0+ ((A-C)**2+(C-B)**2+(B-A)**2)/54.0 - I3 = (C-B)*(A-C)*(B-A)/54.0 + F*G*H - ((C-B)*F*F + (A-C)*G*G + (B-A)*H*H)/6.0 - phi1 = np.arccos(I3/I2**1.5)/3.0 + np.pi/6.0; absc1 = 2.0*np.abs(np.cos(phi1)) - phi2 = phi1 + np.pi/3.0; absc2 = 2.0*np.abs(np.cos(phi2)) - phi3 = phi2 + np.pi/3.0; absc3 = 2.0*np.abs(np.cos(phi3)) - left = ( absc1**m + absc2**m + absc3**m ) - r = (0.5*left)**(1.0/m)*np.sqrt(3.0*I2)/eqStress - - if not Jac: - return (r - 1.0).ravel() - else: - dfdl = r/left/m - jm = r*math_ln(0.5*left)*(-1.0/m/m) + dfdl*0.5*( - absc1**m*math_ln(absc1) + absc2**m*math_ln(absc2) + absc3**m*math_ln(absc3) ) - - da,db,dc = (2.0*A-B-C)/18.0, (2.0*B-C-A)/18.0, (2.0*C-A-B)/18.0 - if dim == 2: - dI2dx = np.array([da, db, dc, H])/1.5*dXdx - dI3dx = np.array([ da*(B-C) + (H**2-G**2)/2.0, - db*(C-A) + (F**2-H**2)/2.0, - dc*(A-B) + (G**2-F**2)/2.0, - (G*F + (A-B))*H ])/3.0*dXdx - else: - dI2dx = np.array([da, db, dc, F,G,H])/1.5*dXdx - dI3dx = np.array([ da*(B-C) + (H**2-G**2)/2.0, - db*(C-A) + (F**2-H**2)/2.0, - dc*(A-B) + (G**2-F**2)/2.0, - (H*G*3.0 + (B-C))*F, - (F*H*3.0 + (C-A))*G, - (G*F*3.0 + (A-B))*H ])/3.0*dXdx - darccos = -1.0/np.sqrt(1.0 - I3**2/I2**3) - - dfdcos = lambda phi : dfdl*m*(2.0*abs(np.cos(phi)))**(m-1.0)*np.sign(np.cos(phi))*(-np.sin(phi)/1.5) - - dfdthe= (dfdcos(phi1) + dfdcos(phi2) + dfdcos(phi3)) - dfdI2, dfdI3 = dfdthe*darccos*I3*(-1.5)*I2**(-2.5)+r/2.0/I2, dfdthe*darccos*I2**(-1.5) - - if mFix[0]: return np.vstack((dfdI2*dI2dx + dfdI3*dI3dx)).T - else: return np.vstack((dfdI2*dI2dx + dfdI3*dI3dx, jm)).T - -def BBC2000(eqStress, paras, sigmas, mFix, criteria, dim, Jac=False): - """ - BBC2000 yield criterion - - the fitted parameters are - d,e,f,g, b,c,a, k; k is optional - criteria are invalid input - """ - d,e,f,g, b,c,a= paras[0:7] - if mFix[0]: k = mFix[1] - else: k = paras[-1] - - s11,s22,s12 = sigmas[0], sigmas[1], sigmas[3] - k2 = 2.0*k; k1 = k - 1.0 - M,N,P,Q,R = d+e, e+f, (d-e)/2.0, (e-f)/2.0, g**2 - Gamma = M*s11 + N*s22 - Psi = ( (P*s11 + Q*s22)**2 + s12**2*R )**0.5 - - l1, l2, l3 = b*Gamma + c*Psi, b*Gamma - c*Psi, 2.0*c*Psi - l1s,l2s,l3s = l1**2, l2**2, l3**2 - - left = a*l1s**k + a*l2s**k + (1-a)*l3s**k - r = left**(1.0/k2)/eqStress - if not Jac: - return (r - 1.0).ravel() - else: - drdl,drdk = r/left/k2, r*math_ln(left)*(-1.0/k2/k) - dldl1,dldl2,dldl3 = a*k2*(l1s**k1)*l1, a*k2*(l2s**k1)*l2, (1-a)*k2*(l3s**k1)*l3 - dldGama, dldPsi = (dldl1 + dldl2)*b, (dldl1 - dldl2 + 2.0*dldl3)*c - temp = (P*s11 + Q*s22)/Psi - dPsidP, dPsidQ, dPsidR = temp*s11, temp*s22, 0.5*s12**2/Psi - dlda = l1s**k + l2s**k - l3s**k - dldb = dldl1*Gamma + dldl2*Gamma - dldc = dldl1*Psi - dldl2*Psi + dldl3*2.0*Psi - dldk = a*math_ln(l1s)*l1s**k + a*math_ln(l2s)*l2s**k + (1-a)*math_ln(l3s)*l3s**k - - J = drdl*np.array([dldGama*s11+dldPsi*dPsidP*0.5, dldGama*(s11+s22)+dldPsi*(-dPsidP+dPsidQ)*0.5, #jd,je - dldGama*s22-dldPsi*dPsidQ*0.5, dldPsi*dPsidR*2.0*g, #jf,jg - dldb, dldc, dlda]) #jb,jc,ja - if mFix[0]: return np.vstack(J).T - else: return np.vstack((J, drdl*dldk + drdk)).T - - -def BBC2003(eqStress, paras, sigmas, mFix, criteria, dim, Jac=False): - """ - BBC2003 yield criterion - - the fitted parameters are - M,N,P,Q,R,S,T,a, k; k is optional - criteria are invalid input - """ - M,N,P,Q,R,S,T,a = paras[0:8] - if mFix[0]: k = mFix[1] - else: k = paras[-1] - - s11,s22,s12 = sigmas[0], sigmas[1], sigmas[3] - k2 = 2.0*k; k1 = k - 1.0 - Gamma = 0.5 * (s11 + M*s22) - Psi = ( 0.25*(N*s11 - P*s22)**2 + Q*Q*s12**2 )**0.5 - Lambda = ( 0.25*(R*s11 - S*s22)**2 + T*T*s12**2 )**0.5 - - l1, l2, l3 = Gamma + Psi, Gamma - Psi, 2.0*Lambda - l1s,l2s,l3s = l1**2, l2**2, l3**2 - left = a*l1s**k + a*l2s**k + (1-a)*l3s**k - r = left**(1.0/k2)/eqStress - if not Jac: - return (r - 1.0).ravel() - else: - drdl,drdk = r/left/k2, r*math_ln(left)*(-1.0/k2/k) - dldl1,dldl2,dldl3 = a*k2*(l1s**k1)*l1, a*k2*(l2s**k1)*l2, (1-a)*k2*(l3s**k1)*l3 - - dldGamma, dldPsi, dldLambda = dldl1+dldl2, dldl1-dldl2, 2.0*dldl3 - temp = 0.25/Psi*(N*s11 - P*s22) - dPsidN, dPsidP, dPsidQ = s11*temp, -s22*temp, Q*s12**2/Psi - temp = 0.25/Lambda*(R*s11 - S*s22) - dLambdadR, dLambdadS, dLambdadT = s11*temp, -s22*temp, T*s12**2/Psi - dldk = a*math_ln(l1s)*l1s**k + a*math_ln(l2s)*l2s**k + (1-a)*math_ln(l3s)*l3s**k - - J = drdl * np.array([dldGamma*s22*0.5, #jM - dldPsi*dPsidN, dldPsi*dPsidP, dldPsi*dPsidQ, #jN, jP, jQ - dldLambda*dLambdadR, dldLambda*dLambdadS, dldLambda*dLambdadT, #jR, jS, jT - l1s**k + l2s**k - l3s**k ]) #ja - - if mFix[0]: return np.vstack(J).T - else : return np.vstack((J, drdl*dldk+drdk)).T - -def BBC2005(eqStress, paras, sigmas, mFix, criteria, dim, Jac=False): - """ - BBC2005 yield criterion - - the fitted parameters are - a, b, L ,M, N, P, Q, R, k k are optional - criteria is invalid input - """ - a,b,L, M, N, P, Q, R = paras[0:8] - if mFix[0]: k = mFix[1] - else: k = paras[-1] - - s11 = sigmas[0]; s22 = sigmas[1]; s12 = sigmas[3] - k2 = 2.0*k - Gamma = L*s11 + M*s22 - Lambda = ( (N*s11 - P*s22)**2 + s12**2 )**0.5 - Psi = ( (Q*s11 - R*s22)**2 + s12**2 )**0.5 - - l1 = Lambda + Gamma; l2 = Lambda - Gamma; l3 = Lambda + Psi; l4 = Lambda - Psi - l1s = l1**2; l2s = l2**2; l3s = l3**2; l4s = l4**2 - left = a*l1s**k + a*l2s**k + b*l3s**k + b*l4s**k - sBar = left**(1.0/k2); r = sBar/eqStress - 1.0 - if not Jac: - return r.ravel() - else: - ln = lambda x : np.log(x + 1.0e-32) - expo = 0.5/k; k1 = k-1.0 - - dsBardl = expo*sBar/left/eqStress - dsBarde = sBar*ln(left); dedk = expo/(-k) - dldl1 = a*k*(l1s**k1)*(2.0*l1) - dldl2 = a*k*(l2s**k1)*(2.0*l2) - dldl3 = b*k*(l3s**k1)*(2.0*l3) - dldl4 = b*k*(l4s**k1)*(2.0*l4) - - dldLambda = dldl1 + dldl2 + dldl3 + dldl4 - dldGama = dldl1 - dldl2 - dldPsi = dldl3 - dldl4 - temp = (N*s11 - P*s22)/Lambda - dLambdadN = s11*temp; dLambdadP = -s22*temp - temp = (Q*s11 - R*s22)/Psi - dPsidQ = s11*temp; dPsidR = -s22*temp - dldk = a*ln(l1s)*l1s**k + a*ln(l2s)*l2s**k + b*ln(l3s)*l3s**k + b*ln(l4s)*l4s**k - - J = dsBardl * np.array( [ - l1s**k+l2s**k, l3s**k+l4s**k,dldGama*s11,dldGama*s22,dldLambda*dLambdadN, - dldLambda*dLambdadP, dldPsi*dPsidQ, dldPsi*dPsidR]) - - if mFix[0]: return np.vstack(J).T - else : return np.vstack(J, dldk+dsBarde*dedk).T - -def Yld2000(eqStress, paras, sigmas, mFix, criteria, dim, Jac=False): - """ - Yld2000 yield criterion - - C: c11,c22,c66 c12=c21=1.0 JAC NOT PASS - D: d11,d12,d21,d22,d66 - """ - C,D = paras[0:3], paras[3:8] - if mFix[0]: m = mFix[1] - else: m = paras[-1] - - s11, s22, s12 = sigmas[0],sigmas[1],sigmas[3] - X = np.array([ 2.0*C[0]*s11-C[0]*s22, 2.0*C[1]*s22-C[1]*s11, 3.0*C[2]*s12 ])/3.0 # a1,a2,a7 - Y = np.array([ (8.0*D[2]-2.0*D[0]-2.0*D[3]+2.0*D[1])*s11 + (4.0*D[3]-4.0*D[1]-4.0*D[2]+ D[0])*s22, - (4.0*D[0]-4.0*D[2]-4.0*D[1]+ D[3])*s11 + (8.0*D[1]-2.0*D[3]-2.0*D[0]+2.0*D[2])*s22, - 9.0*D[4]*s12 ])/9.0 - - def priStrs(s): - temp = np.sqrt( (s[0]-s[1])**2 + 4.0*s[2]**2 ) - return 0.5*(s[0]+s[1] + temp), 0.5*(s[0]+s[1] - temp) - m2 = m/2.0; m21 = m2 - 1.0 - (X1,X2), (Y1,Y2) = priStrs(X), priStrs(Y) # Principal values of X, Y - phi1s, phi21s, phi22s = (X1-X2)**2, (2.0*Y2+Y1)**2, (2.0*Y1+Y2)**2 - phi1, phi21, phi22 = phi1s**m2, phi21s**m2, phi22s**m2 - left = phi1 + phi21 + phi22 - r = (0.5*left)**(1.0/m)/eqStress - - if not Jac: - return (r-1.0).ravel() - else: - drdl, drdm = r/m/left, r*math_ln(0.5*left)*(-1.0/m/m) #/(-m*m) - dldm = ( phi1*math_ln(phi1s) + phi21*math_ln(phi21s) + phi22*math_ln(phi22s) )*0.5 - zero = np.zeros_like(s11); num = len(s11) - def dPrincipalds(X): - """Derivative of principla with respect to stress""" - temp = 1.0/np.sqrt( (X[0]-X[1])**2 + 4.0*X[2]**2 ) - dP1dsi = 0.5*np.array([ 1.0+temp*(X[0]-X[1]), 1.0-temp*(X[0]-X[1]), temp*4.0*X[2]]) - dP2dsi = 0.5*np.array([ 1.0-temp*(X[0]-X[1]), 1.0+temp*(X[0]-X[1]), -temp*4.0*X[2]]) - return np.array([dP1dsi, dP2dsi]) - - dXdXi, dYdYi = dPrincipalds(X), dPrincipalds(Y) - dXidC = np.array([ [ 2.0*s11-s22, zero, zero ], #dX11dC - [ zero, 2.0*s22-s11, zero ], #dX22dC - [ zero, zero, 3.0*s12 ] ])/3.0 #dX12dC - dYidD = np.array([ [ -2.0*s11+ s22, 2.0*s11-4.0*s22, 8.0*s11-4.0*s22, -2.0*s11+4.0*s22, zero ], #dY11dD - [ 4.0*s11-2.0*s22, -4.0*s11+8.0*s22, -4.0*s11+2.0*s22, s11-2.0*s22, zero ], #dY22dD - [ zero, zero, zero, zero, 9.0*s12 ] ])/9.0 #dY12dD - - dXdC=np.array([np.dot(dXdXi[:,:,i], dXidC[:,:,i]).T for i in range(num)]).T - dYdD=np.array([np.dot(dYdYi[:,:,i], dYidD[:,:,i]).T for i in range(num)]).T - - dldX = m*np.array([ phi1s**m21*(X1-X2), phi1s**m21*(X2-X1)]) - dldY = m*np.array([phi21s**m21*(2.0*Y2+Y1) + 2.0*phi22s**m21*(2.0*Y1+Y2), \ - phi22s**m21*(2.0*Y1+Y2) + 2.0*phi21s**m21*(2.0*Y2+Y1) ]) - jC = drdl*np.array([np.dot(dldX[:,i], dXdC[:,:,i]) for i in range(num)]).T - jD = drdl*np.array([np.dot(dldY[:,i], dYdD[:,:,i]) for i in range(num)]).T - - jm = drdl*dldm + drdm - if mFix[0]: return np.vstack((jC,jD)).T - else: return np.vstack((jC,jD,jm)).T - -def Yld200418p(eqStress, paras, sigmas, mFix, criteria, dim, Jac=False): - """ - Yld2004-18p yield criterion - - the fitted parameters are - C: c12,c21,c23,c32,c31,c13,c44,c55,c66; D: d12,d21,d23,d32,d31,d13,d44,d55,d66 for 3D - C: c12,c21,c23,c32,c31,c13,c44; D: d12,d21,d23,d32,d31,d13,d44 for 2D - and m, m are optional - criteria is ignored - """ - if dim == 2: C,D = np.append(paras[0:7],[0.0,0.0]), np.append(paras[7:14],[0.0,0.0]) - else: C,D = paras[0:9], paras[9:18] - if mFix[0]: m = mFix[1] - else: m = paras[-1] - - sv = (sigmas[0] + sigmas[1] + sigmas[2])/3.0 - sdev = np.vstack((sigmas[0:3]-sv,sigmas[3:6])) - ys = lambda sdev, C: np.array([-C[0]*sdev[1]-C[5]*sdev[2], -C[1]*sdev[0]-C[2]*sdev[2], - -C[4]*sdev[0]-C[3]*sdev[1], C[6]*sdev[3], C[7]*sdev[4], C[8]*sdev[5]]) - p,q = ys(sdev, C), ys(sdev, D) - pLambdas, qLambdas = principalStress(p), principalStress(q) # no sort - - m2 = m/2.0; x3 = range(3); num = len(sv) - PiQj = np.array([(pLambdas[i,:]-qLambdas[j,:]) for i in x3 for j in x3]) - QiPj = np.array([(qLambdas[i,:]-pLambdas[j,:]) for i in x3 for j in x3]).reshape(3,3,num) - PiQjs = PiQj**2 - left = np.sum(PiQjs**m2,axis=0) - r = (0.25*left)**(1.0/m)/eqStress - - if not Jac: - return (r - 1.0).ravel() - else: - drdl, drdm = r/m/left, r*math_ln(0.25*left)*(-1.0/m/m) - dldm = np.sum(PiQjs**m2*math_ln(PiQjs),axis=0)*0.5 - dPdc, dQdd = principalStrs_Der(p, sdev, dim), principalStrs_Der(q, sdev, dim) - PiQjs3d = ( PiQjs**(m2-1.0) ).reshape(3,3,num) - dldP = -m*np.array([np.diag(np.dot(PiQjs3d[:,:,i], QiPj [:,:,i])) for i in range(num)]).T - dldQ = m*np.array([np.diag(np.dot(QiPj [:,:,i], PiQjs3d[:,:,i])) for i in range(num)]).T - - jm = drdl*dldm + drdm - jc = drdl*np.sum([dldP[i]*dPdc[i] for i in x3],axis=0) - jd = drdl*np.sum([dldQ[i]*dQdd[i] for i in x3],axis=0) - - if mFix[0]: return np.vstack((jc,jd)).T - else: return np.vstack((jc,jd,jm)).T - -def KarafillisBoyce(eqStress, paras, sigmas, mFix, criteria, dim, Jac=False): - """ - Karafillis-Boyce - - the fitted parameters are - c11,c12,c13,c14,c15,c16,c,m for 3D - c11,c12,c13,c14,c,m for plane stress - 0 1 and self.dimen == 2: - return fitCriteria[self.name]['labels'][1] - else: - return fitCriteria[self.name]['labels'][0] - - def report_name(self): - return fitCriteria[self.name]['name'] - - def fit(self,stress): - global fitResults; fitErrors; fitResidual - if options.exponent > 0.0: nExponent = options.exponent - else: nExponent = 0 - nameCriterion = self.name.lower() - criteria = Criteria(nameCriterion,self.uniaxial,self.expo, self.dimen) - bounds = fitCriteria[nameCriterion]['bound'][dDim] # Default bounds, no bound - guess0 = Guess # Default initial guess, depends on bounds - - if fitResults == []: - initialguess = guess0 - else: - initialguess = np.array(fitResults[-1]) - - ydata = np.zeros(np.shape(stress)[1]) - try: - popt, pcov, infodict, errmsg, ierr = \ - leastsqBound (criteria.fun, initialguess, args=(ydata,stress), - bounds=bounds, Dfun=criteria.jac, full_output=True) - if ierr not in [1, 2, 3, 4]: - raise RuntimeError("Optimal parameters not found: "+errmsg) - else: - residual = criteria.fun(popt, ydata, stress) - fitResidual.append(np.linalg.norm(residual)/np.sqrt(len(residual))) - if (len(ydata) > len(initialguess)) and pcov is not None: - s_sq = (criteria.fun(popt, *(ydata,stress))**2).sum()/(len(ydata)-len(initialguess)) - pcov = pcov * s_sq - perr = np.sqrt(np.diag(pcov)) - fitResults.append(popt.tolist()) - fitErrors .append(perr.tolist()) - - popt = np.concatenate((np.array(popt), np.repeat(options.exponent,nExponent))) - perr = np.concatenate((np.array(perr), np.repeat(0.0,nExponent))) - - damask.util.croak('Needed {} function calls for fitting'.format(infodict['nfev'])) - except Exception as detail: - damask.util.croak(detail) - pass - return popt - -#--------------------------------------------------------------------------------------------------- -class myThread (threading.Thread): - """Runner""" - - def __init__(self, threadID): - threading.Thread.__init__(self) - self.threadID = threadID - def run(self): - semaphore.acquire() - conv=converged() - semaphore.release() - while not conv: - doSim(self.name) - semaphore.acquire() - conv=converged() - semaphore.release() - -def doSim(thread): - semaphore.acquire() - global myLoad - loadNo=loadcaseNo() - if not os.path.isfile('%s.load'%loadNo): - damask.util.croak('Generating load case for simulation %s (%s)'%(loadNo,thread)) - f=open('%s.load'%loadNo,'w') - f.write(myLoad.getLoadcase(loadNo)) - f.close() - semaphore.release() - else: semaphore.release() - -# if spectralOut does not exist, run simulation - semaphore.acquire() - if not os.path.isfile('%s_%i.spectralOut'%(options.geometry,loadNo)): - damask.util.croak('Starting simulation %i (%s)'%(loadNo,thread)) - semaphore.release() - damask.util.execute('DAMASK_spectral -g %s -l %i'%(options.geometry,loadNo)) - else: semaphore.release() - -# if ASCII tables do not exist, run postprocessing - semaphore.acquire() - if not os.path.isfile('./postProc/%s_%i.txt'%(options.geometry,loadNo)): - damask.util.croak('Starting post processing for simulation %i (%s)'%(loadNo,thread)) - semaphore.release() - try: - damask.util.execute('postResults --cr f,p --co totalshear %s_%i.spectralOut'%(options.geometry,loadNo)) - except: - damask.util.execute('postResults --cr f,p %s_%i.spectralOut'%(options.geometry,loadNo)) - damask.util.execute('addCauchy ./postProc/%s_%i.txt'%(options.geometry,loadNo)) - damask.util.execute('addStrainTensors -0 -v ./postProc/%s_%i.txt'%(options.geometry,loadNo)) - damask.util.execute('addMises -s Cauchy -e ln(V) ./postProc/%s_%i.txt'%(options.geometry,loadNo)) - else: semaphore.release() - -# reading values from ASCII table (including linear interpolation between points) - semaphore.acquire() - damask.util.croak('Reading values from simulation %i (%s)'%(loadNo,thread)) - refFile = './postProc/%s_%i.txt'%(options.geometry,loadNo) - table = damask.ASCIItable(refFile,readonly=True) - table.head_read() - - thresholdKey = {'equivalentStrain':'Mises(ln(V))', - 'totalshear': 'totalshear', - }[options.fitting] - - for l in [thresholdKey,'1_Cauchy']: - if l not in table.labels(raw = True): damask.util.croak('%s not found'%l) - semaphore.release() - - table.data_readArray(['%i_Cauchy'%(i+1) for i in range(9)]+[thresholdKey]+['%i_ln(V)'%(i+1) for i in range(9)]) - - validity = np.zeros((int(options.yieldValue[2])), dtype=bool) # found data for desired threshold - yieldStress = np.empty((int(options.yieldValue[2]),6),'d') - deformationRate = np.empty((int(options.yieldValue[2]),6),'d') - - line = 0 - for i,threshold in enumerate(np.linspace(options.yieldValue[0],options.yieldValue[1],options.yieldValue[2])): - while line < np.shape(table.data)[0]: - if abs(table.data[line,9])>= threshold: - upper,lower = abs(table.data[line,9]),abs(table.data[line-1,9]) # values for linear interpolation - stress = np.array(table.data[line-1,0:9] * (upper-threshold)/(upper-lower) + \ - table.data[line ,0:9] * (threshold-lower)/(upper-lower)).reshape(3,3) # linear interpolation of stress values - yieldStress[i,:] = t33toSym6(stress) - - dstrain= np.array(table.data[line,10:] - table.data[line-1,10:]).reshape(3,3) - deformationRate[i,:] = t33toSym6(dstrain) - - validity[i] = True - break - else: - line+=1 - if not validity[i]: - semaphore.acquire() - damask.util.croak('The data of result %i at the threshold %f is invalid,'%(loadNo,threshold)\ - +'the fitting at this point is skipped') - semaphore.release() - -# do the actual fitting procedure and write results to file - semaphore.acquire() - global stressAll, strainAll - f=open(options.geometry+'_'+options.criterion+'_'+str(time.time())+'.txt','w') - f.write(' '.join([options.fitting]+myFit.report_labels())+'\n') - try: - for i,threshold in enumerate(np.linspace(options.yieldValue[0],options.yieldValue[1],options.yieldValue[2])): - if validity[i]: - stressAll[i]=np.append(stressAll[i], yieldStress[i]/stressUnit) - strainAll[i]=np.append(strainAll[i], deformationRate[i]) - f.write( str(threshold)+' '+ - ' '.join(map(str,myFit.fit(stressAll[i].reshape(len(stressAll[i])//6,6).transpose())))+'\n') - except Exception: - damask.util.croak('Could not fit results of simulation (%s)'%thread) - semaphore.release() - return - damask.util.croak('\n') - semaphore.release() - -def loadcaseNo(): - global N_simulations - N_simulations+=1 - return N_simulations - -def converged(): - global N_simulations; fitResidual - - if N_simulations < options.max: - if len(fitResidual) > 5 and N_simulations >= options.min: - residualList = np.array(fitResidual[len(fitResidual)-5:]) - if np.std(residualList)/np.max(residualList) < 0.05: - return True - return False - else: - return True - -# -------------------------------------------------------------------- -# MAIN -# -------------------------------------------------------------------- - -parser = OptionParser(option_class=damask.extendableOption, usage='%prog options [file[s]]', description = """ -Performs calculations with various loads on given geometry file and fits yield surface. - -""", version = scriptID) - -# maybe make an option to specifiy if 2D/3D fitting should be done? - -parser.add_option('-l','--load' , dest='load', type='float', nargs=3, - help='load: final strain; increments; time %default', metavar='float int float') -parser.add_option('-g','--geometry', dest='geometry', type='string', - help='name of the geometry file [%default]', metavar='string') -parser.add_option('-c','--criterion', dest='criterion', choices=fitCriteria.keys(), - help='criterion for stopping simulations [%default]', metavar='string') -parser.add_option('-f','--fitting', dest='fitting', choices=thresholdParameter, - help='yield criterion [%default]', metavar='string') -parser.add_option('-y','--yieldvalue', dest='yieldValue', type='float', nargs=3, - help='yield points: start; end; count %default', metavar='float float int') -parser.add_option('--min', dest='min', type='int', - help='minimum number of simulations [%default]', metavar='int') -parser.add_option('--max', dest='max', type='int', - help='maximum number of iterations [%default]', metavar='int') -parser.add_option('-t','--threads', dest='threads', type='int', - help='number of parallel executions [%default]', metavar='int') -parser.add_option('-b','--bound', dest='bounds', type='float', nargs=2, - help='yield points: start; end; count %default', metavar='float float') -parser.add_option('-d','--dimension', dest='dimension', type='choice', choices=['2','3'], - help='dimension of the virtual test [%default]', metavar='int') -parser.add_option('-e', '--exponent', dest='exponent', type='float', - help='exponent of non-quadratic criteria', metavar='int') -parser.add_option('-u', '--uniaxial', dest='eqStress', type='float', - help='Equivalent stress', metavar='float') - -parser.set_defaults(min = 12, - max = 30, - threads = 4, - yieldValue = (0.002,0.004,2), - load = (0.010,100,100.0), - criterion = 'vonmises', - fitting = 'totalshear', - geometry = '20grains16x16x16', - bounds = None, - dimension = '3', - exponent = -1.0, - ) - -options = parser.parse_args()[0] - -if options.threads < 1: - parser.error('invalid number of threads {}'.format(options.threads)) -if options.min < 0: - parser.error('invalid minimum number of simulations {}'.format(options.min)) -if options.max < options.min: - parser.error('invalid maximum number of simulations (below minimum)') -if options.yieldValue[0] > options.yieldValue[1]: - parser.error('invalid yield start (below yield end)') -if options.yieldValue[2] != int(options.yieldValue[2]): - parser.error('count must be an integer') - -for check in [options.geometry+'.geom','numerics.config','material.config']: - if not os.path.isfile(check): - damask.util.croak('"{}" file not found'.format(check)) - -options.dimension = int(options.dimension) - -stressUnit = 1.0e9 if options.criterion == 'hill1948' else 1.0e6 - - -if options.dimension not in fitCriteria[options.criterion]['dimen']: - parser.error('invalid dimension for selected criterion') - -if options.criterion not in ['vonmises','tresca','drucker','hill1948'] and options.eqStress is None: - parser.error('please specify an equivalent stress (e.g. fitting to von Mises)') - -# global variables -fitResults = [] -fitErrors = [] -fitResidual = [] -stressAll= [np.zeros(0,'d').reshape(0,0) for i in range(int(options.yieldValue[2]))] -strainAll= [np.zeros(0,'d').reshape(0,0) for i in range(int(options.yieldValue[2]))] -N_simulations=0 -Guess = [] -threads=[] -semaphore=threading.Semaphore(1) -dDim = None -myLoad = None -myFit = None - -run = runFit(options.exponent, options.eqStress, options.dimension, options.criterion) - -damask.util.croak('Finished fitting to yield criteria') diff --git a/processing/misc/yieldSurfaceFast.py b/processing/misc/yieldSurfaceFast.py deleted file mode 100755 index c58dca733..000000000 --- a/processing/misc/yieldSurfaceFast.py +++ /dev/null @@ -1,1513 +0,0 @@ -#!/usr/bin/env python2.7 -# -*- coding: UTF-8 no BOM -*- - -import threading,time,os -import numpy as np -from optparse import OptionParser -import damask -from damask.util import leastsqBound -from scipy.optimize import nnls - -scriptName = os.path.splitext(os.path.basename(__file__))[0] -scriptID = ' '.join([scriptName,damask.version]) - -def runFit(exponent, eqStress, dimension, criterion): - global threads, myFit, myLoad - global fitResidual - global Guess, dDim - - if options.criterion!='facet': - dDim = dimension - 3 - nParas = len(fitCriteria[criterion]['bound'][dDim]) - nExpo = fitCriteria[criterion]['nExpo'] - - if exponent > 0.0: # User defined exponents - nParas = nParas-nExpo - fitCriteria[criterion]['bound'][dDim] = fitCriteria[criterion]['bound'][dDim][:nParas] - - for i in range(nParas): - temp = fitCriteria[criterion]['bound'][dDim][i] - if fitCriteria[criterion]['bound'][dDim][i] == (None,None): - Guess.append(1.0) - else: - g = (temp[0]+temp[1])/2.0 - if g == 0: g = temp[1]*0.5 - Guess.append(g) - - myLoad = Loadcase(options.load[0],options.load[1],options.load[2],options.flag,options.yieldValue, - nSet = 10, dimension = dimension, vegter = options.criterion=='vegter') - - - myFit = Criterion(exponent,eqStress, dimension, criterion) - for t in range(options.threads): - threads.append(myThread(t)) - threads[t].start() - - for t in range(options.threads): - threads[t].join() - - if options.criterion=='facet': - doFacetFit() - - damask.util.croak('Residuals') - damask.util.croak(fitResidual) - -def doFacetFit(): - n = options.order - Data = np.zeros((options.numpoints, 10)) - for i in range(options.numpoints): - fileName = options.geometry + '_' + str(i+1) + '.yield' - data_i = np.loadtxt(fileName) - - sv = (data_i[0,0] + data_i[1,1] + data_i[2,2])/3.0 - - #convert stress and strain form the 6D to 5D space - S1 = np.sqrt(2.0)*(data_i[0,0] - data_i[1,1])/2.0 - S2 = np.sqrt(6.0)*(data_i[0,0] + data_i[1,1] - 2.0*sv)/2.0 - S3 = np.sqrt(2.0)*data_i[1,2] - S4 = np.sqrt(2.0)*data_i[2,0] - S5 = np.sqrt(2.0)*data_i[0,1] - - E1 = np.sqrt(2.0)*(data_i[3,0]-data_i[4,1])/2.0 - E2 = np.sqrt(6.0)*(data_i[3,0]+data_i[4,1])/2.0 - E3 = np.sqrt(2.0)*data_i[4,2] - E4 = np.sqrt(2.0)*data_i[5,0] - E5 = np.sqrt(2.0)*data_i[3,1] - - Data[i,:] = [E1,E2,E3,E4,E5,S1,S2,S3,S4,S5] - - Data[:,5:] = Data[:,5:] / 100000000.0 - - path=os.path.join(os.getcwd(),'final.mmm') - np.savetxt(path, Data, header='', comments='', fmt='% 15.10f') - - if options.dimension == 2: - reducedIndices = [0,1,4,5,6,9] - elif options.dimension == 3: - reducedIndices = [i for i in range(10)] - - numDirections = Data.shape[0] - Indices = np.arange(numDirections) - sdPairs = Data[:,reducedIndices][Indices,:] - numPairs = sdPairs.shape[0] - dimensionality = sdPairs.shape[1] / 2 - ds = sdPairs[:,0:dimensionality] - s = sdPairs[:,dimensionality::] - - A = np.zeros((numPairs, numPairs)) - B = np.ones((numPairs,)) - for i in range(numPairs): - for j in range(numPairs): - lamb = 1.0 - s_i = s[i,:] - ds_j = ds[j,:] - A[i,j] = lamb * (np.dot(s_i.ravel(), ds_j.ravel()) ** n) - - lambdas, residuals = nnls(A, B) - nonZeroTerms = np.logical_not(np.isclose(lambdas, 0.)) - numNonZeroTerms = np.sum(nonZeroTerms) - dataOut = np.zeros((numNonZeroTerms, 6)) - - if options.dimension == 2: - dataOut[:,0] = lambdas[nonZeroTerms] - dataOut[:,1] = ds[nonZeroTerms,:][:,0] - dataOut[:,2] = ds[nonZeroTerms,:][:,1] - dataOut[:,5] = ds[nonZeroTerms,:][:,2] - elif options.dimension == 3: - dataOut[:,0] = lambdas[nonZeroTerms] - dataOut[:,1] = ds[nonZeroTerms,:][:,0] - dataOut[:,2] = ds[nonZeroTerms,:][:,1] - dataOut[:,3] = ds[nonZeroTerms,:][:,2] - dataOut[:,4] = ds[nonZeroTerms,:][:,3] - dataOut[:,5] = ds[nonZeroTerms,:][:,4] - - headerText = 'facet\n 1 \n F \n {0:<3d} \n {1:<3d} '.format(n, numNonZeroTerms) - path=os.path.join(os.getcwd(),'facet_o{0}.fac'.format(n)) - np.savetxt(path, dataOut, header=headerText, comments='', fmt='% 15.10f') - -def principalStresses(sigmas): - """ - Computes principal stresses (i.e. eigenvalues) for a set of Cauchy stresses. - - sorted in descending order. - """ - lambdas=np.zeros(0,'d') - for i in range(np.shape(sigmas)[1]): - eigenvalues = np.linalg.eigvalsh(sym6toT33(sigmas[:,i])) - lambdas = np.append(lambdas,np.sort(eigenvalues)[::-1]) #append eigenvalues in descending order - lambdas = np.transpose(lambdas.reshape(np.shape(sigmas)[1],3)) - return lambdas - -def principalStress(p): - I = invariant(p) - - I1s3I2= (I[0]**2 - 3.0*I[1])**0.5 - numer = 2.0*I[0]**3 - 9.0*I[0]*I[1] + 27.0*I[2] - denom = 2.0*I1s3I2**3 - cs = numer/denom - - phi = np.arccos(cs)/3.0 - t1 = I[0]/3.0; t2 = 2.0/3.0*I1s3I2 - return np.array( [t1 + t2*np.cos(phi), - t1 + t2*np.cos(phi+np.pi*2.0/3.0), - t1 + t2*np.cos(phi+np.pi*4.0/3.0)]) - -def principalStrs_Der(p, s, dim, Karafillis=False): - """Derivative of principal stress with respect to stress""" - third = 1.0/3.0 - third2 = 2.0*third - - I = invariant(p) - I1s3I2= np.sqrt(I[0]**2 - 3.0*I[1]) - numer = 2.0*I[0]**3 - 9.0*I[0]*I[1] + 27.0*I[2] - denom = 2.0*I1s3I2**3 - cs = numer/denom - phi = np.arccos(cs)/3.0 - - dphidcs = -third/np.sqrt(1.0 - cs**2) - dcsddenom = 0.5*numer*(-1.5)*I1s3I2**(-5.0) - dcsdI1 = (6.0*I[0]**2 - 9.0*I[1])*denom + dcsddenom*(2.0*I[0]) - dcsdI2 = ( - 9.0*I[0])*denom + dcsddenom*(-3.0) - dcsdI3 = 27.0*denom - dphidI1, dphidI2, dphidI3 = dphidcs*dcsdI1, dphidcs*dcsdI2, dphidcs*dcsdI3 - - dI1s3I2dI1 = I[0]/I1s3I2 - dI1s3I2dI2 = -1.5/I1s3I2 - tcoeff = third2*I1s3I2 - - dSidIj = lambda theta : ( tcoeff*(-np.sin(theta))*dphidI1 + third2*dI1s3I2dI1*np.cos(theta) + third, - tcoeff*(-np.sin(theta))*dphidI2 + third2*dI1s3I2dI2*np.cos(theta), - tcoeff*(-np.sin(theta))*dphidI3) - dSdI = np.array([dSidIj(phi),dSidIj(phi+np.pi*2.0/3.0),dSidIj(phi+np.pi*4.0/3.0)]) # i=1,2,3; j=1,2,3 - -# calculate the derivation of principal stress with regards to the anisotropic coefficients - one = np.ones_like(s); zero = np.zeros_like(s); num = len(s) - dIdp = np.array([[one, one, one, zero, zero, zero], - [p[1]+p[2], p[2]+p[0], p[0]+p[1], -2.0*p[3], -2.0*p[4], -2.0*p[5]], - [p[1]*p[2]-p[4]**2, p[2]*p[0]-p[5]**2, p[0]*p[1]-p[3]**2, - -2.0*p[3]*p[2]+2.0*p[4]*p[5], -2.0*p[4]*p[0]+2.0*p[5]*p[3], -2.0*p[5]*p[1]+2.0*p[3]*p[4]] ]) - if Karafillis: - dpdc = np.array([[zero,s[0]-s[2],s[0]-s[1]], [s[1]-s[2],zero,s[1]-s[0]], [s[2]-s[1],s[2]-s[0],zero]])/3.0 - dSdp = np.array([np.dot(dSdI[:,:,i],dIdp[:,:,i]).T for i in range(num)]).T - if dim == 2: - temp = np.vstack([dSdp[:,3]*s[3]]).T.reshape(num,1,3).T - else: - temp = np.vstack([dSdp[:,3]*s[3],dSdp[:,4]*s[4],dSdp[:,5]*s[5]]).T.reshape(num,3,3).T - - return np.concatenate((np.array([np.dot(dSdp[:,0:3,i], dpdc[:,:,i]).T for i in range(num)]).T, - temp), axis=1) - else: - if dim == 2: - dIdc=np.array([[-dIdp[i,0]*s[1], -dIdp[i,1]*s[0], -dIdp[i,1]*s[2], - -dIdp[i,2]*s[1], -dIdp[i,2]*s[0], -dIdp[i,0]*s[2], - dIdp[i,3]*s[3] ] for i in range(3)]) - else: - dIdc=np.array([[-dIdp[i,0]*s[1], -dIdp[i,1]*s[0], -dIdp[i,1]*s[2], - -dIdp[i,2]*s[1], -dIdp[i,2]*s[0], -dIdp[i,0]*s[2], - dIdp[i,3]*s[3], dIdp[i,4]*s[4], dIdp[i,5]*s[5] ] for i in range(3)]) - return np.array([np.dot(dSdI[:,:,i],dIdc[:,:,i]).T for i in range(num)]).T - -def invariant(sigmas): - I = np.zeros(3) - s11,s22,s33,s12,s23,s31 = sigmas - I[0] = s11 + s22 + s33 - I[1] = s11*s22 + s22*s33 + s33*s11 - s12**2 - s23**2 - s31**2 - I[2] = s11*s22*s33 + 2.0*s12*s23*s31 - s12**2*s33 - s23**2*s11 - s31**2*s22 - return I - -def math_ln(x): - return np.log(x + 1.0e-32) - -def sym6toT33(sym6): - """Shape the symmetric stress tensor(6) into (3,3)""" - return np.array([[sym6[0],sym6[3],sym6[5]], - [sym6[3],sym6[1],sym6[4]], - [sym6[5],sym6[4],sym6[2]]]) - -def t33toSym6(t33): - """Shape the stress tensor(3,3) into symmetric (6)""" - return np.array([ t33[0,0], - t33[1,1], - t33[2,2], - (t33[0,1] + t33[1,0])/2.0, # 0 3 5 - (t33[1,2] + t33[2,1])/2.0, # * 1 4 - (t33[2,0] + t33[0,2])/2.0,]) # * * 2 - -class Criteria(object): - def __init__(self, criterion, uniaxialStress,exponent, dimension): - self.stress0 = uniaxialStress - if exponent < 0.0: # Fitting exponent m - self.mFix = [False, exponent] - else: # fixed exponent m - self.mFix = [True, exponent] - self.func = fitCriteria[criterion]['func'] - self.criteria = criterion - self.dim = dimension - def fun(self, paras, ydata, sigmas): - return self.func(self.stress0, paras, sigmas,self.mFix,self.criteria,self.dim) - def jac(self, paras, ydata, sigmas): - return self.func(self.stress0, paras, sigmas,self.mFix,self.criteria,self.dim,Jac=True) - -class Vegter(object): - """Vegter yield criterion""" - - def __init__(self, refPts, refNormals,nspace=11): - self.refPts, self.refNormals = self._getRefPointsNormals(refPts, refNormals) - self.hingePts = self._getHingePoints() - self.nspace = nspace - def _getRefPointsNormals(self,refPtsQtr,refNormalsQtr): - if len(refPtsQtr) == 12: - refPts = refPtsQtr - refNormals = refNormalsQtr - else: - refPts = np.empty([13,2]) - refNormals = np.empty([13,2]) - refPts[12] = refPtsQtr[0] - refNormals[12] = refNormalsQtr[0] - for i in range(3): - refPts[i] = refPtsQtr[i] - refPts[i+3] = refPtsQtr[3-i][::-1] - refPts[i+6] =-refPtsQtr[i] - refPts[i+9] =-refPtsQtr[3-i][::-1] - refNormals[i] = refNormalsQtr[i] - refNormals[i+3] = refNormalsQtr[3-i][::-1] - refNormals[i+6] =-refNormalsQtr[i] - refNormals[i+9] =-refNormalsQtr[3-i][::-1] - return refPts,refNormals - - def _getHingePoints(self): - """ - Calculate the hinge point B according to the reference points A,C and the normals n,m - - refPoints = np.array([[p1_x, p1_y], [p2_x, p2_y]]); - refNormals = np.array([[n1_x, n1_y], [n2_x, n2_y]]) - """ - def hingPoint(points, normals): - A1 = points[0][0]; A2 = points[0][1] - C1 = points[1][0]; C2 = points[1][1] - n1 = normals[0][0]; n2 = normals[0][1] - m1 = normals[1][0]; m2 = normals[1][1] - B1 = (m2*(n1*A1 + n2*A2) - n2*(m1*C1 + m2*C2))/(n1*m2-m1*n2) - B2 = (n1*(m1*C1 + m2*C2) - m1*(n1*A1 + n2*A2))/(n1*m2-m1*n2) - return np.array([B1,B2]) - return np.array([hingPoint(self.refPts[i:i+2],self.refNormals[i:i+2]) for i in range(len(self.refPts)-1)]) - - def getBezier(self): - def bezier(R,H): - b = [] - for mu in np.linspace(0.0,1.0,self.nspace): - b.append(np.array(R[0]*np.ones_like(mu) + 2.0*mu*(H - R[0]) + mu**2*(R[0]+R[1] - 2.0*H))) - return b - return np.array([bezier(self.refPts[i:i+2],self.hingePts[i]) for i in range(len(self.refPts)-1)]) - -def VetgerCriterion(stress,lankford, rhoBi0, theta=0.0): - """0-pure shear; 1-uniaxial; 2-plane strain; 3-equi-biaxial""" - def getFourierParas(r): - # get the value after Fourier transformation - nset = len(r) - lmatrix = np.empty([nset,nset]) - theta = np.linspace(0.0,np.pi/2,nset) - for i,th in enumerate(theta): - lmatrix[i] = np.array([np.cos(2*j*th) for j in range(nset)]) - return np.linalg.solve(lmatrix, r) - - nps = len(stress) - if nps%4 != 0: - damask.util.croak('Warning: the number of stress points is uncorrect, stress points of %s are missing in set %i'%( - ['eq-biaxial, plane strain & uniaxial', 'eq-biaxial & plane strain','eq-biaxial'][nps%4-1],nps/4+1)) - else: - nset = nps/4 - strsSet = stress.reshape(nset,4,2) - refPts = np.empty([4,2]) - - fouriercoeffs = np.array([np.cos(2.0*i*theta) for i in range(nset)]) - for i in range(2): - refPts[3,i] = sum(strsSet[:,3,i])/nset - for j in range(3): - refPts[j,i] = np.dot(getFourierParas(strsSet[:,j,i]), fouriercoeffs) - - -def Tresca(eqStress=None, #not needed/supported - paras=None, - sigmas=None, - mFix=None, #not needed/supported - criteria=None, #not needed/supported - dim=3, - Jac=False): - """ - Tresca yield criterion - - the fitted parameter is paras(sigma0) - """ - if not Jac: - lambdas = principalStresses(sigmas) - r = np.amax(np.array([abs(lambdas[2,:]-lambdas[1,:]),\ - abs(lambdas[1,:]-lambdas[0,:]),\ - abs(lambdas[0,:]-lambdas[2,:])]),0) - paras - return r.ravel() - else: - return -np.ones(len(sigmas)) - -def Cazacu_Barlat(eqStress=None, - paras=None, - sigmas=None, - mFix=None,#not needed/supported - criteria=None, - dim=3, #2D also possible - Jac=False): - """ - Cazacu-Barlat (CB) yield criterion - - the fitted parameters are: - a1,a2,a3,a6; b1,b2,b3,b4,b5,b10; c for plane stress - a1,a2,a3,a4,a5,a6; b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11; c: for general case - mFix is ignored - """ - s11,s22,s33,s12,s23,s31 = sigmas - if dim == 2: - (a1,a2,a3,a4), (b1,b2,b3,b4,b5,b10), c = paras[0:4],paras[4:10],paras[10] - a5 = a6 = b6 = b7 = b8 = b9 = b11 = 0.0 - s33 = s23 = s31 = np.zeros_like(s11) - else: - (a1,a2,a3,a4,a5,a6), (b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11), c = paras[0:6],paras[6:17],paras[17] - - s1_2, s2_2, s3_2, s12_2, s23_2, s31_2 = np.array([s11,s22,s33,s12,s23,s31])**2 - s1_3, s2_3, s3_3, s123, s321 = s11*s1_2, s22*s2_2, s33*s3_2,s11*s22*s33, s12*s23*s31 - d12_2,d23_2,d31_2 = (s11-s22)**2, (s22-s33)**2, (s33-s11)**2 - - J20 = ( a1*d12_2 + a2*d23_2 + a3*d31_2 )/6.0 + a4*s12_2 + a5*s23_2 + a6*s31_2 - J30 = ( (b1 +b2 )*s1_3 + (b3 +b4 )*s2_3 + ( b1+b4-b2 + b1+b4-b3 )*s3_3 )/27.0- \ - ( (b1*s22+b2*s33)*s1_2 + (b3*s33+b4*s11)*s2_2 + ((b1+b4-b2)*s11 + (b1+b4-b3)*s22)*s3_2 )/9.0 + \ - ( (b1+b4)*s123/9.0 + b11*s321 )*2.0 - \ - ( ( 2.0*b9 *s22 - b8*s33 - (2.0*b9 -b8)*s11 )*s31_2 + - ( 2.0*b10*s33 - b5*s22 - (2.0*b10-b5)*s11 )*s12_2 + - ( (b6+b7)*s11 - b6*s22 - b7*s33 )*s23_2 - )/3.0 - f0 = J20**3 - c*J30**2 - r = f0**(1.0/6.0)*np.sqrt(3.0)/eqStress - - if not Jac: - return (r - 1.0).ravel() - else: - drdf = r/f0/6.0 - dj2, dj3 = drdf*3.0*J20**2, -drdf*2.0*J30*c - jc = -drdf*J30**2 - - ja1,ja2,ja3 = dj2*d12_2/6.0, dj2*d23_2/6.0, dj2*d31_2/6.0 - ja4,ja5,ja6 = dj2*s12_2, dj2*s23_2, dj2*s31_2 - jb1 = dj3*( (s1_3 + 2.0*s3_3)/27.0 - s22*s1_2/9.0 - (s11+s22)*s3_2/9.0 + s123/4.5 ) - jb2 = dj3*( (s1_3 - s3_3)/27.0 - s33*s1_2/9.0 + s11 *s3_2/9.0 ) - jb3 = dj3*( (s2_3 - s3_3)/27.0 - s33*s2_2/9.0 + s22 *s3_2/9.0 ) - jb4 = dj3*( (s2_3 + 2.0*s3_3)/27.0 - s11*s2_2/9.0 - (s11+s22)*s3_2/9.0 + s123/4.5 ) - - jb5, jb10 = dj3*(s22 - s11)*s12_2/3.0, dj3*(s11 - s33)*s12_2/1.5 - jb6, jb7 = dj3*(s22 - s11)*s23_2/3.0, dj3*(s33 - s11)*s23_2/3.0 - jb8, jb9 = dj3*(s33 - s11)*s31_2/3.0, dj3*(s11 - s22)*s31_2/1.5 - jb11 = dj3*s321*2.0 - if dim == 2: - return np.vstack((ja1,ja2,ja3,ja4,jb1,jb2,jb3,jb4,jb5,jb10,jc)).T - else: - return np.vstack((ja1,ja2,ja3,ja4,ja5,ja6,jb1,jb2,jb3,jb4,jb5,jb6,jb7,jb8,jb9,jb10,jb11,jc)).T - -def Drucker(eqStress=None,#not needed/supported - paras=None, - sigmas=None, - mFix=None, #not needed/supported - criteria=None, - dim=3, - Jac=False): - """ - Drucker yield criterion - - the fitted parameters are - sigma0, C_D for Drucker(p=1); - sigma0, C_D, p for general Drucker - eqStress, mFix are invalid inputs - """ - if criteria == 'drucker': - sigma0, C_D= paras - p = 1.0 - else: - sigma0, C_D = paras[0:2] - if mFix[0]: p = mFix[1] - else: p = paras[-1] - I = invariant(sigmas) - J = np.zeros([3]) - J[1] = I[0]**2/3.0 - I[1] - J[2] = I[0]**3/13.5 - I[0]*I[1]/3.0 + I[2] - J2_3p = J[1]**(3.0*p) - J3_2p = J[2]**(2.0*p) - left = J2_3p - C_D*J3_2p - r = left**(1.0/(6.0*p))*3.0**0.5/sigma0 - - if not Jac: - return (r - 1.0).ravel() - else: - drdl = r/left/(6.0*p) - if criteria == 'drucker': - return np.vstack((-r/sigma0, -drdl*J3_2p)).T - else: - dldp = 3.0*J2_3p*math_ln(J[1]) - 2.0*C_D*J3_2p*math_ln(J[2]) - jp = drdl*dldp + r*math_ln(left)/(-6.0*p*p) - - if mFix[0]: return np.vstack((-r/sigma0, -drdl*J3_2p)).T - else: return np.vstack((-r/sigma0, -drdl*J3_2p, jp)).T - -def Hill1948(eqStress=None,#not needed/supported - paras=None, - sigmas=None, - mFix=None, #not needed/supported - criteria=None,#not needed/supported - dim=3, - Jac=False): - """ - Hill 1948 yield criterion - - the fitted parameters are: - F, G, H, L, M, N for 3D - F, G, H, N for 2D - """ - s11,s22,s33,s12,s23,s31 = sigmas - if dim == 2: # plane stress - jac = np.array([ s22**2, s11**2, (s11-s22)**2, 2.0*s12**2]) - else: # general case - jac = np.array([(s22-s33)**2,(s33-s11)**2,(s11-s22)**2, 2.0*s23**2,2.0*s31**2,2.0*s12**2]) - - if not Jac: - return (np.dot(paras,jac)/2.0-0.5).ravel() - else: - return jac.T - -def Hill1979(eqStress=None,#not needed/supported - paras=None, - sigmas=None, - mFix=None, - criteria=None,#not needed/supported - dim=3, - Jac=False): - """ - Hill 1979 yield criterion - - the fitted parameters are: f,g,h,a,b,c,m - """ - if mFix[0]: - m = mFix[1] - else: - m = paras[-1] - - coeff = paras[0:6] - s = principalStresses(sigmas) - diffs = np.array([s[1]-s[2], s[2]-s[0], s[0]-s[1],\ - 2.0*s[0]-s[1]-s[2], 2.0*s[1]-s[2]-s[0], 2.0*s[2]-s[0]-s[1]])**2 - - diffsm = diffs**(m/2.0) - left = np.dot(coeff,diffsm) - r = (0.5*left)**(1.0/m)/eqStress #left = base**mi - - if not Jac: - return (r-1.0).ravel() - else: - drdl, dldm = r/left/m, np.dot(coeff,diffsm*math_ln(diffs))*0.5 - jm = drdl*dldm + r*math_ln(0.5*left)*(-1.0/m/m) #/(-m**2) - - if mFix[0]: return np.vstack((drdl*diffsm)).T - else: return np.vstack((drdl*diffsm, jm)).T - -def Hosford(eqStress=None, - paras=None, - sigmas=None, - mFix=None, - criteria=None, - dim=3, - Jac=False): - """ - Hosford family criteria - - the fitted parameters are: - von Mises: sigma0 - Hershey: (1) sigma0, a, when a is not fixed; (2) sigma0, when a is fixed - general Hosford: (1) F,G,H, a, when a is not fixed; (2) F,G,H, when a is fixed - """ - if criteria == 'vonmises': - sigma0 = paras - coeff = np.ones(3) - a = 2.0 - elif criteria == 'hershey': - sigma0 = paras[0] - coeff = np.ones(3) - if mFix[0]: a = mFix[1] - else: a = paras[1] - else: - sigma0 = eqStress - coeff = paras[0:3] - if mFix[0]: a = mFix[1] - else: a = paras[3] - - s = principalStresses(sigmas) - diffs = np.array([s[1]-s[2], s[2]-s[0], s[0]-s[1]])**2 - diffsm = diffs**(a/2.0) - left = np.dot(coeff,diffsm) - r = (0.5*left)**(1.0/a)/sigma0 - - if not Jac: - return (r-1.0).ravel() - else: - if criteria == 'vonmises': # von Mises - return -r/sigma0 - else: - drdl, dlda = r/left/a, np.dot(coeff,diffsm*math_ln(diffs))*0.5 - ja = drdl*dlda + r*math_ln(0.5*left)*(-1.0/a/a) - if criteria == 'hershey': # Hershey - if mFix[0]: return -r/sigma0 - else: return np.vstack((-r/sigma0, ja)).T - else: # Anisotropic Hosford - if mFix[0]: return np.vstack((drdl*diffsm)).T - else: return np.vstack((drdl*diffsm, ja)).T - -def Barlat1989(eqStress=None, - paras=None, - sigmas=None, - mFix=None, - criteria=None, - dim=3, - Jac=False): - """ - Barlat-Lian 1989 yield criteria - - the fitted parameters are: - Anisotropic: a, h, p, m; m is optional - """ - a, h, p = paras[0:3] - if mFix[0]: m = mFix[1] - else: m = paras[-1] - - c = 2.0-a - s11,s22,s12 = sigmas[0], sigmas[1], sigmas[3] - k1,k2 = 0.5*(s11 + h*s22), (0.25*(s11 - h*s22)**2 + (p*s12)**2)**0.5 - fs = np.array([ (k1+k2)**2, (k1-k2)**2, 4.0*k2**2 ]); fm = fs**(m/2.0) - left = np.dot(np.array([a,a,c]),fm) - r = (0.5*left)**(1.0/m)/eqStress - - if not Jac: - return (r-1.0).ravel() - else: - dk1dh = 0.5*s22 - dk2dh, dk2dp = 0.25*(s11-h*s22)*(-s22)/k2, p*s12**2/k2 - dlda, dldc = fm[0]+fm[1], fm[2] - fm1 = fs**(m/2.0-1.0)*m - dldk1, dldk2 = a*fm1[0]*(k1+k2)+a*fm1[1]*(k1-k2), a*fm1[0]*(k1+k2)-a*fm1[1]*(k1-k2)+c*fm1[2]*k2*4.0 - drdl, drdm = r/m/left, r*math_ln(0.5*left)*(-1.0/m/m) - dldm = np.dot(np.array([a,a,c]),fm*math_ln(fs))*0.5 - - ja,jc = drdl*dlda, drdl*dldc - jh,jp = drdl*(dldk1*dk1dh + dldk2*dk2dh), drdl*dldk2*dk2dp - jm = drdl*dldm + drdm - - if mFix[0]: return np.vstack((ja,jc,jh,jp)).T - else: return np.vstack((ja,jc,jh,jp,jm)).T - -def Barlat1991(eqStress, paras, sigmas, mFix, criteria, dim, Jac=False): - """ - Barlat 1991 criteria - - the fitted parameters are: - Anisotropic: a, b, c, f, g, h, m for 3D - a, b, c, h, m for plane stress - m is optional - """ - if dim == 2: coeff = paras[0:4] # plane stress - else: coeff = paras[0:6] # general case - if mFix[0]: m = mFix[1] - else: m = paras[-1] - - s11,s22,s33,s12,s23,s31 = sigmas - if dim == 2: - dXdx = np.array([s22,-s11,s11-s22,s12]) - A,B,C,H = np.array(coeff)[:,None]*dXdx; F=G=0.0 - else: - dXdx = np.array([s22-s33,s33-s11,s11-s22,s23,s31,s12]) - A,B,C,F,G,H = np.array(coeff)[:,None]*dXdx - - I2 = (F*F + G*G + H*H)/3.0+ ((A-C)**2+(C-B)**2+(B-A)**2)/54.0 - I3 = (C-B)*(A-C)*(B-A)/54.0 + F*G*H - ((C-B)*F*F + (A-C)*G*G + (B-A)*H*H)/6.0 - phi1 = np.arccos(I3/I2**1.5)/3.0 + np.pi/6.0; absc1 = 2.0*np.abs(np.cos(phi1)) - phi2 = phi1 + np.pi/3.0; absc2 = 2.0*np.abs(np.cos(phi2)) - phi3 = phi2 + np.pi/3.0; absc3 = 2.0*np.abs(np.cos(phi3)) - left = ( absc1**m + absc2**m + absc3**m ) - r = (0.5*left)**(1.0/m)*np.sqrt(3.0*I2)/eqStress - - if not Jac: - return (r - 1.0).ravel() - else: - dfdl = r/left/m - jm = r*math_ln(0.5*left)*(-1.0/m/m) + dfdl*0.5*( - absc1**m*math_ln(absc1) + absc2**m*math_ln(absc2) + absc3**m*math_ln(absc3) ) - - da,db,dc = (2.0*A-B-C)/18.0, (2.0*B-C-A)/18.0, (2.0*C-A-B)/18.0 - if dim == 2: - dI2dx = np.array([da, db, dc, H])/1.5*dXdx - dI3dx = np.array([ da*(B-C) + (H**2-G**2)/2.0, - db*(C-A) + (F**2-H**2)/2.0, - dc*(A-B) + (G**2-F**2)/2.0, - (G*F + (A-B))*H ])/3.0*dXdx - else: - dI2dx = np.array([da, db, dc, F,G,H])/1.5*dXdx - dI3dx = np.array([ da*(B-C) + (H**2-G**2)/2.0, - db*(C-A) + (F**2-H**2)/2.0, - dc*(A-B) + (G**2-F**2)/2.0, - (H*G*3.0 + (B-C))*F, - (F*H*3.0 + (C-A))*G, - (G*F*3.0 + (A-B))*H ])/3.0*dXdx - darccos = -1.0/np.sqrt(1.0 - I3**2/I2**3) - - dfdcos = lambda phi : dfdl*m*(2.0*abs(np.cos(phi)))**(m-1.0)*np.sign(np.cos(phi))*(-np.sin(phi)/1.5) - - dfdthe= (dfdcos(phi1) + dfdcos(phi2) + dfdcos(phi3)) - dfdI2, dfdI3 = dfdthe*darccos*I3*(-1.5)*I2**(-2.5)+r/2.0/I2, dfdthe*darccos*I2**(-1.5) - - if mFix[0]: return np.vstack((dfdI2*dI2dx + dfdI3*dI3dx)).T - else: return np.vstack((dfdI2*dI2dx + dfdI3*dI3dx, jm)).T - -def BBC2000(eqStress, paras, sigmas, mFix, criteria, dim, Jac=False): - """ - BBC2000 yield criterion - - the fitted parameters are - d,e,f,g, b,c,a, k; k is optional - criteria are invalid input - """ - d,e,f,g, b,c,a= paras[0:7] - if mFix[0]: k = mFix[1] - else: k = paras[-1] - - s11,s22,s12 = sigmas[0], sigmas[1], sigmas[3] - k2 = 2.0*k; k1 = k - 1.0 - M,N,P,Q,R = d+e, e+f, (d-e)/2.0, (e-f)/2.0, g**2 - Gamma = M*s11 + N*s22 - Psi = ( (P*s11 + Q*s22)**2 + s12**2*R )**0.5 - - l1, l2, l3 = b*Gamma + c*Psi, b*Gamma - c*Psi, 2.0*c*Psi - l1s,l2s,l3s = l1**2, l2**2, l3**2 - - left = a*l1s**k + a*l2s**k + (1-a)*l3s**k - r = left**(1.0/k2)/eqStress - if not Jac: - return (r - 1.0).ravel() - else: - drdl,drdk = r/left/k2, r*math_ln(left)*(-1.0/k2/k) - dldl1,dldl2,dldl3 = a*k2*(l1s**k1)*l1, a*k2*(l2s**k1)*l2, (1-a)*k2*(l3s**k1)*l3 - dldGama, dldPsi = (dldl1 + dldl2)*b, (dldl1 - dldl2 + 2.0*dldl3)*c - temp = (P*s11 + Q*s22)/Psi - dPsidP, dPsidQ, dPsidR = temp*s11, temp*s22, 0.5*s12**2/Psi - dlda = l1s**k + l2s**k - l3s**k - dldb = dldl1*Gamma + dldl2*Gamma - dldc = dldl1*Psi - dldl2*Psi + dldl3*2.0*Psi - dldk = a*math_ln(l1s)*l1s**k + a*math_ln(l2s)*l2s**k + (1-a)*math_ln(l3s)*l3s**k - - J = drdl*np.array([dldGama*s11+dldPsi*dPsidP*0.5, dldGama*(s11+s22)+dldPsi*(-dPsidP+dPsidQ)*0.5, #jd,je - dldGama*s22-dldPsi*dPsidQ*0.5, dldPsi*dPsidR*2.0*g, #jf,jg - dldb, dldc, dlda]) #jb,jc,ja - if mFix[0]: return np.vstack(J).T - else: return np.vstack((J, drdl*dldk + drdk)).T - - -def BBC2003(eqStress, paras, sigmas, mFix, criteria, dim, Jac=False): - """ - BBC2003 yield criterion - - the fitted parameters are - M,N,P,Q,R,S,T,a, k; k is optional - criteria are invalid input - """ - M,N,P,Q,R,S,T,a = paras[0:8] - if mFix[0]: k = mFix[1] - else: k = paras[-1] - - s11,s22,s12 = sigmas[0], sigmas[1], sigmas[3] - k2 = 2.0*k; k1 = k - 1.0 - Gamma = 0.5 * (s11 + M*s22) - Psi = ( 0.25*(N*s11 - P*s22)**2 + Q*Q*s12**2 )**0.5 - Lambda = ( 0.25*(R*s11 - S*s22)**2 + T*T*s12**2 )**0.5 - - l1, l2, l3 = Gamma + Psi, Gamma - Psi, 2.0*Lambda - l1s,l2s,l3s = l1**2, l2**2, l3**2 - left = a*l1s**k + a*l2s**k + (1-a)*l3s**k - r = left**(1.0/k2)/eqStress - if not Jac: - return (r - 1.0).ravel() - else: - drdl,drdk = r/left/k2, r*math_ln(left)*(-1.0/k2/k) - dldl1,dldl2,dldl3 = a*k2*(l1s**k1)*l1, a*k2*(l2s**k1)*l2, (1-a)*k2*(l3s**k1)*l3 - - dldGamma, dldPsi, dldLambda = dldl1+dldl2, dldl1-dldl2, 2.0*dldl3 - temp = 0.25/Psi*(N*s11 - P*s22) - dPsidN, dPsidP, dPsidQ = s11*temp, -s22*temp, Q*s12**2/Psi - temp = 0.25/Lambda*(R*s11 - S*s22) - dLambdadR, dLambdadS, dLambdadT = s11*temp, -s22*temp, T*s12**2/Psi - dldk = a*math_ln(l1s)*l1s**k + a*math_ln(l2s)*l2s**k + (1-a)*math_ln(l3s)*l3s**k - - J = drdl * np.array([dldGamma*s22*0.5, #jM - dldPsi*dPsidN, dldPsi*dPsidP, dldPsi*dPsidQ, #jN, jP, jQ - dldLambda*dLambdadR, dldLambda*dLambdadS, dldLambda*dLambdadT, #jR, jS, jT - l1s**k + l2s**k - l3s**k ]) #ja - - if mFix[0]: return np.vstack(J).T - else : return np.vstack((J, drdl*dldk+drdk)).T - -def BBC2005(eqStress, paras, sigmas, mFix, criteria, dim, Jac=False): - """ - BBC2005 yield criterion - - the fitted parameters are - a, b, L ,M, N, P, Q, R, k k are optional - criteria is invalid input - """ - a,b,L, M, N, P, Q, R = paras[0:8] - if mFix[0]: k = mFix[1] - else: k = paras[-1] - - s11 = sigmas[0]; s22 = sigmas[1]; s12 = sigmas[3] - k2 = 2.0*k - Gamma = L*s11 + M*s22 - Lambda = ( (N*s11 - P*s22)**2 + s12**2 )**0.5 - Psi = ( (Q*s11 - R*s22)**2 + s12**2 )**0.5 - - l1 = Lambda + Gamma; l2 = Lambda - Gamma; l3 = Lambda + Psi; l4 = Lambda - Psi - l1s = l1**2; l2s = l2**2; l3s = l3**2; l4s = l4**2 - left = a*l1s**k + a*l2s**k + b*l3s**k + b*l4s**k - sBar = left**(1.0/k2); r = sBar/eqStress - 1.0 - if not Jac: - return r.ravel() - else: - ln = lambda x : np.log(x + 1.0e-32) - expo = 0.5/k; k1 = k-1.0 - - dsBardl = expo*sBar/left/eqStress - dsBarde = sBar*ln(left); dedk = expo/(-k) - dldl1 = a*k*(l1s**k1)*(2.0*l1) - dldl2 = a*k*(l2s**k1)*(2.0*l2) - dldl3 = b*k*(l3s**k1)*(2.0*l3) - dldl4 = b*k*(l4s**k1)*(2.0*l4) - - dldLambda = dldl1 + dldl2 + dldl3 + dldl4 - dldGama = dldl1 - dldl2 - dldPsi = dldl3 - dldl4 - temp = (N*s11 - P*s22)/Lambda - dLambdadN = s11*temp; dLambdadP = -s22*temp - temp = (Q*s11 - R*s22)/Psi - dPsidQ = s11*temp; dPsidR = -s22*temp - dldk = a*ln(l1s)*l1s**k + a*ln(l2s)*l2s**k + b*ln(l3s)*l3s**k + b*ln(l4s)*l4s**k - - J = dsBardl * np.array( [ - l1s**k+l2s**k, l3s**k+l4s**k,dldGama*s11,dldGama*s22,dldLambda*dLambdadN, - dldLambda*dLambdadP, dldPsi*dPsidQ, dldPsi*dPsidR]) - - if mFix[0]: return np.vstack(J).T - else : return np.vstack(J, dldk+dsBarde*dedk).T - -def Yld2000(eqStress, paras, sigmas, mFix, criteria, dim, Jac=False): - """ - Yld2000 yield criterion - - C: c11,c22,c66 c12=c21=1.0 JAC NOT PASS - D: d11,d12,d21,d22,d66 - """ - C,D = paras[0:3], paras[3:8] - if mFix[0]: m = mFix[1] - else: m = paras[-1] - - s11, s22, s12 = sigmas[0],sigmas[1],sigmas[3] - X = np.array([ 2.0*C[0]*s11-C[0]*s22, 2.0*C[1]*s22-C[1]*s11, 3.0*C[2]*s12 ])/3.0 # a1,a2,a7 - Y = np.array([ (8.0*D[2]-2.0*D[0]-2.0*D[3]+2.0*D[1])*s11 + (4.0*D[3]-4.0*D[1]-4.0*D[2]+ D[0])*s22, - (4.0*D[0]-4.0*D[2]-4.0*D[1]+ D[3])*s11 + (8.0*D[1]-2.0*D[3]-2.0*D[0]+2.0*D[2])*s22, - 9.0*D[4]*s12 ])/9.0 - - def priStrs(s): - temp = np.sqrt( (s[0]-s[1])**2 + 4.0*s[2]**2 ) - return 0.5*(s[0]+s[1] + temp), 0.5*(s[0]+s[1] - temp) - m2 = m/2.0; m21 = m2 - 1.0 - (X1,X2), (Y1,Y2) = priStrs(X), priStrs(Y) # Principal values of X, Y - phi1s, phi21s, phi22s = (X1-X2)**2, (2.0*Y2+Y1)**2, (2.0*Y1+Y2)**2 - phi1, phi21, phi22 = phi1s**m2, phi21s**m2, phi22s**m2 - left = phi1 + phi21 + phi22 - r = (0.5*left)**(1.0/m)/eqStress - - if not Jac: - return (r-1.0).ravel() - else: - drdl, drdm = r/m/left, r*math_ln(0.5*left)*(-1.0/m/m) #/(-m*m) - dldm = ( phi1*math_ln(phi1s) + phi21*math_ln(phi21s) + phi22*math_ln(phi22s) )*0.5 - zero = np.zeros_like(s11); num = len(s11) - def dPrincipalds(X): - """Derivative of principla with respect to stress""" - temp = 1.0/np.sqrt( (X[0]-X[1])**2 + 4.0*X[2]**2 ) - dP1dsi = 0.5*np.array([ 1.0+temp*(X[0]-X[1]), 1.0-temp*(X[0]-X[1]), temp*4.0*X[2]]) - dP2dsi = 0.5*np.array([ 1.0-temp*(X[0]-X[1]), 1.0+temp*(X[0]-X[1]), -temp*4.0*X[2]]) - return np.array([dP1dsi, dP2dsi]) - - dXdXi, dYdYi = dPrincipalds(X), dPrincipalds(Y) - dXidC = np.array([ [ 2.0*s11-s22, zero, zero ], #dX11dC - [ zero, 2.0*s22-s11, zero ], #dX22dC - [ zero, zero, 3.0*s12 ] ])/3.0 #dX12dC - dYidD = np.array([ [ -2.0*s11+ s22, 2.0*s11-4.0*s22, 8.0*s11-4.0*s22, -2.0*s11+4.0*s22, zero ], #dY11dD - [ 4.0*s11-2.0*s22, -4.0*s11+8.0*s22, -4.0*s11+2.0*s22, s11-2.0*s22, zero ], #dY22dD - [ zero, zero, zero, zero, 9.0*s12 ] ])/9.0 #dY12dD - - dXdC=np.array([np.dot(dXdXi[:,:,i], dXidC[:,:,i]).T for i in range(num)]).T - dYdD=np.array([np.dot(dYdYi[:,:,i], dYidD[:,:,i]).T for i in range(num)]).T - - dldX = m*np.array([ phi1s**m21*(X1-X2), phi1s**m21*(X2-X1)]) - dldY = m*np.array([phi21s**m21*(2.0*Y2+Y1) + 2.0*phi22s**m21*(2.0*Y1+Y2), \ - phi22s**m21*(2.0*Y1+Y2) + 2.0*phi21s**m21*(2.0*Y2+Y1) ]) - jC = drdl*np.array([np.dot(dldX[:,i], dXdC[:,:,i]) for i in range(num)]).T - jD = drdl*np.array([np.dot(dldY[:,i], dYdD[:,:,i]) for i in range(num)]).T - - jm = drdl*dldm + drdm - if mFix[0]: return np.vstack((jC,jD)).T - else: return np.vstack((jC,jD,jm)).T - -def Yld200418p(eqStress, paras, sigmas, mFix, criteria, dim, Jac=False): - """ - Yld2004-18p yield criterion - - the fitted parameters are - C: c12,c21,c23,c32,c31,c13,c44,c55,c66; D: d12,d21,d23,d32,d31,d13,d44,d55,d66 for 3D - C: c12,c21,c23,c32,c31,c13,c44; D: d12,d21,d23,d32,d31,d13,d44 for 2D - and m, m are optional - criteria is ignored - """ - if dim == 2: C,D = np.append(paras[0:7],[0.0,0.0]), np.append(paras[7:14],[0.0,0.0]) - else: C,D = paras[0:9], paras[9:18] - if mFix[0]: m = mFix[1] - else: m = paras[-1] - - sv = (sigmas[0] + sigmas[1] + sigmas[2])/3.0 - sdev = np.vstack((sigmas[0:3]-sv,sigmas[3:6])) - ys = lambda sdev, C: np.array([-C[0]*sdev[1]-C[5]*sdev[2], -C[1]*sdev[0]-C[2]*sdev[2], - -C[4]*sdev[0]-C[3]*sdev[1], C[6]*sdev[3], C[7]*sdev[4], C[8]*sdev[5]]) - p,q = ys(sdev, C), ys(sdev, D) - pLambdas, qLambdas = principalStress(p), principalStress(q) # no sort - - m2 = m/2.0; x3 = range(3); num = len(sv) - PiQj = np.array([(pLambdas[i,:]-qLambdas[j,:]) for i in x3 for j in x3]) - QiPj = np.array([(qLambdas[i,:]-pLambdas[j,:]) for i in x3 for j in x3]).reshape(3,3,num) - PiQjs = PiQj**2 - left = np.sum(PiQjs**m2,axis=0) - r = (0.25*left)**(1.0/m)/eqStress - - if not Jac: - return (r - 1.0).ravel() - else: - drdl, drdm = r/m/left, r*math_ln(0.25*left)*(-1.0/m/m) - dldm = np.sum(PiQjs**m2*math_ln(PiQjs),axis=0)*0.5 - dPdc, dQdd = principalStrs_Der(p, sdev, dim), principalStrs_Der(q, sdev, dim) - PiQjs3d = ( PiQjs**(m2-1.0) ).reshape(3,3,num) - dldP = -m*np.array([np.diag(np.dot(PiQjs3d[:,:,i], QiPj [:,:,i])) for i in range(num)]).T - dldQ = m*np.array([np.diag(np.dot(QiPj [:,:,i], PiQjs3d[:,:,i])) for i in range(num)]).T - - jm = drdl*dldm + drdm - jc = drdl*np.sum([dldP[i]*dPdc[i] for i in x3],axis=0) - jd = drdl*np.sum([dldQ[i]*dQdd[i] for i in x3],axis=0) - - if mFix[0]: return np.vstack((jc,jd)).T - else: return np.vstack((jc,jd,jm)).T - -def KarafillisBoyce(eqStress, paras, sigmas, mFix, criteria, dim, Jac=False): - """ - Karafillis-Boyce - - the fitted parameters are - c11,c12,c13,c14,c15,c16,c,m for 3D - c11,c12,c13,c14,c,m for plane stress - 0 1 and self.dimen == 2: - return fitCriteria[self.name]['labels'][1] - else: - return fitCriteria[self.name]['labels'][0] - - def report_name(self): - return fitCriteria[self.name]['name'] - - def fit(self,stress): - global fitResults; fitErrors; fitResidual - if options.exponent > 0.0: nExponent = options.exponent - else: nExponent = 0 - nameCriterion = self.name.lower() - criteria = Criteria(nameCriterion,self.uniaxial,self.expo, self.dimen) - bounds = fitCriteria[nameCriterion]['bound'][dDim] # Default bounds, no bound - guess0 = Guess # Default initial guess, depends on bounds - - if fitResults == []: - initialguess = guess0 - else: - initialguess = np.array(fitResults[-1]) - - ydata = np.zeros(np.shape(stress)[1]) - try: - popt, pcov, infodict, errmsg, ierr = \ - leastsqBound (criteria.fun, initialguess, args=(ydata,stress), - bounds=bounds, Dfun=criteria.jac, full_output=True) - if ierr not in [1, 2, 3, 4]: - raise RuntimeError("Optimal parameters not found: "+errmsg) - else: - residual = criteria.fun(popt, ydata, stress) - fitResidual.append(np.linalg.norm(residual)/np.sqrt(len(residual))) - if (len(ydata) > len(initialguess)) and pcov is not None: - s_sq = (criteria.fun(popt, *(ydata,stress))**2).sum()/(len(ydata)-len(initialguess)) - pcov = pcov * s_sq - perr = np.sqrt(np.diag(pcov)) - fitResults.append(popt.tolist()) - fitErrors .append(perr.tolist()) - - popt = np.concatenate((np.array(popt), np.repeat(options.exponent,nExponent))) - perr = np.concatenate((np.array(perr), np.repeat(0.0,nExponent))) - - damask.util.croak('Needed {} function calls for fitting'.format(infodict['nfev'])) - except Exception as detail: - damask.util.croak(detail) - pass - return popt - -#--------------------------------------------------------------------------------------------------- -class myThread (threading.Thread): - """Runner""" - - def __init__(self, threadID): - threading.Thread.__init__(self) - self.threadID = threadID - def run(self): - semaphore.acquire() - conv=converged() - semaphore.release() - while not conv: - if options.criterion=='facet': - doSimForFacet(self.name) - else: - doSim(self.name) - semaphore.acquire() - conv=converged() - semaphore.release() - -def doSim(thread): - semaphore.acquire() - global myLoad - loadNo=loadcaseNo() - if not os.path.isfile('%s.load'%loadNo): - damask.util.croak('Generating load case for simulation %s (%s)'%(loadNo,thread)) - f=open('%s.load'%loadNo,'w') - f.write(myLoad.getLoadcase(loadNo)) - f.close() - semaphore.release() - else: semaphore.release() - -# if spectralOut does not exist, run simulation - semaphore.acquire() - if not os.path.isfile('%s_%i.spectralOut'%(options.geometry,loadNo)): - damask.util.croak('Starting simulation %i (%s)'%(loadNo,thread)) - semaphore.release() - damask.util.execute('DAMASK_spectral -g %s -l %i'%(options.geometry,loadNo)) - else: semaphore.release() - -# reading values from ASCII file - semaphore.acquire() - damask.util.croak('Reading values from simulation %i (%s)'%(loadNo,thread)) - semaphore.release() - refFile = '%s_%i.yield'%(options.geometry,loadNo) - yieldStress = np.empty((6),'d') - if not os.path.isfile(refFile): - validity = False - else: - validity = True - yieldData = np.loadtxt(refFile) - stress = yieldData[:3] - yieldStress = t33toSym6(stress) -# do the actual fitting procedure and write results to file - semaphore.acquire() - global stressAll - f=open(options.geometry+'_'+options.criterion+'_'+str(time.time())+'.txt','w') - f.write(' '.join([options.fitting]+myFit.report_labels())+'\n') - try: - if validity: - stressAll=np.append(stressAll, yieldStress/stressUnit) - f.write(' '.join(map(str,myFit.fit(stressAll.reshape(len(stressAll)//6,6).transpose())))+'\n') - except Exception: - damask.util.croak('Could not fit results of simulation (%s)'%thread) - semaphore.release() - return - damask.util.croak('\n') - semaphore.release() - -def doSimForFacet(thread): - semaphore.acquire() - global myLoad - loadNo=loadcaseNo() - if not os.path.isfile('%s.load'%loadNo): - damask.util.croak('Generating load case for simulation %s (%s)'%(loadNo,thread)) - f=open('%s.load'%loadNo,'w') - f.write(myLoad.getLoadcase(loadNo)) - f.close() - semaphore.release() - else: semaphore.release() - -# if spectralOut does not exist, run simulation - semaphore.acquire() - if not os.path.isfile('%s_%i.spectralOut'%(options.geometry,loadNo)): - damask.util.croak('Starting simulation %i (%s)'%(loadNo,thread)) - semaphore.release() - damask.util.execute('DAMASK_spectral -g %s -l %i'%(options.geometry,loadNo)) - else: semaphore.release() - -def loadcaseNo(): - global N_simulations - N_simulations+=1 - return N_simulations - -def converged(): - global N_simulations; fitResidual - - if options.criterion=='facet': - if N_simulations == options.numpoints: - return True - else: - return False - else: - if N_simulations < options.max: - if len(fitResidual) > 5 and N_simulations >= options.min: - residualList = np.array(fitResidual[len(fitResidual)-5:]) - if np.std(residualList)/np.max(residualList) < 0.05: - return True - return False - else: - return True - -# -------------------------------------------------------------------- -# MAIN -# -------------------------------------------------------------------- - -parser = OptionParser(option_class=damask.extendableOption, usage='%prog options [file[s]]', description = """ -Performs calculations with various loads on given geometry file and fits yield surface. - -""", version = scriptID) - -# maybe make an option to specifiy if 2D/3D fitting should be done? - -parser.add_option('-l','--load' , dest='load', type='float', nargs=3, - help='load: final strain; increments; time %default', metavar='float int float') -parser.add_option('-g','--geometry', dest='geometry', type='string', - help='name of the geometry file [%default]', metavar='string') -parser.add_option('-c','--criterion', dest='criterion', choices=fitCriteria.keys(), - help='criterion for stopping simulations [%default]', metavar='string') -parser.add_option('-f','--fitting', dest='fitting', choices=thresholdParameter, - help='yield criterion [%default]', metavar='string') -parser.add_option('-y','--yieldvalue', dest='yieldValue', type='float', - help='yield points %default', metavar='float') -parser.add_option('--min', dest='min', type='int', - help='minimum number of simulations [%default]', metavar='int') -parser.add_option('--max', dest='max', type='int', - help='maximum number of iterations [%default]', metavar='int') -parser.add_option('-t','--threads', dest='threads', type='int', - help='number of parallel executions [%default]', metavar='int') -parser.add_option('-b','--bound', dest='bounds', type='float', nargs=2, - help='yield points: start; end; count %default', metavar='float float') -parser.add_option('-d','--dimension', dest='dimension', type='choice', choices=['2','3'], - help='dimension of the virtual test [%default]', metavar='int') -parser.add_option('-e', '--exponent', dest='exponent', type='float', - help='exponent of non-quadratic criteria', metavar='int') -parser.add_option('-u', '--uniaxial', dest='eqStress', type='float', - help='Equivalent stress', metavar='float') -parser.add_option('--flag', dest='flag', type='string', - help='yield stop flag, totalStrain, plasticStrain or plasticWork', metavar='string') -parser.add_option('--numpoints', dest='numpoints', type='int', - help='number of yield points to fit facet potential [%default]', metavar='int') -parser.add_option('--order', dest='order', type='int', - help='order of facet potential [%default]', metavar='int') - -parser.set_defaults(min = 12, - max = 20, - threads = 4, - yieldValue = 0.002, - load = (0.010,100,100.0), - criterion = 'vonmises', - fitting = 'totalshear', - geometry = '20grains16x16x16', - bounds = None, - dimension = '3', - exponent = -1.0, - flag = 'totalStrain', - numpoints = 100, - order = 8 - ) - -options = parser.parse_args()[0] - -if options.threads < 1: - parser.error('invalid number of threads {}'.format(options.threads)) -if options.min < 0: - parser.error('invalid minimum number of simulations {}'.format(options.min)) -if options.max < options.min: - parser.error('invalid maximum number of simulations (below minimum)') - -for check in [options.geometry+'.geom','numerics.config','material.config']: - if not os.path.isfile(check): - damask.util.croak('"{}" file not found'.format(check)) - -options.dimension = int(options.dimension) - -stressUnit = 1.0e9 if options.criterion == 'hill1948' else 1.0e6 - - -if options.dimension not in fitCriteria[options.criterion]['dimen']: - parser.error('invalid dimension for selected criterion') - -if options.criterion not in ['vonmises','tresca','drucker','hill1948'] and options.eqStress is None: - parser.error('please specify an equivalent stress (e.g. fitting to von Mises)') - -# global variables -fitResults = [] -fitErrors = [] -fitResidual = [] -stressAll= np.zeros(0,'d').reshape(0,0) -N_simulations=0 -Guess = [] -threads=[] -semaphore=threading.Semaphore(1) -dDim = None -myLoad = None -myFit = None - -if options.criterion == 'facet': - run = runFit(options.exponent, options.eqStress, options.dimension, options.criterion) -else: - run = runFit(options.exponent, options.eqStress, options.dimension, options.criterion) - -damask.util.croak('Finished fitting to yield criteria') From d1fa2a14dc6fe63032c088378f66bdad2b1482ea Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 9 Dec 2019 05:28:00 +0100 Subject: [PATCH 34/78] was used only for yield surface fitting --- python/damask/util.py | 257 ------------------------------------------ 1 file changed, 257 deletions(-) diff --git a/python/damask/util.py b/python/damask/util.py index 63b9aed65..cf041f946 100644 --- a/python/damask/util.py +++ b/python/damask/util.py @@ -221,263 +221,6 @@ class return_message(): return srepr(self.message) -def leastsqBound(func, x0, args=(), bounds=None, Dfun=None, full_output=0, - col_deriv=0, ftol=1.49012e-8, xtol=1.49012e-8, - gtol=0.0, maxfev=0, epsfcn=None, factor=100, diag=None): - from scipy.optimize import _minpack - """ - Non-linear least square fitting (Levenberg-Marquardt method) with - bounded parameters. - the codes of transformation between int <-> ext refers to the work of - Jonathan J. Helmus: https://github.com/jjhelmus/leastsqbound-scipy - other codes refer to the source code of minpack.py: - - An internal parameter list is used to enforce contraints on the fitting - parameters. The transfomation is based on that of MINUIT package. - please see: F. James and M. Winkler. MINUIT User's Guide, 2004. - - bounds : list - (min, max) pairs for each parameter, use None for 'min' or 'max' - when there is no bound in that direction. - For example: if there are two parameters needed to be fitting, then - bounds is [(min1,max1), (min2,max2)] - - This function is based on 'leastsq' of minpack.py, the annotation of - other parameters can be found in 'least_squares.py'. - """ - - def _check_func(checker, argname, thefunc, x0, args, numinputs, - output_shape=None): - from numpy import shape - """The same as that of minpack.py""" - res = np.atleast_1d(thefunc(*((x0[:numinputs],) + args))) - if (output_shape is not None) and (shape(res) != output_shape): - if (output_shape[0] != 1): - if len(output_shape) > 1: - if output_shape[1] == 1: - return shape(res) - msg = "%s: there is a mismatch between the input and output " \ - "shape of the '%s' argument" % (checker, argname) - func_name = getattr(thefunc, '__name__', None) - if func_name: - msg += " '%s'." % func_name - else: - msg += "." - raise TypeError(msg) - if np.issubdtype(res.dtype, np.inexact): - dt = res.dtype - else: - dt = dtype(float) - return shape(res), dt - - def _int2extGrad(p_int, bounds): - """Calculate the gradients of transforming the internal (unconstrained) to external (constrained) parameter.""" - grad = np.empty_like(p_int) - for i, (x, bound) in enumerate(zip(p_int, bounds)): - lower, upper = bound - if lower is None and upper is None: # No constraints - grad[i] = 1.0 - elif upper is None: # only lower bound - grad[i] = x/np.sqrt(x*x + 1.0) - elif lower is None: # only upper bound - grad[i] = -x/np.sqrt(x*x + 1.0) - else: # lower and upper bounds - grad[i] = (upper - lower)*np.cos(x)/2.0 - return grad - - def _int2extFunc(bounds): - """Transform internal parameters into external parameters.""" - local = [_int2extLocal(b) for b in bounds] - - def _transform_i2e(p_int): - p_ext = np.empty_like(p_int) - p_ext[:] = [i(j) for i, j in zip(local, p_int)] - return p_ext - return _transform_i2e - - def _ext2intFunc(bounds): - """Transform external parameters into internal parameters.""" - local = [_ext2intLocal(b) for b in bounds] - - def _transform_e2i(p_ext): - p_int = np.empty_like(p_ext) - p_int[:] = [i(j) for i, j in zip(local, p_ext)] - return p_int - return _transform_e2i - - def _int2extLocal(bound): - """Transform a single internal parameter to an external parameter.""" - lower, upper = bound - if lower is None and upper is None: # no constraints - return lambda x: x - elif upper is None: # only lower bound - return lambda x: lower - 1.0 + np.sqrt(x*x + 1.0) - elif lower is None: # only upper bound - return lambda x: upper + 1.0 - np.sqrt(x*x + 1.0) - else: - return lambda x: lower + ((upper - lower)/2.0)*(np.sin(x) + 1.0) - - def _ext2intLocal(bound): - """Transform a single external parameter to an internal parameter.""" - lower, upper = bound - if lower is None and upper is None: # no constraints - return lambda x: x - elif upper is None: # only lower bound - return lambda x: np.sqrt((x - lower + 1.0)**2 - 1.0) - elif lower is None: # only upper bound - return lambda x: np.sqrt((x - upper - 1.0)**2 - 1.0) - else: - return lambda x: np.arcsin((2.0*(x - lower)/(upper - lower)) - 1.0) - - i2e = _int2extFunc(bounds) - e2i = _ext2intFunc(bounds) - - x0 = np.asarray(x0).flatten() - n = len(x0) - - if len(bounds) != n: - raise ValueError('the length of bounds is inconsistent with the number of parameters ') - - if not isinstance(args, tuple): - args = (args,) - - shape, dtype = _check_func('leastsq', 'func', func, x0, args, n) - m = shape[0] - - if n > m: - raise TypeError('Improper input: N=%s must not exceed M=%s' % (n, m)) - if epsfcn is None: - epsfcn = np.finfo(dtype).eps - - def funcWarp(x, *args): - return func(i2e(x), *args) - - xi0 = e2i(x0) - - if Dfun is None: - if maxfev == 0: - maxfev = 200*(n + 1) - retval = _minpack._lmdif(funcWarp, xi0, args, full_output, ftol, xtol, - gtol, maxfev, epsfcn, factor, diag) - else: - if col_deriv: - _check_func('leastsq', 'Dfun', Dfun, x0, args, n, (n, m)) - else: - _check_func('leastsq', 'Dfun', Dfun, x0, args, n, (m, n)) - if maxfev == 0: - maxfev = 100*(n + 1) - - def DfunWarp(x, *args): - return Dfun(i2e(x), *args) - - retval = _minpack._lmder(funcWarp, DfunWarp, xi0, args, full_output, col_deriv, - ftol, xtol, gtol, maxfev, factor, diag) - - errors = {0: ["Improper input parameters.", TypeError], - 1: ["Both actual and predicted relative reductions " - "in the sum of squares\n are at most %f" % ftol, None], - 2: ["The relative error between two consecutive " - "iterates is at most %f" % xtol, None], - 3: ["Both actual and predicted relative reductions in " - "the sum of squares\n are at most %f and the " - "relative error between two consecutive " - "iterates is at \n most %f" % (ftol, xtol), None], - 4: ["The cosine of the angle between func(x) and any " - "column of the\n Jacobian is at most %f in " - "absolute value" % gtol, None], - 5: ["Number of calls to function has reached " - "maxfev = %d." % maxfev, ValueError], - 6: ["ftol=%f is too small, no further reduction " - "in the sum of squares\n is possible.""" % ftol, - ValueError], - 7: ["xtol=%f is too small, no further improvement in " - "the approximate\n solution is possible." % xtol, - ValueError], - 8: ["gtol=%f is too small, func(x) is orthogonal to the " - "columns of\n the Jacobian to machine " - "precision." % gtol, ValueError], - 'unknown': ["Unknown error.", TypeError]} - - info = retval[-1] # The FORTRAN return value - - if info not in [1, 2, 3, 4] and not full_output: - if info in [5, 6, 7, 8]: - np.warnings.warn(errors[info][0], RuntimeWarning) - else: - try: - raise errors[info][1](errors[info][0]) - except KeyError: - raise errors['unknown'][1](errors['unknown'][0]) - - mesg = errors[info][0] - x = i2e(retval[0]) - - if full_output: - grad = _int2extGrad(retval[0], bounds) - retval[1]['fjac'] = (retval[1]['fjac'].T / np.take(grad, - retval[1]['ipvt'] - 1)).T - cov_x = None - if info in [1, 2, 3, 4]: - from numpy.dual import inv - from numpy.linalg import LinAlgError - perm = np.take(np.eye(n), retval[1]['ipvt'] - 1, 0) - r = np.triu(np.transpose(retval[1]['fjac'])[:n, :]) - R = np.dot(r, perm) - try: - cov_x = inv(np.dot(np.transpose(R), R)) - except LinAlgError as inverror: - print(inverror) - pass - return (x, cov_x) + retval[1:-1] + (mesg, info) - else: - return (x, info) - -def _general_function(params, ydata, xdata, function): - return function(xdata, *params) - ydata -def _weighted_general_function(params, ydata, xdata, function, weights): - return (function(xdata, *params) - ydata)*weights - -def curve_fit_bound(f, xdata, ydata, p0=None, sigma=None, bounds=None, **kw): - """Similar as 'curve_fit' in minpack.py.""" - if p0 is None: - # determine number of parameters by inspecting the function - import inspect - args, varargs, varkw, defaults = inspect.getargspec(f) - if len(args) < 2: - msg = "Unable to determine number of fit parameters." - raise ValueError(msg) - if 'self' in args: - p0 = [1.0] * (len(args)-2) - else: - p0 = [1.0] * (len(args)-1) - - if np.isscalar(p0): - p0 = np.array([p0]) - - args = (ydata, xdata, f) - if sigma is None: - func = _general_function - else: - func = _weighted_general_function - args += (1.0/np.asarray(sigma),) - - return_full = kw.pop('full_output', False) - res = leastsqBound(func, p0, args=args, bounds = bounds, full_output=True, **kw) - (popt, pcov, infodict, errmsg, ier) = res - - if ier not in [1, 2, 3, 4]: - msg = "Optimal parameters not found: " + errmsg - raise RuntimeError(msg) - - if (len(ydata) > len(p0)) and pcov is not None: - s_sq = (func(popt, *args)**2).sum()/(len(ydata)-len(p0)) - pcov = pcov * s_sq - else: - pcov = np.inf - - return (popt, pcov, infodict, errmsg, ier) if return_full else (popt, pcov) - - class ThreadPool: """Pool of threads consuming tasks from a queue.""" From 82c741d6bbfd5ebf2d0d82fb611c3d80a20110f5 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 9 Dec 2019 05:32:38 +0100 Subject: [PATCH 35/78] crystallite not needed anymore --- processing/pre/geom_fromDREAM3D.py | 1 - processing/pre/geom_fromOsteonGeometry.py | 3 --- processing/pre/geom_fromVoronoiTessellation.py | 1 - processing/pre/hybridIA_linODFsampling.py | 6 ------ processing/pre/patchFromReconstructedBoundaries.py | 4 ---- 5 files changed, 15 deletions(-) diff --git a/processing/pre/geom_fromDREAM3D.py b/processing/pre/geom_fromDREAM3D.py index 159793cd8..7d5b1442d 100755 --- a/processing/pre/geom_fromDREAM3D.py +++ b/processing/pre/geom_fromDREAM3D.py @@ -145,7 +145,6 @@ for name in filenames: config_header += [''] for i in range(np.nanmax(microstructure)): config_header += ['[{}{}]'.format(label,i+1), - 'crystallite 1', '(constituent)\tphase {}\ttexture {}\tfraction 1.0'.format(phase[i],i+1), ] diff --git a/processing/pre/geom_fromOsteonGeometry.py b/processing/pre/geom_fromOsteonGeometry.py index 499a8867f..627d92728 100755 --- a/processing/pre/geom_fromOsteonGeometry.py +++ b/processing/pre/geom_fromOsteonGeometry.py @@ -126,15 +126,12 @@ for i in range(3,np.max(microstructure)): config_header = ['', '[canal]', - 'crystallite 1', '(constituent)\tphase 1\ttexture 1\tfraction 1.0', '[interstitial]', - 'crystallite 1', '(constituent)\tphase 2\ttexture 2\tfraction 1.0' ] for i in range(3,np.max(microstructure)): config_header += ['[Point{}]'.format(i-2), - 'crystallite 1', '(constituent)\tphase 3\ttexture {}\tfraction 1.0'.format(i) ] diff --git a/processing/pre/geom_fromVoronoiTessellation.py b/processing/pre/geom_fromVoronoiTessellation.py index 28e215f85..d5ec43701 100755 --- a/processing/pre/geom_fromVoronoiTessellation.py +++ b/processing/pre/geom_fromVoronoiTessellation.py @@ -290,7 +290,6 @@ for name in filenames: config_header += [''] for ID in grainIDs: config_header += ['[Grain{}]'.format(ID), - 'crystallite 1', '(constituent)\tphase {}\ttexture {}\tfraction 1.0'.format(options.phase,ID) ] diff --git a/processing/pre/hybridIA_linODFsampling.py b/processing/pre/hybridIA_linODFsampling.py index cf1a473cf..caa747337 100755 --- a/processing/pre/hybridIA_linODFsampling.py +++ b/processing/pre/hybridIA_linODFsampling.py @@ -211,10 +211,6 @@ parser.add_option('-p','--phase', dest = 'phase', type = 'int', metavar = 'int', help = 'phase index to be used [%default]') -parser.add_option('--crystallite', - dest = 'crystallite', - type = 'int', metavar = 'int', - help = 'crystallite index to be used [%default]') parser.add_option('-r', '--rnd', dest = 'randomSeed', type = 'int', metavar = 'int', \ @@ -223,7 +219,6 @@ parser.set_defaults(randomSeed = None, number = 500, algorithm = 'IA', phase = 1, - crystallite = 1, ang = True, ) @@ -351,7 +346,6 @@ for name in filenames: for i,ID in enumerate(range(nSamples)): materialConfig += ['[Grain%s]'%(str(ID+1).zfill(formatwidth)), - 'crystallite %i'%options.crystallite, '(constituent) phase %i texture %s fraction 1.0'%(options.phase,str(ID+1).rjust(formatwidth)), ] diff --git a/processing/pre/patchFromReconstructedBoundaries.py b/processing/pre/patchFromReconstructedBoundaries.py index fabec0fdf..e9196916e 100755 --- a/processing/pre/patchFromReconstructedBoundaries.py +++ b/processing/pre/patchFromReconstructedBoundaries.py @@ -941,19 +941,15 @@ if any(output in options.output for output in ['spectral','mentat']): for i,grain in enumerate(rcData['grainMapping']): config+=['[grain{}]'.format(grain), - 'crystallite\t1', '(constituent)\tphase 1\ttexture {}\tfraction 1.0'.format(i+1)] if (options.xmargin > 0.0): config+=['[x-margin]', - 'crystallite\t1', '(constituent)\tphase 2\ttexture {}\tfraction 1.0\n'.format(len(rcData['grainMapping'])+1)] if (options.ymargin > 0.0): config+=['[y-margin]', - 'crystallite\t1', '(constituent)\tphase 2\ttexture {}\tfraction 1.0\n'.format(len(rcData['grainMapping'])+1)] if (options.xmargin > 0.0 and options.ymargin > 0.0): config+=['[xy-margin]', - 'crystallite\t1', '(constituent)\tphase 2\ttexture {}\tfraction 1.0\n'.format(len(rcData['grainMapping'])+1)] if (options.xmargin > 0.0 or options.ymargin > 0.0): From acc252ea5b8ebf316c75bf10cd291c67d12f9e44 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 9 Dec 2019 05:38:15 +0100 Subject: [PATCH 36/78] thermal/damage constitutive (i.e. source) results are not tested --- src/constitutive.f90 | 89 +------------------------------------------- src/crystallite.f90 | 16 +------- 2 files changed, 3 insertions(+), 102 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index 4067c026a..6ad5c76cc 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -50,7 +50,6 @@ module constitutive constitutive_SandItsTangents, & constitutive_collectDotState, & constitutive_collectDeltaState, & - constitutive_postResults, & constitutive_results contains @@ -101,51 +100,14 @@ subroutine constitutive_init if (any(phase_kinematics == KINEMATICS_slipplane_opening_ID)) call kinematics_slipplane_opening_init if (any(phase_kinematics == KINEMATICS_thermal_expansion_ID)) call kinematics_thermal_expansion_init - write(6,'(/,a)') ' <<<+- constitutive init -+>>>' + write(6,'(/,a)') ' <<<+- constitutive init -+>>>'; flush(6) mainProcess: if (worldrank == 0) then !-------------------------------------------------------------------------------------------------- ! write description file for constitutive output call IO_write_jobFile(FILEUNIT,'outputConstitutive') PhaseLoop: do ph = 1,material_Nphase - activePhase: if (any(material_phaseAt == ph)) then - write(FILEUNIT,'(/,a,/)') '['//trim(config_name_phase(ph))//']' - - SourceLoop: do s = 1, phase_Nsources(ph) - knownSource = .true. ! assume valid - sourceType: select case (phase_source(s,ph)) - case (SOURCE_damage_isoBrittle_ID) sourceType - ins = source_damage_isoBrittle_instance(ph) - outputName = SOURCE_damage_isoBrittle_label - thisOutput => source_damage_isoBrittle_output - thisSize => source_damage_isoBrittle_sizePostResult - case (SOURCE_damage_isoDuctile_ID) sourceType - ins = source_damage_isoDuctile_instance(ph) - outputName = SOURCE_damage_isoDuctile_label - thisOutput => source_damage_isoDuctile_output - thisSize => source_damage_isoDuctile_sizePostResult - case (SOURCE_damage_anisoBrittle_ID) sourceType - ins = source_damage_anisoBrittle_instance(ph) - outputName = SOURCE_damage_anisoBrittle_label - thisOutput => source_damage_anisoBrittle_output - thisSize => source_damage_anisoBrittle_sizePostResult - case (SOURCE_damage_anisoDuctile_ID) sourceType - ins = source_damage_anisoDuctile_instance(ph) - outputName = SOURCE_damage_anisoDuctile_label - thisOutput => source_damage_anisoDuctile_output - thisSize => source_damage_anisoDuctile_sizePostResult - case default sourceType - knownSource = .false. - end select sourceType - if (knownSource) then - write(FILEUNIT,'(a)') '(source)'//char(9)//trim(outputName) - OutputSourceLoop: do o = 1,size(thisOutput(:,ins)) - if(len_trim(thisOutput(o,ins)) > 0) & - write(FILEUNIT,'(a,i4)') trim(thisOutput(o,ins))//char(9),thisSize(o,ins) - enddo OutputSourceLoop - endif - enddo SourceLoop - endif activePhase + if (any(material_phaseAt == ph)) write(FILEUNIT,'(/,a,/)') '['//trim(config_name_phase(ph))//']' enddo PhaseLoop close(FILEUNIT) endif mainProcess @@ -169,8 +131,6 @@ subroutine constitutive_init plasticState(ph)%sizeDotState) constitutive_source_maxSizeDotState = max(constitutive_source_maxSizeDotState, & maxval(sourceState(ph)%p(:)%sizeDotState)) - constitutive_source_maxSizePostResults = max(constitutive_source_maxSizePostResults, & - maxval(sourceState(ph)%p(:)%sizePostResults)) enddo PhaseLoop2 @@ -639,51 +599,6 @@ subroutine constitutive_collectDeltaState(S, Fe, Fi, ipc, ip, el) end subroutine constitutive_collectDeltaState -!-------------------------------------------------------------------------------------------------- -!> @brief returns array of constitutive results -!-------------------------------------------------------------------------------------------------- -function constitutive_postResults(S, Fi, ipc, ip, el) - - integer, intent(in) :: & - ipc, & !< component-ID of integration point - ip, & !< integration point - el !< element - real(pReal), dimension(sum(sourceState(material_phaseAt(ipc,el))%p(:)%sizePostResults)) :: & - constitutive_postResults - real(pReal), intent(in), dimension(3,3) :: & - Fi !< intermediate deformation gradient - real(pReal), intent(in), dimension(3,3) :: & - S !< 2nd Piola Kirchhoff stress - integer :: & - startPos, endPos - integer :: & - i, of, instance !< counter in source loop - - constitutive_postResults = 0.0_pReal - - - endPos = 0 - - SourceLoop: do i = 1, phase_Nsources(material_phaseAt(ipc,el)) - startPos = endPos + 1 - endPos = endPos + sourceState(material_phaseAt(ipc,el))%p(i)%sizePostResults - of = material_phasememberAt(ipc,ip,el) - sourceType: select case (phase_source(i,material_phaseAt(ipc,el))) - case (SOURCE_damage_isoBrittle_ID) sourceType - constitutive_postResults(startPos:endPos) = source_damage_isoBrittle_postResults(material_phaseAt(ipc,el),of) - case (SOURCE_damage_isoDuctile_ID) sourceType - constitutive_postResults(startPos:endPos) = source_damage_isoDuctile_postResults(material_phaseAt(ipc,el),of) - case (SOURCE_damage_anisoBrittle_ID) sourceType - constitutive_postResults(startPos:endPos) = source_damage_anisoBrittle_postResults(material_phaseAt(ipc,el),of) - case (SOURCE_damage_anisoDuctile_ID) sourceType - constitutive_postResults(startPos:endPos) = source_damage_anisoDuctile_postResults(material_phaseAt(ipc,el),of) - end select sourceType - - enddo SourceLoop - -end function constitutive_postResults - - !-------------------------------------------------------------------------------------------------- !> @brief writes constitutive results to HDF5 output file !-------------------------------------------------------------------------------------------------- diff --git a/src/crystallite.f90 b/src/crystallite.f90 index 292241001..dffd4079a 100644 --- a/src/crystallite.f90 +++ b/src/crystallite.f90 @@ -742,23 +742,9 @@ function crystallite_postResults(ipc, ip, el) ip, & !< integration point index ipc !< grain index - real(pReal), dimension(1+ & - 1+sum(sourceState(material_phaseAt(ipc,el))%p(:)%sizePostResults)) :: & - crystallite_postResults - integer :: & - c - + real(pReal), dimension(2) :: crystallite_postResults crystallite_postResults = 0.0_pReal - crystallite_postResults(1) = 0.0_pReal ! header-like information (length) - c = 1 - - crystallite_postResults(c+1) = real(sum(sourceState(material_phaseAt(ipc,el))%p(:)%sizePostResults),pReal) ! size of constitutive results - c = c + 1 - if (size(crystallite_postResults)-c > 0) & - crystallite_postResults(c+1:size(crystallite_postResults)) = & - constitutive_postResults(crystallite_S(1:3,1:3,ipc,ip,el), crystallite_Fi(1:3,1:3,ipc,ip,el), & - ipc, ip, el) end function crystallite_postResults From 07ebd8d1b3e92efe14e76d7b67c475a503539360 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 9 Dec 2019 05:48:37 +0100 Subject: [PATCH 37/78] only damage/thermal 'homogenization' postResults is currently needed --- src/crystallite.f90 | 18 ------------------ src/damage_nonlocal.f90 | 2 +- src/homogenization.f90 | 10 +++------- 3 files changed, 4 insertions(+), 26 deletions(-) diff --git a/src/crystallite.f90 b/src/crystallite.f90 index dffd4079a..4ae87b82e 100644 --- a/src/crystallite.f90 +++ b/src/crystallite.f90 @@ -108,7 +108,6 @@ module crystallite crystallite_stressTangent, & crystallite_orientations, & crystallite_push33ToRef, & - crystallite_postResults, & crystallite_results contains @@ -732,23 +731,6 @@ function crystallite_push33ToRef(ipc,ip,el, tensor33) end function crystallite_push33ToRef -!-------------------------------------------------------------------------------------------------- -!> @brief return results of particular grain -!-------------------------------------------------------------------------------------------------- -function crystallite_postResults(ipc, ip, el) - - integer, intent(in):: & - el, & !< element index - ip, & !< integration point index - ipc !< grain index - - real(pReal), dimension(2) :: crystallite_postResults - - crystallite_postResults = 0.0_pReal - -end function crystallite_postResults - - !-------------------------------------------------------------------------------------------------- !> @brief writes crystallite results to HDF5 output file !-------------------------------------------------------------------------------------------------- diff --git a/src/damage_nonlocal.f90 b/src/damage_nonlocal.f90 index 0a8a3c867..d37f68486 100644 --- a/src/damage_nonlocal.f90 +++ b/src/damage_nonlocal.f90 @@ -55,7 +55,7 @@ contains !-------------------------------------------------------------------------------------------------- subroutine damage_nonlocal_init - integer :: maxNinstance,homog,instance,o,i + integer :: maxNinstance,homog,instance,i integer :: sizeState integer :: NofMyHomog, h integer(kind(undefined_ID)) :: & diff --git a/src/homogenization.f90 b/src/homogenization.f90 index 0112f9cf5..c5250f9d2 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -583,7 +583,7 @@ end subroutine materialpoint_stressAndItsTangent !-------------------------------------------------------------------------------------------------- -!> @brief parallelized calculation of result array at material points +!> @brief calculation of result array at material points !-------------------------------------------------------------------------------------------------- subroutine materialpoint_postResults @@ -595,7 +595,6 @@ subroutine materialpoint_postResults i, & !< integration point number e !< element number - !$OMP PARALLEL DO PRIVATE(myNgrains,thePos,theSize) elementLooping: do e = FEsolving_execElem(1),FEsolving_execElem(2) myNgrains = homogenization_Ngrains(material_homogenizationAt(e)) IpLooping: do i = FEsolving_execIP(1,e),FEsolving_execIP(2,e) @@ -615,15 +614,12 @@ subroutine materialpoint_postResults thePos = thePos + 1 grainLooping :do g = 1,myNgrains - theSize = 1 + & - 1 + & - sum(sourceState(material_phaseAt(g,e))%p(:)%sizePostResults) - materialpoint_results(thePos+1:thePos+theSize,i,e) = crystallite_postResults(g,i,e) ! tell crystallite results + theSize = 2 + materialpoint_results(thePos+1:thePos+theSize,i,e) = 0.0_pReal thePos = thePos + theSize enddo grainLooping enddo IpLooping enddo elementLooping - !$OMP END PARALLEL DO end subroutine materialpoint_postResults From 1c180864022c5484813ced9b85725938441efc02 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 9 Dec 2019 05:58:27 +0100 Subject: [PATCH 38/78] not needed anymore --- src/constitutive.f90 | 18 ++++-------------- src/homogenization.f90 | 3 +-- 2 files changed, 5 insertions(+), 16 deletions(-) diff --git a/src/constitutive.f90 b/src/constitutive.f90 index 6ad5c76cc..2d0688467 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -37,7 +37,6 @@ module constitutive integer, public, protected :: & constitutive_plasticity_maxSizeDotState, & - constitutive_source_maxSizePostResults, & constitutive_source_maxSizeDotState public :: & @@ -60,17 +59,9 @@ contains !-------------------------------------------------------------------------------------------------- subroutine constitutive_init - integer, parameter :: FILEUNIT = 204 integer :: & - o, & !< counter in output loop ph, & !< counter in phase loop - s, & !< counter in source loop - ins !< instance of plasticity/source - - integer, dimension(:,:), pointer :: thisSize - character(len=64), dimension(:,:), pointer :: thisOutput - character(len=32) :: outputName !< name of output, intermediate fix until HDF5 output is ready - logical :: knownSource + s !< counter in source loop !-------------------------------------------------------------------------------------------------- ! initialized plasticity @@ -105,16 +96,15 @@ subroutine constitutive_init mainProcess: if (worldrank == 0) then !-------------------------------------------------------------------------------------------------- ! write description file for constitutive output - call IO_write_jobFile(FILEUNIT,'outputConstitutive') + call IO_write_jobFile(204,'outputConstitutive') PhaseLoop: do ph = 1,material_Nphase - if (any(material_phaseAt == ph)) write(FILEUNIT,'(/,a,/)') '['//trim(config_name_phase(ph))//']' + if (any(material_phaseAt == ph)) write(204,'(/,a,/)') '['//trim(config_name_phase(ph))//']' enddo PhaseLoop - close(FILEUNIT) + close(204) endif mainProcess constitutive_plasticity_maxSizeDotState = 0 constitutive_source_maxSizeDotState = 0 - constitutive_source_maxSizePostResults = 0 PhaseLoop2:do ph = 1,material_Nphase !-------------------------------------------------------------------------------------------------- diff --git a/src/homogenization.f90 b/src/homogenization.f90 index c5250f9d2..5be988ec3 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -262,8 +262,7 @@ subroutine homogenization_init materialpoint_sizeResults = 1 & ! grain count + 1 + thermal_maxSizePostResults & + damage_maxSizePostResults & - + homogenization_maxNgrains * ( 1 & ! crystallite size - + 1 + constitutive_source_maxSizePostResults) + + homogenization_maxNgrains * 2 ! obsolete header information allocate(materialpoint_results(materialpoint_sizeResults,discretization_nIP,discretization_nElem)) write(6,'(/,a)') ' <<<+- homogenization init -+>>>' From 19bc6863275b4d9059e7ea0989508b843870c6fe Mon Sep 17 00:00:00 2001 From: Test User Date: Mon, 9 Dec 2019 06:02:49 +0100 Subject: [PATCH 39/78] [skip ci] updated version information after successful test of v2.0.3-1237-g5a2053cd --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 35ae2dc0f..1439ed27c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v2.0.3-1228-g3e269f04 +v2.0.3-1237-g5a2053cd From eef6ae5733a662da968bb05318c994b9e05221e7 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 9 Dec 2019 06:12:14 +0100 Subject: [PATCH 40/78] shell scripts are deprecated --- .gitlab-ci.yml | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6e82561c5..a2d4fb6a2 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -506,18 +506,6 @@ GridSolver: - master - release -Processing: - stage: createDocumentation - script: - - cd $DAMASKROOT/processing/pre - - $DAMASKROOT/PRIVATE/documenting/scriptHelpToWiki.py --debug *.py - - cd $DAMASKROOT/processing/post - - rm vtk2ang.py DAD*.py - - $DAMASKROOT/PRIVATE/documenting/scriptHelpToWiki.py --debug *.py - except: - - master - - release - ################################################################################################## backupData: stage: saveDocumentation @@ -528,7 +516,6 @@ backupData: - mv $TESTROOT/performance/time.png $BACKUP/${CI_PIPELINE_ID}_${CI_COMMIT_SHA}/ - mv $TESTROOT/performance/memory.png $BACKUP/${CI_PIPELINE_ID}_${CI_COMMIT_SHA}/ - mv $DAMASKROOT/PRIVATE/documenting/DAMASK_* $BACKUP/${CI_PIPELINE_ID}_${CI_COMMIT_SHA}/ - - mv $DAMASKROOT/processing $BACKUP/${CI_PIPELINE_ID}_${CI_COMMIT_SHA}/ only: - development From 5abe27ab60e81d47d01c35c141e8cc913b29e1ce Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Mon, 9 Dec 2019 06:24:37 +0100 Subject: [PATCH 41/78] only locally used --- src/source_damage_anisoBrittle.f90 | 4 ++-- src/source_damage_isoBrittle.f90 | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/source_damage_anisoBrittle.f90 b/src/source_damage_anisoBrittle.f90 index 9997f81e5..a68f7b315 100644 --- a/src/source_damage_anisoBrittle.f90 +++ b/src/source_damage_anisoBrittle.f90 @@ -21,10 +21,10 @@ module source_damage_anisoBrittle source_damage_anisoBrittle_offset, & !< which source is my current source mechanism? source_damage_anisoBrittle_instance !< instance of source mechanism - integer, dimension(:,:), allocatable, target, public :: & + integer, dimension(:,:), allocatable :: & source_damage_anisoBrittle_sizePostResult !< size of each post result output - character(len=64), dimension(:,:), allocatable, target, public :: & + character(len=64), dimension(:,:), allocatable :: & source_damage_anisoBrittle_output !< name of each post result output integer, dimension(:,:), allocatable :: & diff --git a/src/source_damage_isoBrittle.f90 b/src/source_damage_isoBrittle.f90 index 89f5a038c..f6b99555f 100644 --- a/src/source_damage_isoBrittle.f90 +++ b/src/source_damage_isoBrittle.f90 @@ -18,9 +18,9 @@ module source_damage_isoBrittle integer, dimension(:), allocatable, public, protected :: & source_damage_isoBrittle_offset, & source_damage_isoBrittle_instance - integer, dimension(:,:), allocatable, target, public :: & + integer, dimension(:,:), allocatable :: & source_damage_isoBrittle_sizePostResult - character(len=64), dimension(:,:), allocatable, target, public :: & + character(len=64), dimension(:,:), allocatable :: & source_damage_isoBrittle_output enum, bind(c) From 4be7aa990c0c4afbe507e65fe3817febbd003e45 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 10 Dec 2019 06:45:00 +0100 Subject: [PATCH 42/78] HDF5 results output for constitutive damage models --- src/source_damage_anisoBrittle.f90 | 52 +++++++++++---------------- src/source_damage_anisoDuctile.f90 | 56 ++++++++++++------------------ src/source_damage_isoBrittle.f90 | 54 ++++++++++++---------------- src/source_damage_isoDuctile.f90 | 55 ++++++++++++----------------- 4 files changed, 88 insertions(+), 129 deletions(-) diff --git a/src/source_damage_anisoBrittle.f90 b/src/source_damage_anisoBrittle.f90 index a68f7b315..5dc8b96af 100644 --- a/src/source_damage_anisoBrittle.f90 +++ b/src/source_damage_anisoBrittle.f90 @@ -13,6 +13,7 @@ module source_damage_anisoBrittle use discretization use config use lattice + use results implicit none private @@ -21,9 +22,6 @@ module source_damage_anisoBrittle source_damage_anisoBrittle_offset, & !< which source is my current source mechanism? source_damage_anisoBrittle_instance !< instance of source mechanism - integer, dimension(:,:), allocatable :: & - source_damage_anisoBrittle_sizePostResult !< size of each post result output - character(len=64), dimension(:,:), allocatable :: & source_damage_anisoBrittle_output !< name of each post result output @@ -61,7 +59,7 @@ module source_damage_anisoBrittle source_damage_anisoBrittle_init, & source_damage_anisoBrittle_dotState, & source_damage_anisobrittle_getRateAndItsTangent, & - source_damage_anisoBrittle_postResults + source_damage_anisoBrittle_results contains @@ -102,7 +100,6 @@ subroutine source_damage_anisoBrittle_init enddo enddo - allocate(source_damage_anisoBrittle_sizePostResult(maxval(phase_Noutput),Ninstance), source=0) allocate(source_damage_anisoBrittle_output(maxval(phase_Noutput),Ninstance)) source_damage_anisoBrittle_output = '' @@ -154,7 +151,6 @@ subroutine source_damage_anisoBrittle_init select case(outputs(i)) case ('anisobrittle_drivingforce') - source_damage_anisoBrittle_sizePostResult(i,source_damage_anisoBrittle_instance(p)) = 1 source_damage_anisoBrittle_output(i,source_damage_anisoBrittle_instance(p)) = outputs(i) prm%outputID = [prm%outputID, damage_drivingforce_ID] @@ -171,7 +167,6 @@ subroutine source_damage_anisoBrittle_init call material_allocateSourceState(phase,sourceOffset,NofMyPhase,1,1,0) - sourceState(phase)%p(sourceOffset)%sizePostResults = sum(source_damage_anisoBrittle_sizePostResult(:,instance)) sourceState(phase)%p(sourceOffset)%aTolState=param(instance)%aTol @@ -262,39 +257,32 @@ subroutine source_damage_anisobrittle_getRateAndItsTangent(localphiDot, dLocalph dLocalphiDot_dPhi = -sourceState(phase)%p(sourceOffset)%state(1,constituent) -end subroutine source_damage_anisobrittle_getRateAndItsTangent +end subroutine source_damage_anisoBrittle_getRateAndItsTangent !-------------------------------------------------------------------------------------------------- -!> @brief return array of local damage results +!> @brief writes results to HDF5 output file !-------------------------------------------------------------------------------------------------- -function source_damage_anisoBrittle_postResults(phase, constituent) +subroutine source_damage_anisoBrittle_results(phase,group) - integer, intent(in) :: & - phase, & - constituent - - real(pReal), dimension(sum(source_damage_anisoBrittle_sizePostResult(:, & - source_damage_anisoBrittle_instance(phase)))) :: & - source_damage_anisoBrittle_postResults - - integer :: & - instance, sourceOffset, o, c - - instance = source_damage_anisoBrittle_instance(phase) + integer, intent(in) :: phase + character(len=*), intent(in) :: group +#if defined(PETSc) || defined(DAMASK_HDF5) + integer :: sourceOffset, o, instance + + instance = source_damage_anisoBrittle_instance(phase) sourceOffset = source_damage_anisoBrittle_offset(phase) - c = 0 - - do o = 1,size(param(instance)%outputID) - select case(param(instance)%outputID(o)) + associate(prm => param(instance), stt => sourceState(phase)%p(sourceOffset)%state) + outputsLoop: do o = 1,size(prm%outputID) + select case(prm%outputID(o)) case (damage_drivingforce_ID) - source_damage_anisoBrittle_postResults(c+1) = & - sourceState(phase)%p(sourceOffset)%state(1,constituent) - c = c + 1 - + call results_writeDataset(group,stt,'tbd','driving force','tbd') end select - enddo -end function source_damage_anisoBrittle_postResults + enddo outputsLoop + end associate +#endif + +end subroutine source_damage_anisoBrittle_results end module source_damage_anisoBrittle diff --git a/src/source_damage_anisoDuctile.f90 b/src/source_damage_anisoDuctile.f90 index 409466e48..caba26ef4 100644 --- a/src/source_damage_anisoDuctile.f90 +++ b/src/source_damage_anisoDuctile.f90 @@ -12,6 +12,7 @@ module source_damage_anisoDuctile use discretization use material use config + use results implicit none private @@ -20,9 +21,6 @@ module source_damage_anisoDuctile source_damage_anisoDuctile_offset, & !< which source is my current damage mechanism? source_damage_anisoDuctile_instance !< instance of damage source mechanism - integer, dimension(:,:), allocatable, target, public :: & - source_damage_anisoDuctile_sizePostResult !< size of each post result output - character(len=64), dimension(:,:), allocatable, target, public :: & source_damage_anisoDuctile_output !< name of each post result output @@ -54,7 +52,7 @@ module source_damage_anisoDuctile source_damage_anisoDuctile_init, & source_damage_anisoDuctile_dotState, & source_damage_anisoDuctile_getRateAndItsTangent, & - source_damage_anisoDuctile_postResults + source_damage_anisoDuctile_results contains @@ -96,7 +94,6 @@ subroutine source_damage_anisoDuctile_init enddo enddo - allocate(source_damage_anisoDuctile_sizePostResult(maxval(phase_Noutput),Ninstance),source=0) allocate(source_damage_anisoDuctile_output(maxval(phase_Noutput),Ninstance)) source_damage_anisoDuctile_output = '' @@ -139,7 +136,6 @@ subroutine source_damage_anisoDuctile_init select case(outputs(i)) case ('anisoductile_drivingforce') - source_damage_anisoDuctile_sizePostResult(i,source_damage_anisoDuctile_instance(p)) = 1 source_damage_anisoDuctile_output(i,source_damage_anisoDuctile_instance(p)) = outputs(i) prm%outputID = [prm%outputID, damage_drivingforce_ID] @@ -156,8 +152,7 @@ subroutine source_damage_anisoDuctile_init sourceOffset = source_damage_anisoDuctile_offset(phase) call material_allocateSourceState(phase,sourceOffset,NofMyPhase,1,1,0) - sourceState(phase)%p(sourceOffset)%sizePostResults = sum(source_damage_anisoDuctile_sizePostResult(:,instance)) - sourceState(phase)%p(sourceOffset)%aTolState=param(instance)%aTol + sourceState(phase)%p(sourceOffset)%aTolState=param(instance)%aTol enddo @@ -226,35 +221,28 @@ end subroutine source_damage_anisoDuctile_getRateAndItsTangent !-------------------------------------------------------------------------------------------------- -!> @brief return array of local damage results +!> @brief writes results to HDF5 output file !-------------------------------------------------------------------------------------------------- -function source_damage_anisoDuctile_postResults(phase, constituent) +subroutine source_damage_anisoDuctile_results(phase,group) - integer, intent(in) :: & - phase, & - constituent - real(pReal), dimension(sum(source_damage_anisoDuctile_sizePostResult(:, & - source_damage_anisoDuctile_instance(phase)))) :: & - source_damage_anisoDuctile_postResults - - integer :: & - instance, sourceOffset, o, c - - instance = source_damage_anisoDuctile_instance(phase) + integer, intent(in) :: phase + character(len=*), intent(in) :: group +#if defined(PETSc) || defined(DAMASK_HDF5) + integer :: sourceOffset, o, instance + + instance = source_damage_anisoDuctile_instance(phase) sourceOffset = source_damage_anisoDuctile_offset(phase) - - c = 0 - - do o = 1,size(param(instance)%outputID) - select case(param(instance)%outputID(o)) - case (damage_drivingforce_ID) - source_damage_anisoDuctile_postResults(c+1) = & - sourceState(phase)%p(sourceOffset)%state(1,constituent) - c = c + 1 - - end select - enddo -end function source_damage_anisoDuctile_postResults + associate(prm => param(instance), stt => sourceState(phase)%p(sourceOffset)%state) + outputsLoop: do o = 1,size(prm%outputID) + select case(prm%outputID(o)) + case (damage_drivingforce_ID) + call results_writeDataset(group,stt,'tbd','driving force','tbd') + end select + enddo outputsLoop + end associate +#endif + +end subroutine source_damage_anisoDuctile_results end module source_damage_anisoDuctile diff --git a/src/source_damage_isoBrittle.f90 b/src/source_damage_isoBrittle.f90 index f6b99555f..e38c15682 100644 --- a/src/source_damage_isoBrittle.f90 +++ b/src/source_damage_isoBrittle.f90 @@ -12,14 +12,13 @@ module source_damage_isoBrittle use discretization use material use config + use results implicit none private integer, dimension(:), allocatable, public, protected :: & source_damage_isoBrittle_offset, & source_damage_isoBrittle_instance - integer, dimension(:,:), allocatable :: & - source_damage_isoBrittle_sizePostResult character(len=64), dimension(:,:), allocatable :: & source_damage_isoBrittle_output @@ -46,7 +45,7 @@ module source_damage_isoBrittle source_damage_isoBrittle_init, & source_damage_isoBrittle_deltaState, & source_damage_isoBrittle_getRateAndItsTangent, & - source_damage_isoBrittle_postResults + source_damage_isoBrittle_Results contains @@ -85,8 +84,7 @@ subroutine source_damage_isoBrittle_init source_damage_isoBrittle_offset(phase) = source enddo enddo - - allocate(source_damage_isoBrittle_sizePostResult(maxval(phase_Noutput),Ninstance),source=0) + allocate(source_damage_isoBrittle_output(maxval(phase_Noutput),Ninstance)) source_damage_isoBrittle_output = '' @@ -122,7 +120,6 @@ subroutine source_damage_isoBrittle_init select case(outputs(i)) case ('isobrittle_drivingforce') - source_damage_isoBrittle_sizePostResult(i,source_damage_isoBrittle_instance(p)) = 1 source_damage_isoBrittle_output(i,source_damage_isoBrittle_instance(p)) = outputs(i) prm%outputID = [prm%outputID, damage_drivingforce_ID] @@ -139,7 +136,6 @@ subroutine source_damage_isoBrittle_init sourceOffset = source_damage_isoBrittle_offset(phase) call material_allocateSourceState(phase,sourceOffset,NofMyPhase,1,1,1) - sourceState(phase)%p(sourceOffset)%sizePostResults = sum(source_damage_isoBrittle_sizePostResult(:,instance)) sourceState(phase)%p(sourceOffset)%aTolState=param(instance)%aTol enddo @@ -214,35 +210,31 @@ subroutine source_damage_isoBrittle_getRateAndItsTangent(localphiDot, dLocalphiD - sourceState(phase)%p(sourceOffset)%state(1,constituent) end subroutine source_damage_isoBrittle_getRateAndItsTangent - -!-------------------------------------------------------------------------------------------------- -!> @brief return array of local damage results -!-------------------------------------------------------------------------------------------------- -function source_damage_isoBrittle_postResults(phase, constituent) - integer, intent(in) :: & - phase, & - constituent - real(pReal), dimension(sum(source_damage_isoBrittle_sizePostResult(:, & - source_damage_isoBrittle_instance(phase)))) :: & - source_damage_isoBrittle_postResults - integer :: & - instance, sourceOffset, o, c - - instance = source_damage_isoBrittle_instance(phase) +!-------------------------------------------------------------------------------------------------- +!> @brief writes results to HDF5 output file +!-------------------------------------------------------------------------------------------------- +subroutine source_damage_isoBrittle_results(phase,group) + + integer, intent(in) :: phase + character(len=*), intent(in) :: group +#if defined(PETSc) || defined(DAMASK_HDF5) + integer :: sourceOffset, o, instance + + instance = source_damage_isoBrittle_instance(phase) sourceOffset = source_damage_isoBrittle_offset(phase) - c = 0 - - do o = 1,size(param(instance)%outputID) - select case(param(instance)%outputID(o)) + associate(prm => param(instance), stt => sourceState(phase)%p(sourceOffset)%state) + outputsLoop: do o = 1,size(prm%outputID) + select case(prm%outputID(o)) case (damage_drivingforce_ID) - source_damage_isoBrittle_postResults(c+1) = sourceState(phase)%p(sourceOffset)%state(1,constituent) - c = c + 1 - + call results_writeDataset(group,stt,'tbd','driving force','tbd') end select - enddo -end function source_damage_isoBrittle_postResults + enddo outputsLoop + end associate +#endif + +end subroutine source_damage_isoBrittle_results end module source_damage_isoBrittle diff --git a/src/source_damage_isoDuctile.f90 b/src/source_damage_isoDuctile.f90 index 65930cd07..69b8e82bf 100644 --- a/src/source_damage_isoDuctile.f90 +++ b/src/source_damage_isoDuctile.f90 @@ -11,6 +11,7 @@ module source_damage_isoDuctile use discretization use material use config + use results implicit none private @@ -18,9 +19,6 @@ module source_damage_isoDuctile source_damage_isoDuctile_offset, & !< which source is my current damage mechanism? source_damage_isoDuctile_instance !< instance of damage source mechanism - integer, dimension(:,:), allocatable, target, public :: & - source_damage_isoDuctile_sizePostResult !< size of each post result output - character(len=64), dimension(:,:), allocatable, target, public :: & source_damage_isoDuctile_output !< name of each post result output @@ -46,7 +44,7 @@ module source_damage_isoDuctile source_damage_isoDuctile_init, & source_damage_isoDuctile_dotState, & source_damage_isoDuctile_getRateAndItsTangent, & - source_damage_isoDuctile_postResults + source_damage_isoDuctile_Results contains @@ -86,7 +84,6 @@ subroutine source_damage_isoDuctile_init enddo enddo - allocate(source_damage_isoDuctile_sizePostResult(maxval(phase_Noutput),Ninstance),source=0) allocate(source_damage_isoDuctile_output(maxval(phase_Noutput),Ninstance)) source_damage_isoDuctile_output = '' @@ -122,7 +119,6 @@ subroutine source_damage_isoDuctile_init select case(outputs(i)) case ('isoductile_drivingforce') - source_damage_isoDuctile_sizePostResult(i,source_damage_isoDuctile_instance(p)) = 1 source_damage_isoDuctile_output(i,source_damage_isoDuctile_instance(p)) = outputs(i) prm%outputID = [prm%outputID, damage_drivingforce_ID] @@ -138,9 +134,7 @@ subroutine source_damage_isoDuctile_init sourceOffset = source_damage_isoDuctile_offset(phase) call material_allocateSourceState(phase,sourceOffset,NofMyPhase,1,1,0) - sourceState(phase)%p(sourceOffset)%sizePostResults = sum(source_damage_isoDuctile_sizePostResult(:,instance)) sourceState(phase)%p(sourceOffset)%aTolState=param(instance)%aTol - enddo @@ -196,35 +190,32 @@ subroutine source_damage_isoDuctile_getRateAndItsTangent(localphiDot, dLocalphiD dLocalphiDot_dPhi = -sourceState(phase)%p(sourceOffset)%state(1,constituent) end subroutine source_damage_isoDuctile_getRateAndItsTangent - -!-------------------------------------------------------------------------------------------------- -!> @brief return array of local damage results -!-------------------------------------------------------------------------------------------------- -function source_damage_isoDuctile_postResults(phase, constituent) - integer, intent(in) :: & - phase, & - constituent - real(pReal), dimension(sum(source_damage_isoDuctile_sizePostResult(:, & - source_damage_isoDuctile_instance(phase)))) :: & - source_damage_isoDuctile_postResults - integer :: & - instance, sourceOffset, o, c +!-------------------------------------------------------------------------------------------------- +!> @brief writes results to HDF5 output file +!-------------------------------------------------------------------------------------------------- +subroutine source_damage_isoDuctile_results(phase,group) + + integer, intent(in) :: phase + character(len=*), intent(in) :: group +#if defined(PETSc) || defined(DAMASK_HDF5) + integer :: sourceOffset, o, instance - instance = source_damage_isoDuctile_instance(phase) - sourceOffset = source_damage_isoDuctile_offset(phase) + instance = source_damage_isoDuctile_instance(phase) + sourceOffset = source_damage_isoDuctile_offset(phase) - c = 0 + associate(prm => param(instance), stt => sourceState(phase)%p(sourceOffset)%state) + outputsLoop: do o = 1,size(prm%outputID) + select case(prm%outputID(o)) + case (damage_drivingforce_ID) + call results_writeDataset(group,stt,'tbd','driving force','tbd') + end select + enddo outputsLoop + end associate +#endif - do o = 1,size(param(instance)%outputID) - select case(param(instance)%outputID(o)) - case (damage_drivingforce_ID) - source_damage_isoDuctile_postResults(c+1) = sourceState(phase)%p(sourceOffset)%state(1,constituent) - c = c + 1 +end subroutine source_damage_isoDuctile_results - end select - enddo -end function source_damage_isoDuctile_postResults end module source_damage_isoDuctile From 5681e661e2472f2692e067635c87913ac80bf937 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 10 Dec 2019 07:14:39 +0100 Subject: [PATCH 43/78] DADF5-results replaces postResults --- src/damage_local.f90 | 31 +++++++++++++++++++++++++++++- src/damage_nonlocal.f90 | 32 ++++++++++++++++++++++++++++++- src/homogenization.f90 | 42 +++++++++++++++++++++++++---------------- 3 files changed, 87 insertions(+), 18 deletions(-) diff --git a/src/damage_local.f90 b/src/damage_local.f90 index 74ad47c9b..5ce27c339 100644 --- a/src/damage_local.f90 +++ b/src/damage_local.f90 @@ -11,6 +11,7 @@ module damage_local use source_damage_isoDuctile use source_damage_anisoBrittle use source_damage_anisoDuctile + use results implicit none private @@ -42,7 +43,8 @@ module damage_local public :: & damage_local_init, & damage_local_updateState, & - damage_local_postResults + damage_local_postResults, & + damage_local_Results contains @@ -210,6 +212,33 @@ subroutine damage_local_getSourceAndItsTangent(phiDot, dPhiDot_dPhi, phi, ip, el end subroutine damage_local_getSourceAndItsTangent +!-------------------------------------------------------------------------------------------------- +!> @brief writes results to HDF5 output file +!-------------------------------------------------------------------------------------------------- +module subroutine damage_local_results(homog,group) + + integer, intent(in) :: homog + character(len=*), intent(in) :: group +#if defined(PETSc) || defined(DAMASK_HDF5) + integer :: o, instance + + instance = damage_typeInstance(homog) + associate(prm => param(instance)) + + outputsLoop: do o = 1,size(prm%outputID) + select case(prm%outputID(o)) + + case (damage_ID) + call results_writeDataset(group,damage(homog)%p,'phi',& + 'damage indicator','-') + end select + enddo outputsLoop + end associate +#endif + +end subroutine damage_local_results + + !-------------------------------------------------------------------------------------------------- !> @brief return array of damage results !-------------------------------------------------------------------------------------------------- diff --git a/src/damage_nonlocal.f90 b/src/damage_nonlocal.f90 index d37f68486..d7e1aa074 100644 --- a/src/damage_nonlocal.f90 +++ b/src/damage_nonlocal.f90 @@ -14,6 +14,7 @@ module damage_nonlocal use source_damage_isoDuctile use source_damage_anisoBrittle use source_damage_anisoDuctile + use results implicit none private @@ -45,7 +46,8 @@ module damage_nonlocal damage_nonlocal_getDiffusion33, & damage_nonlocal_getMobility, & damage_nonlocal_putNonLocalDamage, & - damage_nonlocal_postResults + damage_nonlocal_postResults, & + damage_nonlocal_Results contains @@ -246,6 +248,34 @@ subroutine damage_nonlocal_putNonLocalDamage(phi,ip,el) end subroutine damage_nonlocal_putNonLocalDamage + +!-------------------------------------------------------------------------------------------------- +!> @brief writes results to HDF5 output file +!-------------------------------------------------------------------------------------------------- +module subroutine damage_nonlocal_results(homog,group) + + integer, intent(in) :: homog + character(len=*), intent(in) :: group +#if defined(PETSc) || defined(DAMASK_HDF5) + integer :: o, instance + + instance = damage_typeInstance(homog) + associate(prm => param(instance)) + + outputsLoop: do o = 1,size(prm%outputID) + select case(prm%outputID(o)) + + case (damage_ID) + call results_writeDataset(group,damage(homog)%p,'phi',& + 'damage indicator','-') + end select + enddo outputsLoop + end associate +#endif + +end subroutine damage_nonlocal_results + + !-------------------------------------------------------------------------------------------------- !> @brief return array of damage results !-------------------------------------------------------------------------------------------------- diff --git a/src/homogenization.f90 b/src/homogenization.f90 index 5be988ec3..842c5f4b6 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -23,7 +23,6 @@ module homogenization use damage_local use damage_nonlocal use results - use HDF5_utilities implicit none private @@ -790,33 +789,44 @@ subroutine homogenization_results material_homogenization_type => homogenization_type integer :: p - character(len=256) :: group + character(len=pStringLen) :: group_base,group !real(pReal), dimension(:,:,:), allocatable :: temp do p=1,size(config_name_homogenization) - group = trim('current/materialpoint')//'/'//trim(config_name_homogenization(p)) - call HDF5_closeGroup(results_addGroup(group)) - - group = trim(group)//'/mech' - - call HDF5_closeGroup(results_addGroup(group)) - select case(material_homogenization_type(p)) - case(HOMOGENIZATION_rgc_ID) - call mech_RGC_results(homogenization_typeInstance(p),group) - end select - - group = trim('current/materialpoint')//'/'//trim(config_name_homogenization(p))//'/generic' - call HDF5_closeGroup(results_addGroup(group)) + group_base = 'current/materialpoint/'//trim(config_name_homogenization(p)) + call results_closeGroup(results_addGroup(group_base)) + group = trim(group_base)//'/generic' + call results_closeGroup(results_addGroup(group)) !temp = reshape(materialpoint_F,[3,3,discretization_nIP*discretization_nElem]) !call results_writeDataset(group,temp,'F',& ! 'deformation gradient','1') !temp = reshape(materialpoint_P,[3,3,discretization_nIP*discretization_nElem]) !call results_writeDataset(group,temp,'P',& ! '1st Piola-Kirchoff stress','Pa') + + group = trim(group_base)//'/mech' + call results_closeGroup(results_addGroup(group)) + select case(material_homogenization_type(p)) + case(HOMOGENIZATION_rgc_ID) + call mech_RGC_results(homogenization_typeInstance(p),group) + end select + + group = trim(group_base)//'/damage' + call results_closeGroup(results_addGroup(group)) + select case(damage_type(p)) + case(DAMAGE_LOCAL_ID) + call damage_local_results(p,group) + case(DAMAGE_NONLOCAL_ID) + call damage_nonlocal_results(p,group) + end select + + group = trim(group_base)//'/thermal' + call results_closeGroup(results_addGroup(group)) + + enddo - enddo #endif end subroutine homogenization_results From ca06c1d3a294228d70235f3cfd7bd9e15360da60 Mon Sep 17 00:00:00 2001 From: "f.basile" Date: Tue, 10 Dec 2019 13:49:33 +0100 Subject: [PATCH 44/78] Fix bugs in relatedOperations for NW,GT and GTprime. --- python/damask/orientation.py | 6 +- python/tests/reference/Rotation/1_BCC.pdf | Bin 0 -> 44551 bytes python/tests/reference/Rotation/1_FCC.pdf | Bin 0 -> 44391 bytes python/tests/reference/Rotation/2_BCC.pdf | Bin 0 -> 43118 bytes python/tests/reference/Rotation/2_FCC.pdf | Bin 0 -> 43107 bytes .../tests/reference/Rotation/PoleFigures_OR.m | 99 ++++++++++++++++++ python/tests/reference/Rotation/bcc_GT.txt | 2 +- .../tests/reference/Rotation/bcc_GT_prime.txt | 2 +- python/tests/reference/Rotation/bcc_NW.txt | 2 +- python/tests/reference/Rotation/fcc_GT.txt | 2 +- .../tests/reference/Rotation/fcc_GT_prime.txt | 2 +- python/tests/reference/Rotation/fcc_NW.txt | 2 +- 12 files changed, 108 insertions(+), 9 deletions(-) create mode 100644 python/tests/reference/Rotation/1_BCC.pdf create mode 100644 python/tests/reference/Rotation/1_FCC.pdf create mode 100644 python/tests/reference/Rotation/2_BCC.pdf create mode 100644 python/tests/reference/Rotation/2_FCC.pdf create mode 100644 python/tests/reference/Rotation/PoleFigures_OR.m diff --git a/python/damask/orientation.py b/python/damask/orientation.py index 65318f169..1b08d2937 100644 --- a/python/damask/orientation.py +++ b/python/damask/orientation.py @@ -875,7 +875,7 @@ class Lattice: [[ 17, 12, 5],[ 17, 7, 17]], [[ 5, 17, 12],[ 17, 17, 7]], [[ 12, -5,-17],[ 7,-17,-17]], - [[-17,-12, 5],[-17, 7, 17]]],dtype='float')} + [[-17,-12, 5],[-17,-7, 17]]],dtype='float')} # Greninger--Troiano' orientation relationship for fcc <-> bcc transformation # from Y. He et al., Journal of Applied Crystallography 39:72-81, 2006 @@ -901,7 +901,7 @@ class Lattice: [[-17,-17, 7],[-17, -5, 12]], [[ 7,-17,-17],[ 12,-17, -5]], [[ 17, -7,-17],[ 5, -12,-17]], - [[ 17,-17, 7],[ 17, -5,-12]], + [[ 17,-17, -7],[ 17, -5,-12]], [[ -7, 17,-17],[-12, 17, -5]], [[-17, 7,-17],[ -5, 12,-17]], [[-17, 17, -7],[-17, 5,-12]]],dtype='float'), @@ -957,7 +957,7 @@ class Lattice: [[ 2, 1, -1],[ 0, -1, 1]], [[ -1, -2, -1],[ 0, -1, 1]], [[ -1, 1, 2],[ 0, -1, 1]], - [[ -1, 2, 1],[ 0, -1, 1]], + [[ 2, -1, 1],[ 0, -1, 1]], #It is wrong in the paper, but matrix is correct [[ -1, 2, 1],[ 0, -1, 1]], [[ -1, -1, -2],[ 0, -1, 1]]],dtype='float')} diff --git a/python/tests/reference/Rotation/1_BCC.pdf b/python/tests/reference/Rotation/1_BCC.pdf new file mode 100644 index 0000000000000000000000000000000000000000..fe22f6a2e36d180c423a1902b1a7409f866ff324 GIT binary patch literal 44551 zcma&NWmF!)(lv@Z!QsK(-QC^YA;<$kg1fs1cXxM(;O-XO-Gc`AOLETp-tYTy*Sddt z*35KQ*L3e)RcmH8xssR!Ju?Fv9C>*~WfdGV5fhQEu_YWI9~`5SgRO}((A0s5O4!Z_ zXl_a*p{PWpVd~&$VQWLg!obGBM6aqKtfVTXsK!I|X-3Qz=xl9j<0R=|WM^&xbYu~u zhGP_UFg0@e93W=oWJ*LO#>2wI%+1Wg%*4#f#>~o1%fw8{#6(FACm;Z4YGd+uW|sf; zfQV7f)W*!ooQU=Fk_r){goTyUr#FleR-d-SOo6s0rbM6P9GyO=u!eKXJnI~fK5wfh zU!1N<6^sSjieY3j?1`e`TxVL>X|AxVQvh}5efN$*Nu+{uq(A3YW%Zxi-ss_{#ZX1X zz>DMz{J7~CKzM)I{~-HK(EWaA#PK^{kN+ch{NsjnRB-N_9Nm=ZLoG31C8K-A%1=wV z*tP2nUvDiS-1~L=TfbyXd!+r4ryi>T<5kJW+uq0HBOzeMw}0#7haRtu&+F00&7-g2 z`}iEt?TGbHe`qA*AAyl>pYd)y=*+c`*N2#H{-xr`Zl-`p=4GYRWQXP<^);@A%`1y> z4ZSe(`P)aQjGIN?OR%rc7QZo7Ys*??RP2A5#0zAtWZE~Y{U*%ufo~c*4!{t(ClAKE zs;&JAaA3jCxxGF)J9KEI_{K+PY|>O55f>M0?ev-vWZaP8DUh{x#mo*zY;;Tg)G9b( z-P^i;F{*nDOW3xR5Fb8e4`K>05Tv9>iteSA6t^&GrW@Q7it+`Nk90JBGQ(pXLWcci zhE9Np2UnGj719bkJBah;Mj?HRF7^Af{!vEXH+jp6#r_6E#j8R5Y20quMx8Tv&24me zMe9|#3+cSoEZ4>6@LKo&kL)e@kcXB2TgvYREp_t2Kgwc%Ax-(%VHWUHG%KRM*Y25I zDG~-^rKVPS=!$I5qYCwc*E^(akWe((ixf;*gJ^$jGB&EH@?DHI3EFPADRodAP@lW^ zQ$ej>O0aUABj;oTR6dNO^L;Vw4_x))QS%vj8Kr*rkWD78a>2l9{5&x*RiU@8?o!gL zYr3sNVr!2>6G4-i#Ots{$CAqskM2!Q_>Hmja&sEujQVn;H^FNxB;A}yrPW6_Bp~q0 zY*=O^c5}@)1J-(hn|%6BkuDA87k~~~rJQft*c-iJ54&Q?0UbX>;7Q*Pr}N!! z#B?T`O$-1ev4hQv;X8ZW*pNHw;U6?6`-MR64lTX#z(4&`phKq& zZQKz%?%)SY!(#n3f|wXv7#uL)FKfftqY6e~$Hy*RwMC`EV;yH$dy@ip$EuBey&Ktg z_p2bRf>sKCZH`oLHE&|Dsh2LmyiYbjk`S1@6A zp=2;p9r>jz0%0E`^j5y!QOae$pj|lL(wqhK>obV&G_N^+@sQgDDCkV}9#SRRS~i=W zrei4;6VFDq{#8hjZO;tkml=R{o^mDEM4P?CMy7|JUlJcgVC7Jk`L*+#^sXM;!9|N@ zVA-Esu(u6o=#Z4F@9tBEB7Rj`ECf2)QjGRkI?+(y*;#z(K<2WLqOm`MCS}38YQtIs zq-2Ki5a3T3X=8ApV)M{t102G}>)WyFX;>E<;?%>RUv)D1h%}3PGfqx6)&%(rcMBLU1voUq5=|N0QbD>S1Z!DgxeeuYcHgwrwn7Ym1qto#mlQW;>yeXG54w1j}&kKbobia zVjoPT>A4ij2_f#9w%B%mT9RD1F8bF*t6p%EimQw{Fw!FYL4*^zu9^kfvnSm=HjX6A zwAXclwG}M1xj31B*2rk+YyQzzhQi2TN>dZdM~6oIQS)#I5~5P;t`;8XgTWlpBxfGBmkMi3m!%(6?N|y zO>*UrtXwBLW$#T^Ds5!*kMkhmam#>o33;4bx~=#x`ph&s$bOyuZOZA3s8^wgoaH(` z-+Y&IzuWUKt6n3FB^#AEQDqCS?KT*rf?g)J9YnZT6Hh%a0)_hxYB^|vf5Zfbtsj|a zDf{XM=&j?my(A0;+x5uU1UM)OiAk<%9+g%j2%5KWH2JXV(!6>%WGDv12$*TE{vo_A z!KqYfO;%17G&lEZ{z#BGTK`yq0s)`Qsf1$TNYf{a(pl;s78DDNj}H3EfA&W>dza_i zF7j<4$RY%JBfACi?J2p;L-byH;^iZ?%uDoE_59@sL)9^QsN_Luv58uVC1w-c;Q&_m z4+dwXSd{|atjPCd6g>|UlB+#|!yRDx@`nM&6^!d-Esc?X&1p--<+b`t`EN@C4Aa!- zYeaCh_j<6cTz70%nV(M!HVCa!VGBC}kN1?p!ifa9_GY&ZZ2|*>6f%l1Qe1~&;oHx7 zN#r`oR(w9bAzGOzw=I;t{RmLimYe~~38)fHlHAzhc%-x^FftBWW?>L5 z!%ksR*mc|_WJLJN6mKUkN=^~EU{eNCq3R?%-)#9G3&Gbk2GB@f?4v_uVffPkdcTOB z!rLVC3y(|NC4zR-#86`V5~Ft$oQA?~_ux!gxncMdh?EC_U{24VdZDoUs<^m?1H@I> zXp95m);j?`5O9KtMouXr9L`9gD_zgr_~Aiqk|24H!Q5_?WJB*vm4{O}6rQ=K`kq>N zfh$A{Qx;SQXRfqi7Dekj5OJQzit;naYK6p2gDpKOY%CV&R*`c{9QCuImEEYosa~vJ z3GO+6ImH!AN9ReQ(xR1|0dey2~luPhmT`Q%r zh8Ez~OkzTx9r0DOA1(&{vWQ+K-CZ&0UV+J;j`0TXwuB!? zAHg{vTaQN{&qjnF*E<9sgcE7QANNMAJ<@RZgwcB`@#ru(xwr= z5r_>`9LU^T4HtXf$YFhVv5~#BrFu~Y>d#OSB;b*a%|&Q(jjrKgi$&~WYrck{q*nHh z2L~~lQBgD*iS_R*TabaX2TKnO!ENaQc~b{9W>hC4jfWu4fy*W$bA?*d!_>zm zq6sodbM)^`MUy5LUi%dQLOlah%9KM-4V&YCKu(C4`?RCgBT`DH3}YCwUm;S=3bKL= zdJ_OD!37?5Nz78%ixMB;-!BWp(gmW*Z+y+A2&aax=4NI4X8(6$X+BGPtJC3^sVnAC{guKAxEm-cvzJ zNCaxGw=b0Ql|qy@CJ_b+dKR=I8r_z8dJ`VVpDD=T1_K*UgpXe=0oXZF>>2RelSeIH z1ZNhhLkJN~x~3R%--!yM3+zc{$^wxqCo3Wn$T7^~qh0a)P9!YViyWIvESaV@IyojSuK?U;p;`f5~S%F7Ugy=8*1U4;9?t>wuY)+ZrBz(*y}n z?Fv-kY22j`=u)HM{vf0cQk={)rGp+rjoj}>YeBVk#LRVjK|z#;2Q5Y5_qSPUae?#6C^elN(qi}c(!5#YPRBXzP!zz8|9)axOSXGu_c%!-9! z4ebSQ0wHyxc%++Vjm2Y%5&BaIGQO=4m=-sUB&6dGvi4XC(+Y2ksKHG4p(jFexB)>j%uw10nPQm%bQ7W3P>E3 zZ;0=V3H9x~e+bM!NdBPr7qbQHUG;Us87Wck*~8C$g=(7~`);1@U}%UnknH~$Y`*;+ zPMlRu+X`I^43tHis@9Ffh7yVhLNth$92g=3%q8eD@e)gp5sDYOhzC13dLkrqDdZ_- zgN6wKQ!}g7s2qU~qQ3!4g+lfE0pSKfjKg5gZesa^6S_hTx{6$LJ&&q4CE{;{1-_(C z6zspZtf7)On($Nam6XL*{TgIZmw6Ua7|l&`-MlkoA0|r=;9hJRNv!Iw(ii?dDjk4Q z8_HBa(eup?1d}?>g@=yom4OAy8Rj%nb8*BE!UhE%{4j1ACXJf3mh_5MyAs7;Si3Tf zgOmx;O(ZZx3`jXjk3ee-Wv)klOnG#@J#bm#ZD{WIB1vL(-KjC)nop-F;5deQLsw*+ z`kE?+1OipE4xS9Uf_x*U8vja#jzPh%eBV>+NMaNp)CP7w1YH>%8I16Y7`=Kxi5uq? zW(;AoxH3a*2F%}%i6C5pG>fht;j%CXjFd`%33I|e#91=?S3Xs01IXRTHBg5MTf~A| zV8rQVB(idk^Q%yT)={u+AcKbqW)`}X1q(>!L8TB|iKNR>x3JN+W?{IeA#dGKq>(S|Z$822di$gjqME@W`*Dl!h0EgfJKTR@Icl z!gWVh$jifY{>D?-1IEX!w21=02eZr{-~7qf;{wE8L12O$j4OiB9CP>4V#r-m17Z~* zfRnB!fvAe}q6)VQATr1Bknu$|gv7T^>Zd;sg|3f0D)045a$6k{HC?N%mCou;i7DFY zdYm1{!f_Oyh!YufiK5#lp58#;<_=KA+)`9?6B+u5?%GYjiE~tt((`3S^PHrm?`FlR zq{?J9PYW5Gg~Ln4iYb2Q>qzNG_OA;b@Jj6@zNtlpDj0&EmNArCwiAGkX7PkP|D+`( zb{>Ra%fW#sTWiGbA5nYMpM))|5K4#D=L|3rvvuI+Gk0+cetrprB1oj?gN=VJ3l0{; zu+A+aYy`GlK$T@iWGyN#J&K?@g50A>JvE{Ujg_DXi&p4j5f#nd=DIIhqY~ra!&$f4 z4Ev#G#O4G7uyNI*Ji?cp zY_%>p8rJ&FX8XMuN%1$94{R#DScJOO05AzmJPcRs8mSGVvB*d#RD$Qs>X~HY{hdA! zALpp;U>Y>=F3=k@hU6E>pWkdcngDV zNa9K5Uu_1@I^zu-DHaNY31qtYypq`qj zh~)i77Xt)Pj-SxEgGyp(SkpwN zOm7F`gNzRf*$udy?ln9Fv%}9ttd55ci1% zw1(z0d)l4rbxyGn!g!eJT*qQPlKwzgG6sW-0An~yUZv8*!|=$pYxycmHjEvdmkmsy zFF|*FjQ}yhHyTpC?VAzcTucm1;T(#NPi2 zOlm8MTN;?kg}~c83Kw5IFBW$0;W4oU^RrO#RN`{Wn~xE`T$7gP#sTOd_fCu<{y;*- zN81R{43uz+To48TG{*`h@a1Syq3FIyCH!$l2muZ6iiqJVx1y7-6aWO4txEp_7r~_s zbe)er1SR_=v7(p$#)pFu?N1sxGNePPIv{M;A0Y$C%|QSR3&ohFb&jJlTBKKsbLID!=XG2U=ReiI#-IiK)IRH5xIHqX~k6a3IA< zjgFb?$iqUAmEC6t36e*H%p6KPF`jkS5-HFw;2<$i9H@ghuViu*3nX}OC^`j>2dIZ% zWF0kS3nULwRXbi4_aC+gxkqcoH%I|YlCfAQf+B*BaU zrpNW*dplC1FardXxp;YQnLq%o=0)*5FxvpD9#jU@L40uN=w7ItD(Z>+C*n$P4a3|0SfS5y4IK^?|VSh{=Gx?V&+B33}B_2351wZ zw?P3Lg`XKJ#UGleXTIVoLxh+kq{fPqMH)#- z`NDuMZ+JG^hUv$vbr!`ZyZy$#yhSkU5i*^6$^#b8C^jlG4N36qm1j#shUIS{-~sED z>>34`OED=4z*-FjZ;|C0eC7c+cN11hWmww8z}!?aK%5eFUpI5xS&;_)uOheOutqa} zG`hlV2tOe58tXOE8PoQknK;{N9ojJPx^m~%OfrFLHIy=74)3XYGi{m>NGiL#&3ky=@NYQS~)lK>nIBM7> z)_&XePOT|pm^D1YUR95w7CqD-FEpyw<*<>fWHyFyhJdf^w3QoX9!JF3>C1M;ZE%~= z(rrVmCPy3I&q-j}kRse;K0+`W=88DWVgwe)8Bs~)&#U=ODSAL5ZBMb42$`~5TuNv( zx7`mgV~=GrkKe4VpP-imgoHbqhcn&p64k>EznASW8~y&-VVK&g;g>txQRzNVUjepE z%`HdBp%TrWE<^44%m>f_MvRH|yEv>ft~o^W_{)!HdbWQz@5j5@L}>IEY?m&XJCGx6 z2r@)O1ysKajm1P3G^UD%gDgDR%Mb`0{D zGbiG^JtK4Xnn#_diPnKxh#9W{S%Bf-7FxHd&4&e1NhnHALiVQ0z#mkIkQjwVJALNJ z!zOh7SGx@eHN4+BrFOf>O8*?TAz=^}?)=U*NeA*^M!5MX)G=S4oaA)`kxk3T{Um=J z&PSi6ij?~?QlW!6%OW39AG#HS3YhJIG*4{~3F*U*uiZW|Z(0j+z*VHhVzoZMctTR= zDeUzg6tw<<{AG~8(0w(#I{0WPooKeT34gX7g9x!mOe9eK3;pbFhA1Se1(W>mY%ld- z*}`7C$y#3=>rz)#oT570Bo<&=;!JKy#l~Kls56FzA8xF+j+Xy|mIDf^c?%E#dX`ti z$oa^6&)y9KC4uBK2|jTh=`%@~e1rX-jtxdyFx>r3qA&RvwALNWTn-PV)_pgE7if4B zlwt?f`z^P}QZV0;waZZPmT4JbTxE)D8NqCkkkG%@9h-@^RkH7JL3INgE(1&d&Wz6L zYb6tMwBd5c(D&0{wc0H6ULpP8{6*k*!b0T(U__21!{ostdwU7cG9U;GN3qc}ASn6+ z`RO=db)aB8^{h~5ruJExIAC2uU_8yORA3NL@0XVgr81k$?5tFTBGK-TmkV1n0kxiP zRw{0Gpwo}bg;dydXDId3y)1gmq9zH(E(mM*%=OZFtcJ^hCJFdGu|_fR^7r7t5Pmt1 z6?_Dod#)9e8maj!m_&IO1$f+xI2LOH>1Df^M0p8}y%2sijum4BJc7FV(V%{%X~Pwh zXJ&`xe$#}}kr|_y6!~HbU?{&KM_OsL7C*_i1dH)wBcwEW3g-S${%;&FzNCX zT)-dvmK}kr_KJE-vUqzo&Xu_6?W@Mn<%aL$gQejUwX+sL6b? zI*W^vHUNnVY?9mg$!f#NXdJ*RrD1@p?c`~Vm}zt zc>a8jU}Zr38F3T!Gl}vjX)y<+H6Zy+xQTkPzttqBT%MTZxRABFcuyu$`@UxtJ<52# zUUIRR2(v$#zma3G3(#^_*Fww`?^$s*Yqn5t_odHgAKfefpcAU-vuE(ywFAob@-ONC9#20j35|-6~HI$R@uHZ2P#V7WhNy}XK zJ%GE{c(+XGup?5sWH)V&JMnvHUwVVk1Os7&jRJxHBF28EV?fw>gtLNrng`83BQ}F0 z%^${aW=|XtM}f)JIlI(ZyLpCM&zH=?8%&1&2 z9H{vV>$r-S^dZ)DAz``DJmfBH>Ti`viP1gxn`T?ec07s>zo?1BNpA=*nbJ-AE^j=S zJqG(oB07lJjpHNkujG%Hm4~ksS3?3)}gz8k5*bx>mzR@9bi}Yfjx(bl7|Eq z-o>t}nNc*7qPxx)$#a(SG@poHC)Y=T~5|cd1nsgcMcBs@Y}3(Jrv0o-!|-{!-7h{3YL%V_By_USJvZTSS!{+sU~c zl}c5<0#!_vx)Rk;6|xG|OLe0PHC45#8nsb1t_F2R)uI;lOjW#21xA&)UWH8csa{1$ zb)i8;PqnU5#Z5J;NhML$qFJR@RlG%ILKVMN+|g7>Zt!&MD%Em5sh1^b zh*s3Byp-^~pzMo*wtAa~0X9%|vb%n#xC(6SKEnk-m0`b{nrk&_!5dhwT%wOW)||zm zNR{EX>X>JBVo?!N-&=xDFy@lO5ki&mG42!JtC`x87b!5*;c0p+e<;sbpvZcegzcSY z5juG+GWp^FHT`{al9k8mh9dXZuZ)&2QD1f&cg$~TOY~(5czMpPa5|SQc;}B_Px;lx z%ocHL5-X}6ETg`(ZEh8n zQ1{pF%Lc zo#l$53dj`~1Uxl-%@Ds<%oilZDC^W8;;0|^@9EN14uJ&;)N=w(lE0qZ7gWSc?$k*! z^$~MdTaHP<7H-9t2ud}W+f0nk7z^O>)l_lx3G;MTj_V`pKB8!bX5<~!5JOKJ3upwL zT(j%GnpmE&Ca1|o`GxEzmU+%7{bF&(!})Dk%pneZnwVcVr)o>%A&DyDQN=B)>oc?L zV#9=zr_Ts+$S<3o(+Xl^55@VOQk<*;9G#mFv#d-^U)79))KHzPsAKqUnZ%y#D391Y zL{nQvzof;-!G44DeX1DK(10i8?fr4w>TR?^cg3ZK9p8(}K@8XeAF{n}=U< z!9RYd4A~rB6Xu>rZD0a}>wJYN@b05_+Gub^0=Z;kwHN4uxCM2>&6+%h8QjdTP~B&K=(38$2#BldvKpSE)_y8EIr7+ao}lvo>yc7U zyRu3yW-D|{t-w&Z*+Zkawz=#}Eq<>`=fJ?L*vRH$bjNQ0j6jK{VQa`<4>4?Vxcw*K z6tPsGepd4O+vvT$jbdy=5g4xS;)vrp%QQiAHpUIWSGdbJ;ZtNAp!8PJ!>;k4h+d3JPkd=SYY5^0w#EU59?OhHFIJxwK%# z9=s%~j2=ANvo+vBtlLGgWrI3!h_o;{S(4~tNxK_Y^={aCxp@67;ebd2SIZphQNt$4 zxQeZ&WM6+$;Ock~_#1MX`5u$6r>dLFX>mpz^D$nfm*a`MMH4@UakB~3n}T|IOj-Z! zj#=+WIF~rcJJpIC|8?PRhr9bHSmuG@;e$^05l!R~k?cx$1f}K69(S3>O59Cs|FQgq zm+T@BZgl_e0~IO(Y@=nnxU~Qizc;p*q5E{J5Bejt56UG+C%Wrh(1&5gz4!2Lx5B+C zl!t?0Y$gV`FSGH~*o)a)r#jP z1H!jcA~mA+edN1tJ+=6uKg*^KF}VgU8CL{A839MqR|?Xj5CILO9GIPusKh9sW&r(V zCXB^L&rQ6bq}SJd;iaqKgGJz?R;oD&m$5Tpm8!~lti|J`|DEE6N+Mx^U{RQ>Kl)9U9Uxvcm!Q{<_Bk)LyD)()<)!Q&G+GI4p{g zKgW=ggD=fMZ55diS-rk$G(16@{y8PC3*9B#Y!(02l(p`@<&SW%U+5`gBwa@FwpbW> zX<=GAYvS&fUF^mBV+o^_7c);I??Nx50JW(^26ttmY6YT!{l(-AYyBs~8u_ohfV{B)_QYK7UNP zJM_`6kgVNBlDTOuS1(>m&&^S%_;D5!=O~(03hBHs&QT(|g}CHs_qKE%vDX~(Hb$7V zVbN*l`6$5Ay!!bG`c=b~AiSCv0-S-cuk%}KI!AVj3FAxe%TBo z0kUG7LNQZ1cRJg&f}RbA3pWWfy z2Q+=(4LF%&>iqV3;Oz@HrLDI64r1aSekO?<|95FzPQCGz4c{7$VmJGN$O1As(vyrIe6Ag*<-RFa`vU3?K-Ru znPsiv=g6GR^3B*jxl9gLQ3{_PQ758`%WGXyIKiPX-%sn*25pU#IY6h$PQbA@_ZWj7 zl+M_Qa+JjLXuW5OJ$#`e{OorMhSbeaYF?{n9Ae1Ty3Dh*q-9iR?4s%Z+w^~K;J_=w zgjv}Rew*Y&%jNm1^=Xi*^Kb|3#5y(vrznWRl-oliI!T6@Zs`Ov_UnzE|1F{mwWlM_ zNy0dqyj!94-5Gs1({rP`M{ghGuQg{D!7V`1Gwcz#`9e|vBVUju+tcljrr~Ps(fIoa@Ow=Doo-f5{jxgs9akn-Q|W^;v1=8+ZntPl z`3Z|o54jUbS>3P;RnfL|)*!9qp3ep`0`V!O$%$5fyUt}t z9~GVe*6H{Q?H-U3nG<6Jk< zYi24f53I3_XmD9b@9>+Y{W}ws#jVzZf9N8AhkSHN6UNXprdUq!F$Of2(539JiQ{m^ zh2?mH+B>us{^U%}v{88Df4F=wvh-T@LgWif8Z`rQ=KQEzsFpf`2Yr+M3+E6E8l#5r zP=jyWkHKdCYv@*5)UQXXkN^0=D65L-BmtD}ZK;as-PbA5t-nped;bp~6FtWqMtVy| zH0;?$kt+M!>*MJB6nTO z5M@(4-O;kbdXp1)`!{$@hOo_)!l?{;4b_H%avJxB-ol6vOo<%K!vAtSRT($R>nQU3 zi?hl-O5uX_<&)b9ITDuCrR*&FsYXWy2Y2#Caeb0nUe&D3UN7F@ik0$<&+LX>V>rz>bsLpJ9UqZ5FlDN;uEl zbka(4!jkU6HZi8Vb-_9Vo&@tQhUJlIRXlu2MI9b~;j=~RQAHol6S6wH;B)lGw4h6@0Ze#Vll}|%ag|OqWA<>5ewX+K z^3yk_1AoXb4n#p@h|%lG?i_jS6>Yb{wV#UvtI}ZT0bk6$I9ZqpmxylVizE!b&-1D8h6&4RahsvqIpdkZP}FNi-FjTI4kMa^gin{_PGhiZxHsTVVn zOV^~f8hYRskCs$zhs2^)Onx6Am5KgUnR^27^N#U%7sqE4C%(BoGC_cH;f){4Hq{j# z9CdFW8L)hYI}SO0xeP@Hj3aI9i=7%ApnmE1z|H@LWN+ryf3Lbxk>#l-#rCkWK6| zPWj6G&q>vLUFV`Uvst z0MjX=EQrkfcih|U=eQ(akIzurob`F^-z-V;eTId$q>It>f8(4_t?qe88jxE^4#QyW z?5;8yl-pvIy^9V@@_vq{>fHaAL(54v7r1wQh;J?Nu1VvaDtGiZ@;8-WI@`oM4U(hV zT{Id>UwCsgYW|@a@zS#I=5x-4pucFwCDHIqc*&5_aQ%yBee*6I@yNr$ym=En1YG zBlJB6|K;nZE}NBNOZeojo7!3{#Ja;au$TY0q7YqSdHoe{?e2zq_N|_psXm#>TR_@l z^j~GuI8zG8TptaMsbQ~6v&r>6na=xb@_+MuR8vNaBo5DEy|^wb10CZ>aL<2(7h6(o zlAc~f7gH~mTW0fMFvgOvK#K2w45D*{`;hI{S)Jmw5g)g3#o%>g1g;*5gg%P)= z^8xgV_%#u#>9Rh&%s=8o;R_#3%c_hV2SxSM9_>b3s}j|+>S#glMAC2nQwhS6`qEY> zo}un}*V!zh=Om|mh>YAu1jFY)kXyhRmNl$Erz%bLcNjka3~swwF`6&x9tpM}4rpUeT5+`0GkZj^9bEy_spwX6=iG zX^s!k=Xdk#>eBZ&m1B(gk8roLRg}*{$aYzyez)i|ywh+PjFxb!oz^Yd zhx#@mwaXy693O?&_&LOy{IdmTS{OW}m3+oe{Kq-O`oAcTa{G&Noaiis8|} zq$8lb3_Ve^?81@g%=_x=9Qj%7sH0q-64-Ymd$7kmf+p2`chl@HHv6+KyA0QoSGc&O)#g{&{G?rW*aFijBCf2)@MjL0 z*X7PwR&OnJ6Y>kkP%STRdlO5Anp4yzVi2LrD;_Rc%M4AwVere#Y2HmXM58=NP$5s3 zo23kj2yD=G^WziXo5v}D*MM0`L1$6hrPPc0)RAz<3QpNDNInu{BmDqq54Os=$NpDF zLj2QhnzE5zpjd*qkp5u6B!P|Ltb`)(4Gh;Y_sQ(eIc@8kj~M4K2pDc{a^!LC`a_f7d?63HpbE z{oC&y?OMvm-RPsJEeIX@`wm(_!_9ng)iwbgUHeV+(Z>k?|D_}$WfRMQ!%`(KAk2K* zrjziLv&tcRH5wk>&JloOWMZy#r6RVogv}+=lK*oRHfohQQ|gE-wAlRsUp0>&)9!FS zjoZqA-umI{hrGek$V5yQ0^?V8NjfbV zAz*TiOgK0#f~Mt;*kU2N+(`|W@dR3HbmcUCf9NpulVmJy)p8siaMGE-aTO(<^&WMX zRaAIuPFwc1x@#gxpmDc&Gkv5>neOqyIzGXswx0H8`Vuugg};sG4LkmSDM^4?KY6z> zTIVKs>5S#~s2uw0|GelgBCC+>H9ptvwS1cP4TFbl5UBaQhU=oLlpCa^b75Z}b zN_57GzR;{9Icq^9lU%!PO1;ptr6OWDRMXe1LI#5M;ybQWBP%uGUG7@QA8w0lrk?9l z$}4JadR4w)ePqS6`+WqYZ9VK9pA3alvlQ4D%7q1*Sc~jLu!!2z_UQ6RQKD{00sH|& zp%!>F@gc+}bV^$BS;#c?ltcIYI6+DblR+;5!eP35^4&*4M2Q&tXilYbFohD1LfTHO z?>#tLk`z;kTe)28db#p!_m#`rqnAs(f9&vaes+rP*%X$B`=dxTp)tbZIQoJPd5;*~ z^(Agm@@4gZEJ6Khe*Dhq__1TX7%wTP8>f1CNCAPXsH*#00 z5}pLwxJ)e1{ZU$aTO_I%G|vr+0!OPL6<%|^=OWS>3kAk=?qy(;X+T1uxDuIaT+BE* zAdWTig>_EY-_%uOr}%RXI8zO+ev>W+6h~~F8*a~y%pm3MWgJMtehZso*^#aD3@Gdm zU48@qlqe9Dwgl}Mc^Dc(RK7W$KiGmAX^Fi)ZcGvVHl{3`J00kcA9>FbGb3YP4BY0W z!uLs^^JftBz*XRZ3bEWSpeWfnGTkPO9FMt!fY3|B7?VfXH zXVM>}9HBKJvqt-;iYY zly(9K`Fn~uC=q76iiFi^(PnW@9!QAv0U^00h{9jHAd~asqzepz1Le(eNdhKsNdU($cGY1~ z4p2kbrA-Tmr|JGmvJHaa6;^sL5`db+S1|y8H16P2Au){tCRTgRm|fdfJw~^UItqP& zCaqNhKg;&Cvz+^8w`bVJcd>%%@;Sh9p4@CMZSdWSk!TbAo zXrhA3g7d<(6QG9zoMCkhq?nlhSMpGS82Fo0g=17d&4}|;@z4WZDGeec#dMh4^CK3H z=u8_cmp zzsK+qCt}B{cwxd73 zAxR;7)ZfmCtCO67ZWNouB-_#20hj9a;-Y?sE1VIo=!zl{xo|Au>|=5 z!DPWHzg}JWSY%wF;qkXN?=8+@+#w$;q~ezC(@&}*rS94QTpY5}WI@0@f)X(LYFQhom!_pjUN;(tT*Pw`;4gdM2qn6b?_`hLD)yO1n_X1oX_i7F{d} z`zGkbLfFPDsE-78(I{LNeI!cqJ7}O1N-UyA#LdFUCSNS!z~=iMoNGNSJ@L@lCrG`L zDIukrn>k{yL+NT+kt-gt2?#-5jOYk#i6;FIpAD%A<}uZ)Vo|Xu$e?{-Q9Cf{z}E<1 z#+yOtneqrh9bhtpme!;m%a2JQzeqzW4$sEjNe~G+_9G4JD=ADtUu2@9vTDXUq~=3E zg3-dxGQrxyzQI|5yTw8jA!xW^6E6`aR!sMx0ua;aDEwmKUUY<;jnsq#MDt;TA%05Y z0xFJBs8oq@z4r0~#Y(rWcPUwst#ZMwJ+bJJCOUe#2!sOs@j`;kFY{wLUX^4~tpW^z z;82L!F!XT2FGP(b9p&CN{?Bd!*8_$k`tYVk$*nq!9u0W7x73LL?Fs zumS`LB#CtXpxPyIWyaHF^&Mj>B~tSKo`y|+O?vB5=tcD#cH)6*KRX_r2j_$KFiE1p z2$6KTN7!bA2NCV|&cJ1pp{xxDQKX|$jF6PI3FF`}%7@sp1~NfMoZO{ zaU3TsfQ*4`)dQEE6@{SJ4>4GuRKt>L;3p_N z6b}Jkdsj*_$`YqUDlV3<7qD@Z{+eeG3IuB~B}87vj!5c5B;&J6AV`#Wkr67QpW~(Y$QD%yQkTX7B7xrA0h)_aO!d+R0#y}Uq zLQ4q>`WafHT2{^4&`3}91nJLk?@B*3;dM{5F3ZeQRsax+gdFe%ui5>%I67W*aVDt>H+z|>9Do#TZc6@E9O4Kr)J?z>s_V^&2B90xCZrh!L#&^IKq67{3H90f@jL@j+T_C5$YO z5R%SGD6%zKgjPrhA?ELxdQR|m5mu5^|Ji}Bu!+mf7ii(^qV8Wnzr>?)=MUTfw(X>`&Bj*aw6Sg5M&qQhZ5xek>%K|)zxRH6pY86Roij6MX0n~%o|gvNG)P!g zUS?cVxhsNDYk$`gGD)4zW2RySNg#g#a%k=$FG%V@lyX=d-xri?$xCUI@3E}SdaJwN zN~%wc3xY;z(bwAf*uwzG5~OcIB4q7FlAJ|gG-fz|j$cRWCzC%(IOSjH`}H+trZqB= zD^)9i78%3l8EK-7uMFV?3nscDgG;B3@F7QX)VGoT;fiI~Z$et}! ziWDPk)nCR8S1aZ|?;((p8D8{mhAaFNtsJ@CBp+lj)`@B1Gocy|`M$ zp^Ya@9P;aUt#Grr+@;BnZdYx1f}lC|1^TllSBq5N{PTztOc(E1M1)hhJ)y@!g`4?M zRF0V%1DSmI?EZ49D4OR6Hj|?8)Y(7C2cSsT`fR274D&3*&&pb*v0y@kez!4Rq@E34@HdAqIT&Y- z|LFZK&b$HDs$(UXM;H1E7GFWFgR0vy$JT`&k)va_zhR2bCO8FlljETKom=&Lsi6(a z+|LRAUViu4PrbO=S+vS%y0WO_N+Uz^=2+hg=B>xIstr61I&kTtE>XQem_@SCU|oJ7 z35An@@L)79j)4r*gTP6!^=YBPdXH5K0j>V3Xkx(nl&>G(Ml=i8tv1eq63QVdAQf^Bhzg_2}jU;>|cB1Q}Ta z^~`U>FUFu1th?zzMfZ6Dx7*fGd3}5=;W`&C!er`2G=Zic_>QqrCFO9-xa(J3q4ol z%kKrx9P^XmQJ8mpR7>fWKlUQSYA5ko+9T?ka{Pdn;=lc=9*Ou9fCg0K!~NuSLdiD# zS#>lyf$b43oL)1LfBe?;MhYuwD9;*`O(dh&%j-&-v1f4$l3iF?$JD6J<8fVp-L+GltBuIz`LPn2q^?L1Z+DO&@R)NojMdRL;Fjs0HT1g~%EJQ}LrUv(27jeWE@ zV|mh(^wagQ#$f^_h45=Gj>^cRP&=XCYe)54w}sB;TgK-yEu#R`NNvfgFP3LDUh45u zg3)m|#|0j+pF+MG$8ci3oXj*0AHlX%k%af@cy7XF?W#6X)-d`4@d(&8}GT zgAr28k{=KC{qWN_`2^J>8mkV*jwMLQSF%>g;4iG1HK}7U=@C@OCM;5D=16M_-Oc7N zk|^wZhp-6W<`oNqceYaLwt{wJ^R3iBaNj(G^-~C*vD&Wp?c)uMao`v2kwhq?KkOv> zI)n5J;33dw=5n?8>Dwk_sx-d-IrPvw6dH@C;`{aC>Fo0y@Do(lCL7iGd*JjD^j*-9 zBY|jw4&!{X-m^G=%|g%k2k1LHTY!(<1a-!hIP7ExnqYA@gUW4PfJ|C9tV0F#_Nb76 zI5jMO1Zw^2W!td+H3#yf-#;}a>`mt1@QOeVR%fD@7%2f22MerR2pbsEa=nO@Kn!D@ zKWa_Cjh}jm?n(d63?4@T35_GX4$i-EYIL6709Z@2S|gR>@9?IUrzmt;Pj??5b3SNe z=%3LW2SIyGXfGYu?vU}`Og7VTVEWUdHTw9IJayWMqMwpqoyVff5q{2lMJ#8k-p~nC!ghNwq;w{e_D}gG-`^K=OcvUq9HN=ra@OORdmw zz4u=xk{S`%FZiO$XAy&gHM+1riN;1GnJ713TJfK^4D}IQgJLzlTlTA0#sL}C6EEZ& zpqk1S>EZF@VJqV|wk>2x*(x)HU8|kmNrZEd zZ^YVP*v9mYF_4V zqbPd8nI`3nm`>`KLJ`2YdXAcgm=ux_6isT`!%*wPL>rHzCigCqVD(KBPvXUI^wo1c zs-6oa8`I3!V%@5eeZz2S6=18iEzD{aH=#Sql3i5wucDeH2puH6=Tf$d0=Hw;H!0(> zAOk@JKp&{srDlD;;44~|7Cric1L&rzW9|9#GG#(iG@Tp^WmpwAp&f32@H6NeXlW^o zp-+Z@4$*y5c!$NKDSuQS4M+ALlQoDO4FyF-rIOzw5w}tHe zxb#ptGZ7&lnFD5Fm)&Gs)RcYqd_|cP&!-$52&z-L03;xf^*hi z=G6;d(b;`0cTJC^dLdm3Z|{~2wuE~BsO$SIump!r9-Y?@WP1;gp0mT0M@_k!!LyPKO!)w{Jpy?$_n(PWyHX=FF32N(@q^|x6iA;N5PXVQsQma~k z;DKl_x%0yy7lK98LG#OEsDE?p9cBf((Iw|3PrucvX~D=%zv%E+kCfqOGGvN%I^rdS|$aT7W(}@pheM^8<9dDK2*JHQ-3orIbCW4eVqoSpWpB@zc7uB4mV@Z+D@X zX;2mUQ@ddEBEg3IxNb-{Sx_GZa^ao{gk}!o6U#R-gdCy?iPtmohG;Y*`pMdfQGRr1 zQw_u~T&Zdhb_gSJgbyrWUeStWM-%nr&atKJUDg~su?^Z+fvr+m#X=H0fM5Lb?v`4S zD@({Q;yT&FSvr5VfN33}G{6l=3G^X3Fipvd;Ah$|E z`^m1u+~X2sVLHFT))SPKCyjP^#!z~K_^hDFAxC;_ZUkvWs=V5V=f8mjLK+0cRH5?= zGL7_LDLV1F%B~-Ko_o6ksi@C5&DJ3Jj1*V;p3x9o^w8FPkc`Oxrx{e^SW=)6);&uWmLE9^7ch6y;#i)>`xv;^-PNYLL3-t4OyOdr#`w#K94M zXfM$Tgk>5q3OsPZ;-z6^`$%aJL}eP}3NLh(@P8|;@|*SbLJuo~^IeHeSCW%2QjZ4a z$|}ft#nn#;1oD)0XWMstf}*z_C@>{34C7)U3$bXRk?G}2N)gi@h|8Ap6nfd{IX&j9 z74nmq&N@E7*n4wS4nEUm6m+wg%FTwpM#BeK6YX%gPSKH0iX9rg#Cnp3o$%{*-ECBMlo3v`0;W1QR`!9#+(eOiblX%_yStsyShj0)sh|lQA}@@Wl(0R!5%r z4Mip@fn`^w4GH+*8_$MfMbutOdqTH-ja?Rm=?X*|q>$)g>!G45h!-Ib?ULpQ7-3*5$ARtGel}Au#nD#3qKez6K&Rte9=hy%GK>Ptk)}hZk^O&x*c)c2vuRBfl4`05 zm}TxkiigoEITy(m4KX7p7BI-ve$Ky;t#!0lDpI#qpf6T0R`^T=**+`P@u{ZHYIlWNikE)j3Z|roSUDe6CRN zw|S&ELxg{uFGl93)|%qR*k0s6%M7wlFXhL|6tQZMt0-De$m5i*&gWriw_r=&5B)++ zvaP@|STXpU(^uIf^c5FA zVte~OkT{4*H(137Q6~{uHPRIYe&P~)Qt-IV$!APOGf5{mS#;(VN&(`(_5okw+NRvd z6&Gcks$~}hRzL+w(Uo?g(^9aOEDL?}%_g#@GK+r)jHVY`;Zf`ss|W50l^t+qUp5tM z1W7}c;E-~paIpwau$#?LfF=?M@{>V%h6pJ+k8NggLq$z8aDb` z0?X29!FSyM#M2n6cLbChOl!Y{r&OKw3#LdMZYD!? zCSWgLxVTiPUH~IR&i<81sWUr;rf3j#rC1Dkcn@5rcvQIFPkx)dF=<+MDhE@xNC0o8 z&Ws9ovZcH?nQ#SHLWyF(T)ntm?Dns`gIuFe0!6{3Tbm+s{0T~aaJ_v5z0zeKXH1cN z<)4fNSzQ(<{*;vb=a<8zKIwccNPmu`w3)0Bou290%#p#qd>^|bp9bN1)v=orx2e@D0i z=X*_xfGS}9QOtyty4gPui%nhc`QWDXiYiQ#yUJG#c$r(YCUU?SswvvyrI;^S*CKC_ zRN$2Pfb@=$#5wQ`FF2DDw+`p^4Tqzd2F;+tcp9_)sd(TijmJ{M>b25wf5Tf|hXK3@ zrm9v{5pvQ4>o=o##7IOLoH7Xjy0yocs;S!IqXY>&MBs~n$k;0p>@FDm;s>BmoFa?n zUM^Bv;U?aO`~^{h1d@(@mKw4QpMWByosjLJyDqS!WkB=nj+i9T_R3dUr0Ser9+zTQ zV!u#jVNgx!^Qu?6kN!@>6dT)ASwO@GZ}`nv>tBBmG6%)p?kSpDO5?ntGh!G>>6tMg zOZ`-(tI;JMJ6oLxFs0?mF;2P;GpSDvFqz!m#42rJGX-ywfR<1?HtH3;ruQ2}Af-=N zR^qBN2RND~ZWX~~p`6g%EF<7Hpf(Brh{7}`#8mJ9f=dcOVdfjq$@mhM{-AGeGVS+_ z=Pp3pC9#-(MyhM~d2Xn^(|#s^JE0^YS@`rcAWf#M{k-M=YZDsN;u5Q*(8DH23Ez{X}{x+2Eu)95Lj5tN|@IVN1dJU0f z_!y5lu)CL5$7(S=%+(Vru)z?&p)h~0dp)x(EKS3J=fPCa+8rhRVdN)$%6b`Adq!`M zUOQVgaa3++F)(L+5+vGq2%2~!Wi%%fvu+elO4r_Kn4|8wQ8M=5&kuVl5Lp+GJ`mI| z*V)lbi80HnEZ+ezOgib<1)KPAb!aNg(>(o_&}WywdC=yeZ3CR70*kz7&0Aw%Gf-_3 ze)kTR^_6az(E(vqHb%^n7diGbJ?*qVkYWzjE5ni6Ep5v$E<$AS89J+R&mLVM)Yp(> z($2cJmTU6_fGH~8Oy}_B0$3ObWmoyT{L$!Nl62+O3zedRV>i?+XFi4-k815ph>~5< z83{8MFZ@ZGWcd<3_ zzIHH5DEBkKwS8N#cMduv#+b!wWv5~mw;8wmLGZ+BGdKprvGy2(yVpmkc`GglQ~rJ5T{^QkM%$5l9?LM#$485-fC;o8Hy0=lOy;|eWE zB9Lk9kmmOWvB&m8p`P($5LR5o_P3{K;h?0njt`^48XXswP|F^3eC<6@B0ZuJR60qk zJxm=@z#~%4Lx~Rv#=K>#Z10T|Fui{}_v0>Y1FhM3;?t6gKy8yXO-fvDf%Ik3MDoDB zH~hEayYJ=s>3cp>iNq;?HgWVDg~}ZZfdB3M-fPTdlvwa{7Ei=@dbX3h>qw2v4I}TZ z%i0Z8a=~|MZfm}48oBGzLAR-k3($a%lmFgy2{WbRYzv_&lVPG;8B`?kId&Aa?VN9MOBHQ`+y$eVY?%!9xlK{=%+WWM;udSon?k{8B z(=H0CI;PQKwwg?1QM&`i&bAeyxsRSv(~SjZ z7pJv=>bNEtz?EkK26QaPM8OtsN{5j@2}%F^HHY z@fAIZsa{^SIuFg3|F|9plBg~&3}UWz(8Q5mq-d!UmIE-6_uhHy$b1qDc<{Rz;I@NK zqhKd5;aLDxHTm8WduyqHI%3p(JuBW#TMZ0~iR4?Q^H5{?Z}KCn9b(iINhY{;>b4Ce z8k_PD|5}f4<65bIQi}b$;)B04!$*+}9sNx-eJTEK$y;5F1*l(LtLUT*@HQ zlVNC_QMApsTkRs|mcM{TZ?{Nc>$+*_(~%#lP$^K4NLp$DA0m54#N6Vn%c6Rp>iUiP zKUpG+Lzlp;Nw~i^HYXT9SOZTPCcQ98E-awkszR|;*A!T!2f$8)O`+=in=SLI^=QF? z1Q{Hhv~{h)Dc~M1(ch{Kcn{!B_D2@YW;v~<3Ew}!fr1=p<-Gmds{dM*9n3eC>R+i% z-$!C?S7Z*>Zpv(h_-G&Y-=Fq!IVOLGm3;LAfMC`YQcC9K$c)cMdHWx8AgoCAc3$T!6l}^k@12M{l~8c|3vSRJ4>>e?e36-+@IklGN+o1? zXeZL}z6S6Y!z~A*Fr8A=%z^Ar;k^S4ZjlFe(7}}&qeTr>MEjTj{;@>ybV}>s#RYf@ z>J9ONF#YQuh!k3hU)#utYjM$A%ECq4ApIV?f1ha;Yt(v?BgS7Dv@M|77U_O@W0Kww zy)~T#{~F{750R6=!t#mlr zn>_u~E}0e7Dyk?5S0;Eh*kM-V;NVspLf{9h=cjGEptpWcd-TVWdu+jWVsV?B`}f&D zugq6vO|dLnXy<0G6M#0r+~m04j|-Fe;20$I!&0Q!np!r(8bpDmNb{r4{zs`_Z+S zk8BL5fH@d%9*Wbt-z8ve$$n?@w5W0+0Dce*;3(?(DULTJ3hUUQ=+`y3?-zQv0NfP9 z(t99rQ^QbL%`R%4)miXmv}jONoo@osYB^U@TZ836ckl$&1YIl~V7h3~qi=LsWnW(tlLb)2by&;}JP{YJ^pFhYDFKGBY5@ zzqY^OHxwRzIjfl$Dr^Sa{l@J1O--^kwD+DO0lC0svsUZWWn1oz$N~UhO2%EK(R-%@lkfDF|GxcE?;^x? zOJ~f#<7o=_84)+@rqz$du2>tcMLe-a_0LAeXS(qHFnS+6_ufErimSDw(J_dPZNNrIu!Fe7*f&~q#kg< z9DpUhJ8bLV989?2O-dMWF=eTn?AYPcdqEjcWQD37y5L$dAm~G#$OH3H<^boLt(|a4 z-fEEj%lE}Tp?JVY%BBw@)q~RMBJU5f?y^6?!fZc{F3~cbRH^!pCtji85gBr{oxo@l zkfYtYcr(-kY+|^UK6*4P`+}m1;j{!@%R748q=*eC$cxOngRu@rmB?e6@Q;j2hPlcI9;71+>w6?Ix6*(ZEXpFBbu zd0>Wl9jyDS1At%|CcJQZ+ArksLdm-^gtFENs2E~yQuw;_Z@lMS7D*o~#0<^V;xTww z!#^?rfDreMiPGLKiP3GoMqxrN(*mB_ReE`+QA?gIbiT#Gn`m~Z`JsI#pO2inNKaR} zpOYjK9r51hPV_Dq)z~AS6;DK9VJo8Vo?$pZ{!jJwtrq2X>Izh)ocgpU782j%_bDq2 z-@M}u#Wkd4>BhoGE``#7?SZJ~NNm$f`hNaKp5r;7Jdpb-RtLy|P4SLrUpNd*qRPJ4 z6-#t5y(uHg)|U3^oKA!lbu=offFJz)s0JVDwtxQq+FE4Tf*$JLMy$}HuY2mfU;ST(&EKkvKG&|;-dIn! zYR#7y*90!w)%_?)>x$|dhKO*=l5lBqD>gDF+Q|VaV3Flt%@cpXs-gFT>%67A|8c$2 z-!Pdc;vFUh)Cdm3uwyrLFSy~{jnTIjRMiIm708%W3K4A_?3gR@7XHU=utXj` zAMCYTB1e4cfDc zJjO79b@95kT7St^MYM2#t1=!NO0)gAF)Dz7CjrunXz&^Ii)xlg?~8}vu7PqCde2ES zQFTKOn4V|L60VO@X)qW1X<#VV8Fw#rGM4$o{`hJ4O@X9h;&(i$qAUs`Af(t59t#>Y z%ocE|wXgY%I259DhNgoK)uVL_y{sDMs|bl&uJWv}4r(06*`4;-`BD1_HzEc*cWki0 z!BF1(P}ytbf$0o#x{c)*mi-!m9dVKBYBGxgj&%>YN~G3z_X;Ewl5@JrshCE1(>nEu zf>P35a;FBF`2Z2hyO7fNQBIB{>!!nh6d=xTW#BCAjJk*a+aW# zRp;&0708l3mR0GD9PVQN+sFyJzc?oN%%ymT_GFR@>9i8^ZJR5VPdtdEcHia*G-adQ z?8xutKZy>9oI8ZaJ+eLBu8Cn;Dkw8rX{amap9$ZsEv4x6;k?CV+pUE14x ztda&z&(#s0)!5A5&T>fhY^hq(-B$!#zh5lw!G$Lbc(8>}@|i4uBlIL*K##e|zKGRJ zXaM9S6jCc2u5gM3kHX!%0+3q)QrF65APc>T+0ssfOp0NWw{Psf9~%TY<&Z}kfN8$+ zV%$+kj)?^}KUPFNKwBiT#S+m1Z$`Muc&#Fs0bqfJSP&^bY=VrwGlF<+sur@kcEO;M)5R<{E`Y# z6qLcf^O1i&k9E(inWfV0K8!BM`>@G_=*y$vnrNjG>h-VED=+U#HKpjaQD-Yi31aC4 zlbyQyzd87@VnI_hfE2}M9}`=PPO-nKd{Qwyn6=enA~(`i&h$Z;$K%81+Z~u+7b%kt zw9eGc9)!o={e(kuI|%%b?Mc>9k2&fzr_hlurc|%g(^w$EEucz2No9qrg z^=>n9+?#2X9H&uwRP3sSs(O;f;>jzAJl+qFu9>Ia@SvHswVP4ZOsuL@H-8AXe4iI~ zeoy>}uz4D5Xx?%v1K!3gkBkHG9ho*C1LgfaL_qNm%_%XKNtt@9AKjnFJ0-U^2 z3sS|N@e5`fkpvXfNih^N8n?=6nsUqg94OWV;OC!(q~H*tj=)o9dOW&%Ub!KVGY@U2 zdw`^rN^H0cDgBz25=!Zn=^q-g-hBgBft}=gi6n1`pwydI1Xd#S|JDv(35N0NzekhO zaIyg;ZHa~jGmy|?vlg79TUg1rm0M2fmY#_nBlhK0NB`$a=r#FIZ2ODwhz~bT4xWOp zkvr{z{a7uNNCKYPVRWU5{yY3V_(&;C0K)!1&+MU-9?HU|X}=nyCzI5U&$oM1M`Zr! zX0g02Ai9VH2b5Iym?vLho4zR=5M30ZgX>eN^{buuxu2aZK8#1lOmB^!n+#1j^;Nn! zf+W{OX}=Bj-EB}s6>I{(5>oaMla&_IOk+;|a}a8YVZ@if8>1N3(7WyS1G{hgC1h!U zh1m!#ucEn93^mI*uc#dK)Iv?W{euO8&$+VOb`0Nc?<=56YN&jgHs>F3O*HWQ1#jq+V5F1RbiEL4Mu zU0D?5+y0@^M}SETuI#OwZ6@yb{TpNU^e@b6Z4dpd#LuHPFfNff;Aue&N~Q+{6xb>F zb_H$j-JTVTfp~7C8MK0hf{z;j>OtbFZLN=6YaWmkZ(4Ui8PlkHAKx$$T;akfjGoyJ zzTnoXnjSo*r1Q!!@#V|g(h}Fk`6K7Eq6f>&Ubg5#n($%7{h|FO_4eDS$&9xsMkCdO zCtbGKrjuNxeC#2Z98Abs<9W*XZWVj2@`LH%vGTU6qa;`duLgs~cg#yOFT-^^{#Op)J>dBHKS!z}m!D^&32 zpFr|96wr0AMp}g(Y-Pc}K=a-MRE1dI&&s-FAT6a0U=xiOPL}tnQUX4OBj>{|=;6tC`E9^409dzLZy6`TA%7nJC`%EMb&NYKTw48Nn?GO%q}kezQy z*{eQzDDJunpw_U#kC&Y~4%oyqI9(_7%;L4^A@0ckOCi?tt&9BfuKsPC$o5@gLV+^+ zMjcH2E-NVZb)!a|n;OH62gof8#qcXB@If>DcmXOttan4R#)uu}u} z`!$|&$jGC#0xG`_W^%=*%hAPFcoyrs*N9uNuG5l$ZJAkNYklo^xZhe60QaZgsLnqU zY`}5SfWKbR-+?1mD_Ki?)>H=}V=B#eybSC)N{xJ@`vI&fsd^DPj>`70wzc+a;q!bh zg@2a>nc6@m3fJ3vKFpManNdQ{9NrbEa3iP-pxNmqHmnY4elv(01u0{UsXd{|@-e z004imvB$Xc^0fbsu+*J@pNJJ@^pHpd)8SEv3I0N z?~EzR+{GiYEdv1gb1?5*AXofAHj=nUl-JI1_ORPK$I1k9N_MzceWH{1tZWRi;_3O( z=5?aB{Ap>r-(9o1!{-hs3U{asNzV{<(-`3ri-^<^%I@d!D%UWxXu{am+A% zz~w+7h*>|KY~yNw1N}WH0igf<8|dG#Ci=KwLWgOV`#Ndj^#3=Ed_tKL-dXR_(!E*x zHNIuLJ<`|Mc795(26D%mc>f1h1THhdC^&V3ON2L@oj*G2HYww^4Y$w)-T@h~W5EVXU|2IPktz-mc!T4hUY;Ca`27 zC!xF*;ImOd#)C4lY$UPtI6>S?7H3BI?ng5=o` z7uYB`VmrFy*#T^Zx1B8R?2X~8rSp0MyvI4sW{mQCa&60(SskcvL|VsAqxYHy)ky%; z4fK>V7i_s3JkA+Y%vKlh6%e>5fnT44fo82eE5jR%m~)qjOEB^0LM`U8wN7}+d?&Ry z8v~wyJ-AkcO2;-y%=7&;`R1Cw0dedEQf$H1`s#`447Y1Cr(1Ep><$*z$^T_JOyK+v z6A^KdpFm^UVWUpd;jDdPo@;49boVy>3Tlds1uXWL$;!E{k}gCxXfZK(nm)w+GtlHN zU^^(+=yDj3Riy{V^CLKBQpi?H=r8+1%xzGqGJizdBnSk~N*AI6#0Z|*qH&bHo3-fg zJtx*BSU4|Kf%ZMU5C61(*&p+lvbrJ8R8b5JS=@Hdgc?E3BkYkaDQe<3IL7C0zyj=z zx8zBOieYz_@+0Ubg}-z~P0(pgAMQG(XCe)_XqA1$o%-|4W^m z{rx#$l!@VkA%t z7hfS{jHytbzRn)u`}{8%w|#sc4j)az?Q&EM@~U7U4bLGUgySZil=y3}XebuvrqAgH z{(L8>UYqL{WIe11H8veM=0x6|?ZtXZ0`s3|4mNzE4bZ25JQ0xpFeZF#76pdYfS#@m zXlG5%DRxd&s>Xv(0hS*{dxuF^1wXWxl6BkU-I(547ui^M}KRK}#$ z?3|_gN)V@@pOv$5o;>}1eq!}^1*F1bnalAUA+KSfI3MUmdZZs3~~SZ*V%t zP)~&0a_)>QxghN1!uHB@s5q-fVnJq01Ph`HkUD*D5Xt9&2Eldr%>vOczyw~qkWolz zcs}C06KJwjvKgZfFYxXmsvy0UR;ibxXE2`QqD+X4LO?`NQMhO!=g;@+dZ2SU_Jnz{ zcsh^IXQ(G(4rjU32YBYtD)cI72&y2X$(txXnqGyYVe({d8+wo82#RrI&-k_@8b+)? zwrMAXJ+T7N=S9CD(CeWh)fspvpa|4lVG5Xt^cO`_iouUYHd{LF2D_Q#(`NBmMZ(n# z{L#f25Ny2$LJ}KCI6Jmn74tV@#@U+v#gB!PqhR9e2|#46BZV|cOC8%XR;aptjLQ&3 z(c291#4(DJW>tS4@ddJEvg+Y4!9W2C))<$6uA|!(eE`?kBh^DbHRl$Kdt$7W1428? z<9I=;R~oo0S)sgI*4oJhPUJ1VJ%_2*0t-MIPB2#7p&It46DhRs1msRWo}AZLNT z?#Qa3l6*h6G=7W-fvD;eGAlQ=H|v=2z#s)(at5WDFE`cmS^6AnIwC-Ofk^4v5-RB+ zyOf+0Y^Kn~Bi^||r6NH-PBY6TFovS7qW}SYVeJFwU5`C)pEv#S6;VtvcKIo68dM|Q z1N`%{fCfoJ+9%U+(wi_LFVKN`t3+b{K-x4x#qQM5jLUh2bCten5UvoEX+U%= zD{>;S=wRD!frr&tZ?GJ5l2w9XHhJX>8eH`kEPujxq)YS?p=kch0R52vP@_;$23_W- z(Y^Y+0hbaQUH0 zFG*RU;ISksXg%}XkqIH_WX}fcyQ^{~5vz}gKHINkK=vvQ_B?u5XtQ8Pk{FIz*jLslFyYOOR7Thy{aLrqZYuoc z>$D*l|m(;ApqhpUDR3&VASMVOzy z-X5i91*Q>|gtgk-k#qxN&zgtJ9Tg4^c>))7>FYteom}QlP-!G=@R((sja*(D4DvWJ zB6XDDl+P!^pwZM7F;0O_xBmhD4A-n8@mw+#!G|hIW zfk0u(!^wl?!vlM_j9Uk2wC|Xjcw2%!VmFfZrgd{MQL#!}2Hbbk-AK1*tMNRR*|OYN z*+&UIR)U2umrXM5A~gDZk|9v{Zkdere{Ir$r!&JZCk(J!)iGk|POIV-jgm{sWgA!YuUf3=)2rVyMLATa`%kA;600B0Bd;muW&Heq>mxI>KR z;dUNh&(v2C5WuZ5x}E6r`wdkVm?5!|Nq;t3HX`sXApVk}o)q<$@%mUKV|71t+ zcCzAx26_wgib#mb5UT>+v1{n3xDhEsg6s#E)KJ-?589--lZP1-fnYQ->oz!s;X z^;+6hRpq*u{4B!;?C&z)ot0e_@Od|mp-#k7h1JTxd*^gyo%$f_YMo%6Lr(0#7+i~d znCMLYN{(|?Q$J7zML?M5vyp?bAb(FZEK#8Z0e_tXx%dH*y<}?7pwq#iD7_!%2Bmz& z6!;yeaRSTI6pdaBmkrYLY!Q(LYxql#zuy>VSOB_!5Z&PFG_$V;dwLHJOVD;UR=Hb2 zhZKY54}wo%cR|+2RT;X>{!luCYMm1f9W60Kh968dVPe`_D&vZQL5 zdfc%K)xXk#LBe16f+)Ii2J1tE%Xz+v2%jI529aMNhEdP$0YeZwxG|4 zSjUm}b-zqU1L&`=6Or)uPZ(=j_B@sFD6mw9K9+_Vs<>!_KgJ1|xyn>^(qM!tf@Gku zlU8ZCxJY<`KY`;CrEGp~B-Qz5`}vHa4Txyu+5o*r)EH~(`v{Y_BUkuYz;j3+U8pO! zC1&CX%3~D_CcAZgzjM@~+}b6JUl5F+`QOVOe?J&7=&5`6z5rR#GEMppAX=GDBDq_- z+&L*~d|w2@nkxbcXN2!e`G+T;GW>8Pjh;N5c^(NuI~i(a39rOyWCU2EDCcD>IgJI_ zx>)MC`u+mllT9y>q$HY4^f|y80zIOk`L4vkdA-UKFh%a~G+5DvHwM6j+w*kt|1>Eb zHu2t^@VyqB>VRhfMA4NP@8M;h5ucxvC6dU0-D$9M130W+c=0R_t1-r|2H9d-v5dL| zpSw`Xoxe0M@w+6#(D_T8+^>+@5zev5P&K$Mg&B!wt(x|v+zd2&O+Z0_;xWhwe^njy z1Wp_$w926do5O)EH?+UcT#=%a0Ay%FbeBYXr=bys4DqF(5i(rE+!iG;;B>wwJmrl` zfj@56u{gq0c|u2U&=F4c& z=@H_H*5STi(}C>iUm$}w~~y;?V2uNsXErEk)W^R$z<^p(SpMp{MH#nR$x70 zuMq(L!-oec`7>?eWTFY6!uB%eRxcbM(64W(j>5ztAB+y-OABCVvILfL8!`E+;OYHb zMOkU7nL6P|@5kQBQhz>_K_B#zH~fMUqsTqXDC8;HHMMKsUF+W-rC;ggRffum(d!&z zH_TsCjTiwm%PqOBIyzMRdCtd2|Hn`*1BAkp`vUw|J0>Zh`o*#e`tThSSR#|f#dBt% zHBoOUaMQ)SCA4ZgsWA}KJQ3Yq*^Hc4UmEYEGbDWb;Y|LBIU4W21_H79qj_4b#;^_1 zIq-WB_d1s{eWWQl)Su4sO-9&08M!OyR|@`;*fAnhuc9(G%1>leoG9S-=PdrlVxWRL zST`zYIgR1P!0X|y5S+a_75d5$z9vnV?7fj>IQ(*4d1{?0kydEe{$=8xx@z4qGAUVH6YJlyx}(4_bt)fti;A-P``Jh&L&?SYXK z8jfKRpJ(I6l$Q$?Zu>mN-$`N$KPgefoM_qz>7Q0i>dg{<`t*A=p1=5|WRx}* zBso&+Io?iQ!9wzqLQdib0ns&4bu6hYuRzTx2~M-uRD)N+Ale9E%@lOyc{5!vF%gus z;E;NP%@IT?rT`DJanatli)yg&J}N}g*cn;*M9i9J*&M+HyVL#mH)|++tf(Qx3vUUK zdm1&ZGOdo!G^TZ2!V7^hN)n&x&+%gHgERO#>g2qB?a(jv$+!YtKjyu^3^kAFhJ<2o z_q}0xrAEodC&)(crH#{)Q7B{w9oBq)NBO~>pFfQakfoV4w4z*2xyREJc*2H1s?qoI zazT)p#*L=Tsl_FW>kH*O?cys&g=%7)BKF@N%_PNg@EKr61`n`=YJr_$Ps9N|9|fRl zUbpNgt7};-wJDEe`IhoFm|%kss0*fVA3-a?PGuTh8JNP3?ND{M)JW0c4RttKz=JVB zn(UUa_xeGA=ciJfNlhx{$y`L)?ajQmsm*6!T1sbDe@b@gt>=`Z)KUL2Oa=jN$O;dTznp)|!`C#^{Nr*~`Wwr3lK}2+dvw zv4p*@aXX{^zL^ol+aK*)MO@--i)}E_k@JFknrO8dn;mQ^>^rC7_yhluf0?m!Ajuaq z=q(E<p^`rO&Emd2F?Bz7PZ@p^<6=UQD>4Y1W> z(Nizqw_`=BO5YtS-ZbSMZ|qdk(e|n0Sh(8c(WIQGoMOmv+$KVuQMOE^J0re&aXizVCP*g5cc1HbCZDaI*@n`el&aH;p0lwi$vu8X9wRSL2Mq%`W?eR^vv`hBjr zu4m-FjcdTngX9U)lS_WYimI2Mi`$o$S0qf3`A;@F2w4JL&VG_Km?qEG*@k=MS;kKOJr`hGpnWDW}|H?xQU~!<1MKVcaFV%mnLR+ zcnIa@+akkHvA(06zL@cD(PHx}P2T`9#%}yOb>=)w(<8r;=FpfxbF-OJ?#Xbs3|@9! z>QJqf07Qy=^uL#Hgp`{>xR@2+)hk8jG9(ntnkRSBlB$jDcw($%B+p&og_TPkf8N%`2eI{)bEn-8HzK~8vF9BU|v`Yyf~2?KYq(H zi$D0Pc+Dp}X@yWnTpG?w`Z*+9f^cgqm0 zW2en7bq3Bgb-Kb&bIu6dx2Z!lI1rubrjaCH4SzyOb|vkvq3JcmVv?VhEwvX{FctGK zucCI?7`dvJdp7lY#`UgD${W0iyH)&Q<93POdn0y1;!`H?{bWSqZ{2-!yh582>8yQn z2!nI6>>*t95nldq(EXhiGsMcq(69Sy+%780f=Yt#zQa#OU)n?W{EZ;cd0*JpI7I5q>n^)Ly*)ubx#e+*#iu|<6Pp9 zDU)^*2=&a}=(ho0<#|q7bLky$z>CC>QISs3c@1OR@Fgwfqx_!<@%zu8RJ$)^s93SAq(`&dC25dSiQ;z4SVxoc75#%q7Ng60wKs%VBuorga+A|7% z)RP8zlp-b0@Rqltt7#)h8H4+J8a`|MXntNf-D$Dr#4QdyXo=xu40|49uic`g`RD!j z)^Ur1jl8K=C8L@R4OhB-LMM3(nkB^xdXl0kDO;7nx}S|R)EGFsxFggozVpQ!t|hYL zV@%5r&h$UC_jFOf}a ze#2W&144ek&DAUS93%AnwZ@YNUPxDAn|5me4VU|jb=oiIgMXD^HpsGaiX5gRD!NLO zPM@S)EXI7Pz(`pTFXi0P{fu4GAvfIIdTbV^f4r2w#-B?_r@p*zT=S=VArvTq8N_Kr ztC@r=Kqle-nW^Ygk+4_fVFGpMt4`vvi$zc#p_F=DMr2C>4>n6YqgShpDs56y>xzQdo7p}-6n ze^u0=y6nqx7V*lVNq0*+;LVd%+ssnfA6KWC+{ZHJ*-twMgS>{8*R(h+dX z7fScSK&RElZ)SCNmON7CKlu)edC4=~jcGHq9`O>5mC|QMY=bWcZuvvRzH|mapkKm* zAZ1^aowf$ zcakp0pXp;VqS#8!tz=cYcW$j>X8`Yu^)K13rm@#XB;PN}uS+!T)>hen6WtISX-|=# zZr#ILbw4Oo1!x8b#sTWK!)a?>5wd(rlXdGB$}P^Xn(&hbuAmgAnbwP}3<5!YD%7^{ zg1CkDZA&^yEW{2!n50h4#_67uYpc5Fm*B_AWXaYStZ}SC*D8Nhbct^pioph-svks; zVzbJ!uiuHTO34WWq!_^9VPEX~Vu)A|Io5&E&tK&H0#JIvIG?Ex$0$;=mUF$*i?%Ar zF=qis!^R@M$n>AyX0_*zbdLtU%IRjQD~1I}saN!uGqcj%ca4Z9uE`N(rEG`s_hs>C zbZIN6nCmJ~G(#lCoCn?VU8{+?2j;X~z}u$)phO{Nv>yjp#wgdK`i8rWpw>;5FFFlC{rocrvW3M)WX14&lZ z+cAMulE><4 zQ`T2I>7-;ub7;O;VW_Uf&?KFwbT))JWZr8^@oDR!d5#m^)~WG%lhA}4 z`?kcqe>dR=5}HD9qEXv@y@$ikJfpo*5UXhuQ60ze|TK^f@`z5kWzfO|k zz4vUv_cg9Y*K`N;Lf(1|J)kF_^Ikq(-mYG(NH?4HU*P+2*<|(+e%8FR^*Ij)m){@S z?)#PRqfYPfGjSM8?GlkTdpaiL)|TYBnCmx6N_hA%Z=2dGz_im4biJl=O0s-t|%Mp5&|-2>;x%&iD-p=xS%Z>q#(- zOkyBP^18-(*~3wWxi0OpdK*q`xi&D_Z_{!lvy-(G?%mfpPkf2Jb%_A|_T)`sK65cb zT;d)l{&qRKvaaE}nv!#s){DJ3xte(2zBKO-J{+QO_}x~JAp3eJbiC(esVxtRMF?Uy zQ@AJRI)`{vwV1j&t=b9R?^P?Mo<)Q_&N9CuV;nG0wA`D1B+UkLGVQO7vA{v z)Oq>W)pAZwjt;<&Z(#fQe9pA9Zg%P8gO8to*P5*#T)Z>e{WLct4cf(?Phf19e|(GQ zRQGBKyf-vIKj(P~dY3-A_o%&o*D}Sc)ob_n_)O-6w@h9{ZjbnpX8jwX-+sR}?1#tW zNhU5~+j#SGXS2-7xu+{s?|>$+L(;9G=QAYd`PGc&*WWJd+bceL)ElSP!+ z3#hmvPMUwv@BY?~@lr5bKU(45kEZG|A$`^m9zM?f$S^1qDBJ+D0Wc9h} z624LE&S2{%^V0W6lYBK5>X1fHW@)F)`N804o#D-wNcQNQpC{OFTde!l^kZuq+60c} zlz8UJi<9Q_-o)Os4#i(hzpG;GnI%>a@FKih>Pwi2o)3eXtmy-X_U$qsZr+{G$NBi= zDa35Cx7R^5q)?kP7E&QqA1~7#>ZlHWNxDq@;r9c?{CS70kkmk-HrvK4_FA7f5m6oa zB!%w=W5K(TxTJ=#ym8_EdPvAr(XZ(kaAHd@E~9Aqlb?;rQ`@=hMb!vXr|VC$Vy@S( zxyKBi$Q@uc6a_rC+5IEia=FjEEfR?THO=qEdAQfU-|9ZO%*n^Sy-Mo`w0kp57O;61 z*PQ^<4sgIPW-Ug@J6p)mvSGQnq~4E5ES$jM0|G$xU7(7$ zN&grRqSveO)W1dIBmVb|E^thzL)e{Jl8(3OU1tn;=zfVymXFL#1*0qK`|r z)JPrbn8KP7I@}7yU9X?+EYg&{!E;05+L5sHPmZF;52?3@*WNB|Rsv}$cXHKbTz@Rts577R7vxUwK#&OG zZu(kL@j_&qy6nvd{l7rg3GZ_^g&{d%hUzp)Cei!awwZrXe%Zq7qZ6KzB47Uu4leE4 zt{Z2!-9T2iH1mrui$weG4ERv_Yr4dzcg<6m3EaO#qo4)7QlrKnhEXTl!Gy8~MT(G3 z>hwhc>7=wp)`{OOnJ^7!w*GKW$cd;He8PwZTuyn7f0112F{leMACA(J1qS zTUmia@5LkVpnFe;;7(5#_JUM42JYqlM#5)F$GVrh9bzvB@iPZ-Rd7s2CD2(Y1S#}I z+4mvnqlhSqmhNyVheeIMgyU0uf5F{pTvY4s9;*)vGhVHvfmz8Gz*%j)HxvQ87s4rE zOD(1M%}Fx|vz|;OQnKp?vPn9gv$U4z(`dbN(hs&Xb2dJE(}i|MipzL7S9o=p;6Ha*=r3E;3sR3*-T}~6h&kBl98sD-k?3RV%x00Dm) z8g68wI7U(K19dR&r%MrcFTMa05ffnAHG32{`EnlSinu+X@a;e3}#HTMIz8 zy}Q9k_-~E1EdA17_%CBwk%wtw z>21(#T@=t45AvHFYcBA%DS@i--g~t^IW7{l)@6mSS;!iqAPFu+Ea?{ErA?YIMJHN{ zg0G|_xX>V8zVX}Jw2Q^6%V*@+j+GI{rK<*S?*8=+p-yA7os1R61D4s3ILy}1Ef^1V z-Owb1mVUivsH7TET)vujmO2#?e}&=o#-sEbZa}*2pN#O&raB(+pJauD zeUJ2DB1Eg~Y5CP!N_dnztjb19XI^{#Is*m&PiOY|ZbgvXOlc{r6SCza#G`3Db#j9l zFDdjaY$#~Ji;DYEr_)1M>^1BiJ%+}Z3+f0K)d{^ldJ-C*&Fjj@<=wD*n#=xo6iP9_ z%gNy`-;l3>Lq5u z9G)N;!ew*A1Q_@h`SsMQyhNga&5InD<5^Mpg}64F4}b*yJBsHyr16pQkaBo)ymb3G zsyilLg7%biR%F`1n!8SEF6PS@Y6RtH1jyaN;%Kc%&vI~-^Nq;h zJo(M=a4vTX`^LV3lUtI_eu*663s^cS!OzCHksjFs(D;x6HO|b9zoCdlk1CChQav{2 zxJ)+CmhNY;CofeI*lzZ=dPPI4)JS$=0{FMm?(=>6m#-2_0fbafv4O=gN($N^s;;*?@kwPeakd?(T4e#4iZ1=b%zNOO8m6t z&)c^ZeiL}2+Vfx5(3pFLY}F44tGM#P-*;X%ErknlaBKg26HnoOsrMP%@?m(&rU^{D zLpoyPE)$x*gWM;z{8JxU;@IjupHVrBB)_EDrB2%_&=!R@u3&hl#V2+^+o&J3xLF*; zZ(pLxO*FQ#KOA@`yOX@d5G{x-oza#tKcfpYN6OA(f07ewVUiuSWKLO*|AeuyeK|jD z|CVune}?Dl35m$VFa)?-?&n~xAMg@ArUo?Ja4+T^skEP7~yTyPs z1WOmv*Brcu?$&>{avU!uBqfcGv^v4xYz&6?D*4{iTaU(&??#W_EU`4>#6ZTt4t0E;sNgQIlwx}z z<5}|T4S^whQ$3ofq&(r-iJ10h&)a+xAM8FQWNbdcD$8!XX2?Zerf$C~Ha{O8kwg(5 z?v%kOpS$b`pk)H;hC;reEj58GtD?hV%_G}m)&bc zK)R2;FZjw8agKHzp-n^F7N#TJ!FS{pxvU5=sFK}2Cq@r!AI2OD3mB$SW5ddTAct4 zvXHTsB|+0OYiFF+mN15nh~ec4lg*#_Cq|{_Bg;tw;^yv(ZG86>a~9z@TSpRB#Zz=p zTfcz*Sx-H8?;Tf52AngV-fZ`YhH)eX1;rt30Xla|npuLK7(SQ1H$TC^WI|D+{zkf` zZz4GIw*vWiPZMGjYoVeYk+B`~o+NM)?#~Y4M{yr(mTp2vBeL#hjIuz$5R#-){l=1i zB7kz(E7X>&ij5L`PKDJO%?Nj>tLkNlMf8bR%%0=s&neu@ z*#VsK7btGxCRw6&#F!A$gM*Ye@tyZm^ z;H@2ZBf5?9Y~QFS0%d7 z@S%`m%%u`^t&ebyRrE)P!~6!AKFW2f4B~_Mjqe7|5oc!Y#)+3 z4N8p^Gs@MY>21iETy|#B(RXu{)Rt%^F_q*Xsg|e*^pnMLJ~}B@QYi4tv?~R=Rdnj( z59>mib{=&2<0Fd@k*1m`@f920FKiAs1V_^b4RlZ3wMHKwCije*1wq5ed=aQJ2?{(Ne9e3uNHNW}Toe#KTzJ@V+zEQxC4j8D-XrL3< z1?=TtpD|$!y_3_wOmrRg@CXSG4xYWTv_1FTZ=0+JPn+$>S$hY+ThRG>BaWT(Cahb-R7UM9WUwfFKw?*cdxf(UkB|j_XS1#UJcK!I6%@*(dANRsalMmxjkgFcy-Vl}b@K6rIoo@o zzIi*i6N&%?0jN7r1Sll&j}Z7*Xeo^R0=E7~Ec#b0BSQ!P2!Ne^ydS|FoqYgeC@qx8 zDByuJKtSK#)ftu2adv{(D|!0^ECrDY;*!DuF(F}VR1OH{{ow!1Q1WzkcKSbaj9?J2 z|1(419_9@71&IG+1IQcdixl_(P>lc+%E|p>y#z9iYUz#jH>Rp0l~D#6K63Cy+l~?o zp(IN7KF+9IfPlKQC*0W=;%JW&t3VySogh$GfPg6kstEOg{3G~}icqH9RP>)7@gWod zc|SrvP>4`K3*zJhutd2N46p|L+eFEKl|;Tz1XP6pC?9~46(XMn^L8|J_61l9=qsxN1T?&m&sO?- z2O;Zr_V@iy%lu)^E`)*rAwfdHe|-RAqM{?ZD_IY;|njbU*KR$2abe`=`d(yY{N8 zeb$__=B{xTxuU2zJre^f40%OmRW%F~5rD|v$O?v+7lu*M$=<}(*wl%LO31;`*us=Z zTtSgY-PFn1(%z1UnSqr7K(8V%q^KgPpvq13HH@gev8%1Aor{E%p@W5`u`{zMH4LMO zlc}N0SAeLYizyM6C^s{JiHnJu3Bbg{%EZb>3t*xI04S+p`1xT>?M(j8%>4hZfQV7n z)Xv<+f{5komNF5exTTHD*J>EWZNA15H8r+3F(vwnb9VWf!WPCO`@CDGhO9G@erZN& z2yCwZ(;N&0tc((6|n%e%Nu9GYE_S{Zly1_|%+h*+a3 z;oRpd;w#{3EALIA=HhzB?+p;_-btcA zYW}e&ArJofPX6gyzN>%u##sBgO!)ab?h{hrL;vdWlW2K_^7Ho7>upQm<0#GVBB(W7 zVrZFE{L<+7^JDST7WD&rRN&(*PGG&a!(Tx5fuSu7wjaMgl@)E?_pp>+!jU*tael9q zC%biX2lifnKe+*F&^P@9$9VlpK7s`zLxH5EJ0^R&Vd0;)_5iKN5?_4A5-s00&3>*YSF zaDGRde?|KSgI!nNjji;i3%cKu`#3K61YF0qb@?Jn{ z`7iklD)XJA%9x3>Lcj(m(>yk65)QlY8sBTj?hchG^xz^9apyQIJc%O0lB@*hT!Ei8 z;UdWz_?07N^RzwWG)$u4%-Fkhcxv7K7*Gj zd{~7q$bDdwht=szeBCBu9_%>Q60jKbg+wP_;hCtnbR4Xl@snYM;2c~%p zMM4OIwQn?Oe`Z}3IQhP$2wIE$CL9m7f`CK9cMAIr-)!0tGdxW}2iH_oXO54fH8>(+d5&=5FQ0jUw6CYF_ zo>!Dpj>2Y)@AeDU@_Z8T+b!sek8e;HfNj_q0m|PE-_Ian#jW(DBU6MNc*A9*b{i8V z7gz+7vrnT*O+0HCa5ggTdV9AGQnhc0ZbF?)i=p7YDK!vzxb&`M3sAFD-ELQ?4cH;~ z*1lj#fGk7*_&wN*dP43Nbs(u$nQ(0koX&E-oqnxQrw4NtEM|j#u7u+Zpf3`r;(fso z45grho-m}9L8LQLGkek_twg!afD*4)a!K(~8_4V6t|FGzK$0IhW4Q%4ZHTT<_2qRyq-3*0yv0782|1sR!W@d3C%D zmTp=ioizVB!m+!9;9!cTuvFIVX;7L$?)aYg2 z*;k;wq}Ur&2-AL@q2|yD0ib7uNdeI&bDp+vDo|#{C0pm=9T;CP(quYK43m^ZjQiZz zopvx!OEW(&2WJ#vqQr5wFMDI@L((L>|7;Y<&aPYuU%bO})HchS zyW&o&95x;%TiT%3pFB8UqtVT&9<>rLGO$(M#6X07T{$w*R`Syh)Lq5vc+KeyF$HqB zR(HDL7nL}zbbe3^MO-K^akD#=49T-EdOm?KI69Zs`AE7|4N}`&Vt&5CeT*J`=yg8I ze%(R^qWbj~%dA*G?vljXsT=ppHyy$h2fCYE^4Ubz5ub&r>dnNbSy0P{KC`Op1^K|^ z$dNwR-52e^>&RTA$6Y<`!AW|s(Ogx9`Bj-MYVFf$H|nxP#s^Zee3p+i`c}it;UpoV zKh9@reo&S8Q@{HX&b_*h20Ea&r&W6Udhx#E%!(kzB=hANlcMa+5PZ|Ma|*S1eZZ3A zNQ)X zjZ#K-i#eN5mT2^_B%;8bVLQyults7<*H-j1DWV@ehdoV}hc(Y>Hp49js+eUQFP1lX zdR^sC7XIWnI+gZdU3qm zA1%Ol1|NBe!u*FJ!mb`F$X;mYS^Lmp?}|`xf+x>qJB%YRcG3F(xG(cE3rDITynwGBAe#+ju8Ya%l)Lb ziIHY=FlV+IiKeM@f8c9*mG>E`iQ?Lct0{MA=yOQBb#g0IlIDGOd}caI*L(PBUrhiZ^1FtT7cX?A}~av;dy4I3+MNU^?*Rv|IS* zLnIO05I%$8e0HHg>R(xwAS)(Gr03>ELm*<{BBhcrOVpzAZUKn=Du!5M!Ja?^2EDXm z%DpVM$C{CV#JU@GIL>Tv2#cz4gHqsv^M-IuJX)a2aLFMOHeQkn8-^oOBMEmK!9!2 z>+}ZgjKo`LI0zEZFvJ5L497ByB>JU7xIr{-7ukv=dt@xE&bL%z#~HTNwR7R|#gzx$ z(Ccu>`;m91a@|AC=|8QzhFW1Gk;PP47ECSuxbYw>1{M=4L#_x8tjO?*LS2cXV33f@ zN<&?^7eJ2J|w2*7L8=rBZETBMK~gqY?qL2z{pK}}C9i|Ve&{_r@^B9o@o3&CQ^CL#lp%_k-t zm}!y)X~-&xf*^2j)UX2zytad73dzK(3aO;&e*tslj0W8lIKykHDqdm2alwU@4uQh- z&<}#3FPv(M<&z~fA$7)+J?t5b6aX*z7)lxPQin&s0lXhgG=z;ve~@=Iaz#XN33Yub#!yJfW=}8(~ zSXi1^Txr%#0YW@}K^4YjL=*;2`2wW@_#zUc!FRKm0)jp2bTRmqloaFW5~j4Vi4bH! zgdD@Kkl6*}Y2cwp{PhjTqcDgaoRoJ^f@r5QPy~^YqpQl3%gY8Za>6jB$M(zD>6kqF z1fR1Vgk2t#d9%q5%mG%XTMy`u%SVx_QpL)hc?vv-KUm#&h zP=obo5@ZMMg|rrdo}yF-+QHMT3)2Z?EA~$%yp5Ll4&V(?7sjo-WAeAzo(6t|uVcTW zwQ00E5eyp^hwcwgnbeP<`v%G)ct%>+qa^elR04zL-7ZxcI=3>Aqxk>~n3uc>5fCC7 zht|eRZ3qQPn^IV1`?AJhv%2t+#^u@x6xEolcF;~$bJH_$bCsmXxwM3T>AWVhWn949;g zEwwr*qNJQ23R)Qg=HA!V7h&+{%4f>O6jCrr5b_G$L-~VZ-7tokJsJ`gQwFCj0IUi0 zOo@UxUTThFfMyqZdykJNiAw6GQgh)1*vFy3xI#GzU_7H0eJ9`L{F)J-M_fOoAD?_} zFPZ=AnoCylTt5ux1Z-kaBvLnJ2VmX-Z)V`Ytf%_=-LAKg!BSx zl)eHX$>_HV3rwmOk+WW3kI-lz@kGsFc9nRCgL|!^#4%$xvE7j=N;7I65~6@nEQ|ik zJ5ePxG>;N-o`JeZ`h;a~0{SUIax&L^bd;)x0F#wqUL*z-mS1^KS(@ltWz>ImHJKua z0juFFP&1(+J!2L%ZBIDxH|JX?ut^wpbefVYPV<;7WGPX)x^3oK1@wNJGHb_1!5l){ zVZ&qlr2q`Qc?ZG4F%zqpVnWQUp*cXm0>8oDAV9O%w{K?WS)@UB3e;n8Bw`5e6;i_} zOKr&Yq}%cVWqK5j2S&;a5I#EOZIYR8_g!o^OfQs{cJP}>VtPCHS@_dCjgOStn7?AY z-TMxciaU%AQwX`4A+TzF{H>b+2?~d|tf74CD}f{kJ+xWUmZ7uEqXxNPr z-0QGK)348fJH9^b^{Xh7>p}BGGdTU1C?#`j-_(VoPJLuBFEdeD#D?&ZF3OM#_85H3lOaH)>enH>n?Z!sbUoE_vleL7^ z=p{^<6YQbWE}|&h&>%drLAVipaGR>*6x?}N=xyhtK~zypa!MV6^S6U4Sh6F62BWAF zwnhhVnMoHTdc%2xKz`Lgij;B|f+MdYO98ecNr#?>UEHv*AqSf{L6Y?8!MA>3K)5>w zvyj}7E*VN=tr36p`Hw_;Bn$^uLupl~LTQn89H4Q|_gyBcXE(tTKyg9>W<^+{$?1MnznV?am{CwkB4xGv zhJ=RjEbn`s`6I@yr~7$PJ(n$$|J->#{-jx?)UNm4!<;s3aSJ^ z#KDe*;^(+onXPArLZZ%Y#^*D(S6Bw`@r$k^@LyvU_rAoZnO#z zdSKE(GZfB1B2eOu+iI#NBMl`$63XoKqKHb!%!}{t7MlF~WpgHf{wWvB)3jrd-ECV` zB|Efn4lFshGDuuFB}%*tVU{t-H_(Lua;an@1rI5>qc2mWK$1;@NSSF{kpsxBPj(t; z=uC#AYxjW#FA67FL9D4l+otF#oI9}*%8UaJ2AhW3S-SGpj2ny= z7&%m5kKdUpqr8s&l|>0C25!9!ApsfM^!@s7Xegak`nm}5Cj zXl9c@2EfCGTsy}kC?tfj$Sx7T+$Vx({6L?oUcm;N@Pu|0v;po6=E9Wb9ueo6LB~GQHcHBpznxF0Ygw=lHKl+gr6(1quvtf&MSt&yh)r2?j1B73KC2IKx}AG-8|J+4$h! zEHQ|w!|h=aXzxEW{HUTbu;9Aj?P)L-gUed)s9bB9I2p)kS2?k_8X1J7NV3p=%BR55 zN!kew_sZ2qWiKK|8hp<$nu8@Z9|yC^{hi*YaNdOEVZo$acrsamjkcO4jgk_GHGI4jnZR;0RbXeJ zqQ!30I;bav#heKh*h61#ZlDs zSef_xtSnAs)MQP43IGh~!WA@ia8nK%zi_CJr%iR12#&Fw-jvUZi6lPH8eC5ZoT_+*(EiiLFeWrMLPXjDYaVDf^Um(^%b5HmJ|qR{7ceYCPoK0%P(Fg zk6dNyf50Ew=@7ByfKvY~Tk*%3`u8_iZ-}x1*99hyFX>oG-Xn;kRR>;tgT6 zH##2IyV2A=FteA`z$3&5RJszB|0W^PS#K-z0v%tML$=hV^|VU*DTl>+Cdi#X+o0rp z2@%DYPfyXzDc9`Xcj!zTM*VDEDru5NeyOcP$Ip>2cu3zaBx79BlPu}>r!DHe-mOuT z!qu?Z$Z9Y<%i!2|d+NJQ{&#btB&u0<+lthzG5qa1pyG0yi}?Vk)ToUe{m$=HwAJ_0 zCeA8I>-gzZ=_&U3{LYNXrYU?He8m7)B64*vgJ!SE@Kc>ay2&|v{jA?PRF#?m#pIo; zX=q8feK3fU`O$o8U7~C2zkl?}O-VZVJhzcf>4aLpV>dh`>}rQeAj~=Io~ba+b0q3k zGV{74+|eyph@wO$9BQXrjz4+jTIaCNKpf>BYaij@5k<=`MCsYv z!dmjJHVbk|esq#|E};WK=7_gg>v6dZl5RBDaC-etxYE|3IoqM%Yp%KMGyg+fyT~B= zuzsJtY^88KD?VqcCo~0W6nc zOIU9@gGg|#g9VFK(tTpaZvuahAx zqscTN#$-j9GJ{o?6t|^L(F}f1GK_vd#d47I#t`->WoSn-+_Ho&VlWp;=eU^+K|&U1y4v zsl=G%5My34nmz!HCEU?uB=sqZdI+FwEVD8~R!G=hPrhc1G5fH;f;sK}`5)C%v zl>l_??=3dtBLK`3i4Gg7UBH2bM2~E#FBvY^jj7B)_{kV6ikVDq#PirM7Bd;QiRMO6 z?FkzxE3Vb;1!prEhAFAxV#=SXa5yT7zTPfUT}+ggqY8A-+!GU6nbS8+`q-nOUu=@n zL=dB+7MrkI-bxI2v1L(Ic}?uymv~QS$hqG~OlKOGsaY6b)yKz^iA)K409BPSOZ5VP zM#~6mxUdR#?FW?W2=w(9#Zgxp&(dj`Pix>r*-ELSg4)r|k&nu0VMl$Jib2&d!~)Mz z#AHQKX(-yEmKg-2AO9Y>1wY@s|3*zaxKCdU!ayY;Tg(7ZR1FKzn?z~w?lk;XiT#az zg*B)LLx@Ob5V@)uHI#hAuL>PAe9nQ#x*#;wx~;OgXU`KLrF#seCgL-I4jK4{J(KZdVjsQfci#Z>AX2Of{+=A*8gVO)!ZT zv{pqf2%#Q?Qk^2w(I-^A6iC`xzyqo?nS9=R++|B`r>qLOp(9;*x8wV3s5ntti{Q?Q zx-SuPMMx&CgWlBemzLh2;xagtu7&WBLb#i*OgF z!(fOG3wb31;9+GeN_!SkBrTddc^Ec6e=V5TDYQv~Qa1D3+E;_5(Vfx?+$+#u$X)dG=Lc1Ok39aU1& zwc^L12Ij#1VpGxZH>jF4dDMw@s0p?2Fyy{qH!=z`u(--5*w%l73+R++H<^^!114_9 z3h4hBlO&-ImAJ9IgKy-P_({4qp8%hlalY$TgveKlaBNz#o%-@s`)(YTmdd$9o}Mhp zg}{(^peqH*xC5*dPe&v|Og9+H)BGZ(CIM}z)Qkt&i7gk2xYyCv6s~Qe56)KK zL}HzMcnz1TD)bl`cEtG|+I2koQFwcG`WHrc#RV9pO^yU-Br|kkn=y3S1f)}6HP{=G zOizA`%CJ3q$7Yexe{h*v@ZEr776UuGNT80_Y{{Ow9&J!CMbJt8N$=eBgJVdRIB`>$ zWmIjlC5sDB=izipX}zJ}9N}XjH=oNuw*~p9<6*<21%kqTC^`D#sh&Iy){@Q-Rj6t= zmGVBF%Rc4nj?I?h0q^c*8B@qR2&NR(U!4=G48rzeD%5b@esZS#cO@JtfLWdc)m$?Z2b;T5;g;xnRBV~JTwP)FG71!y&(~W8x_lnk`isZ^oiAv^X zuiI+rt5f_=8pf*D=L(mGP28%6UtS{h(%;VX#%PYJ-5DxX+cz(GDOc_>EK^c7epje5 z>)Q{jvjKJc=%gUrawve3ZonDXPi%ga+5RP9Mo1!<2JZ3S+7-0%LX%R3Z%jGSziW45j&~ znCEaA*UVWdp#6E8j;NQfZXR^p(Za1Lsxi1oO;!Pi!ed6J+FgWT#h_RoX%UX`-HAv=o_L;C(VD}Zl*E^d%Zn@W^1UmU zu27TA8!qCGzJr#pV3NvvEqcjVFjT65l_mrfXO`a8t5zII6PmHPTb-cRsrseyv&%Gx zoD8<8a%AuqT64{uEysP{$Bi;H0Fy9d#fFsVej^=LcsJ*9Nx%>P_N|e)b};kfjrx)W zIH^Cs)bB%eEB!O^N3q{)d!Aogbq{8bz&oFx%}eV`=*#t%-|?fnuJ7aN%7nnlrQfsD zex~Oe$Jk4PwN7o}vcNX8bWJibyMm4pBp_W-c8|>*H;-}m7M#y6d$W&vS%5bR6(>-U z&&IpQR^T(gH)ayI4UEG<_LIcy?zjIY&@pY~x@32Ns-a@Y5!Qm_OYhDz`{!HE13QJi zL1MeQ*#efU{h23dZY`A)={U6$W_Qry_I33{4~E^0{5jI2cV(&+Zsn!nJ-VD-)n=cS!EMM+r&QaFgUJ1FMIW&Q z+;Wb1nklQ-cYDw~VL#k74u^7#o*7=BVaGwG3f%my)_gz3eeqNHA}jXhf)}5%o}%%X zMIFuepWlzpJ?u-nNb8D*FiZ%vwXF_IsCvw%Z(W!l=5cC8dz;D#>J8SkF}pgxPRW)_ znKo%(8gqD_pd`kcy>xiR*%`bp!T?NCjC%@PT;lrg<2@#W92$GjZE0NSn>&=hhiT%P z4ByMP)HfG$V_Iz+tftyR?%-~0gWtVI?CWm5bP-1~`_yTBP-h_sPH>+psjvB(-^!;j zv`2I8d%$M_TWfa7-Qb7Ui+-FgGiLb)2jVs@4L8?Q%d3ySF)!EreQ&5HhaT3RPXz=@ z&ctHL5q#2ZCXztCKRkRoW*8ZO%(>F<-B&kLM6dBosNc)m@+RY6$sSzqOB1V6MC`{K zHe9=ezA-q4#UY2tVRnc7zG>Oo?uw>tJTm9Xdm?PlZ5NT=?Dz0xeUNwyv)4Gs=|2~s zOb$zK1*Xisv3T|7cEb#lta~$w@|o^xwAS2HINvsVJvO|>qWS*G1L4nU{Te6I$z<&5P`j7#G-1jokt*Yv!?|gstA3l^^HF`6 z)oGOr!w3HDTZ$(FzoRppK8agJvUx?e0wd!>iY3*Yu;=D#EBQFb`NZ1Z;#x@x&j1_; zPcdX?FN-hjwYy_67QEwuoL8N5ai@OJnjzjkTWTAig0EPhK=&c}`6qpDpe+%%Q-R=v+6 z7h@%4RPCzFYHA;K7UR;}Tl?*ev!=i*i?x`!Q79kc;*Q$MuM3)Tx>z=5wlf799FD+cMEmyhEt__d@w+@^ zD=hcb93I_!Wj-9g+~*YmDSW5qp?kTvQ0TpF;_|L^ATmErg^g?(6nYr0=boN_wd!4E zw0^XR+v57^sMaZ)sJ?uj_9C`AwJMQYcREa8R{4#6AKs5cZ>B#d&rU=4p}w>4O~?Gv zgt0!`cn_Dc=Y=~LVZ(MsVRd&Itc^GN`@uH@+`KgA)>QZn1&w#W6J_OYQRqeO`+na_ z(Knw@UryloPQ=GBd^cBh5_i)of_RF0eYJT|?X`rPut}>m6b^MCa?Oa#@9_a+$HIVh z4!lyxh!Zkur37+)t3Cg9^Is81Rc#KNCfB*mp4{Eu)06YUDjGBQV;a3KKfW_)KkCdM z``TmsnUgcvDD1>?U%skS+qH%3)~q|!M(@W?_Ed`au3Ypzs&AjM#5L@P+M^(D=b0zs z%&o=DrQNbDORodoMHvzxcg3+>?X)J=@sed(dBIEv@9tT5Q&2c$?FXB#7Hayc&z%}v zw^w1j8Fki1?p)LS$_L@+eiOy4w`X~$#O%i&DMA2TgWYj|)EeC>hu{`IZgf|M)OJq2 zKY^`Q$7w#Vlhg^l1a|hS?}nb(rr!X%GM!B2cKbnfJ+`eTc+D+-+=(TBJ97xS>!D|} zaoK^ER+gjAg@hBsb;CJ@SMmC9w(8K!^J!ukUv_LyRPv-Do-RM^qGj%NqHg%PKGHT# z(t6%tYMz!ZtUb@^6^N54qVA;~h!daq8v`j!57r)28tt{f#2rTm+@jjRJLNFkqQ?!s znGsp&0Ly^D=WnfjgH@{%jY2OKoxKZRaklYaZYICsHNZUjrfTNglkA7Wzd-H3f%KLM z;w!o~2h=^@96kZ1y9E(necE#}_;&G|5Y$`#-z7;qnc6V*7m?GIp*^$amYo&<{?gs{ zG9uh09)3*TDLzc8kVuV9yjhz0z z`YVC}wlmhHY-*3*45rR7&i*?KZgDO5n>D#zy03rQv`;6`kI#U^qnx=)RkpOtfq6*oJNJW=TYy?lCl9h~=d)*N0l&SJ>(&JWuTTE7r$#RSjP#KY zcjt|ZU+sJiuMa^{1*KEz-Q{D-Me@gyP(`cYxyi}9Eg6r-i>G=;i{Sa!kPivx6Z1!g z7258PT*!~V^B$Ry{Q^=dmNtBt7v3L^zS<-DlP(o=LO55y)_H!+Q%23Xc2{@8Hs{`V zPr|la&-hb0q*p-F*GeC>DDvViUB5qnJq615@@i5RH>lctaWN=s=Pq#BD9b-1bwrQ! zN|*HdTk`8!zy6K0!y6yB)vwoj+%e4yE3fxf5UwkRpyt0lpb219fWa+c9K6$xz%6Mt zJVn_$Nv81-&=8%t=%gw!>|ij|G&BbRGvAtjW>k@Xg?DK zYo%{~C-)F=>(M$6-t`Q+1J_&jZ(-D1x_HOb?8JuSZ}(nYF}k)1dEpi@QFu3SrtwzJ zqzD1&-xEBrCoa=IrTvBW6EW+>j3CozP<+`O}}sMs!P}Eq`!4kGyt?A#r~&I{yby_s4os0!tI4K>2PN zZ=UZJODWyNm#*%9)kE;}uK;)o{9;jKt7*iv3LYXSijMBi=N#6B|D*uz?IV2lP?;Bz zDf;=!Kuhsj{-ifyu6OPqU6!U|+8G9{uaO3`k;@^B&s&OW!{jw+){(m5XOE9FrKcSf zZ1d#lir0+ZM~*A8{v)USX$7Bh1J^5=Io2BKk&RHL8_KDxyw`tAVVfo-UeiV{=J%#P z3};K}GJHXhtxah&^ujIaaCAQ^xZn`DWL-ECDQ$OjPs{mx)iJ;2@N_Glqv!F`XIHA{ z`GVU%SMKU=es|d_a2fm;$s9uGx+fd}ukr!-+1HD2U+gIS$BxA>b}Ytp@@RSWK6@TX z3tV1&A&y7Q%MW*aI{5=UtTt=X-SrL>|D}`n#Z!m7_2PoX{o-p-Qg?pDIZwnP{;B=1 ztofvl>pMJlw0jf6-UlGO`!Fnw8dj{i{UwObKZ5jcRQ7Cq-G1LZ`f88xd)7)C5kp`4 zzLkFQMc=>NDq`LI!aKj#g|Oq+GyT*S>6J6-RY&TvC0*FwFA$ zppI$ChBPji{=5M(B`^IKUhtmik2&j|TRR5L_8hbD_j{EHx>dh$ zEBV`}6lkFWj8<-@ewOk*C2WD?=!o@3#&Ot0Q`NK0i)f3chml8;O2( zKmpx6k$#=$B2H0Q7^&{h@tNWLe^SY6vf{7#gK3EmPyJI#de^NXW>$mgznmhu9*p&` z8fdx8a}ltsD7(krxki6G{n}Yjy_2$Yu3`VkiFh^FZvGd{k9?P3 zvit>}kGiDd$JY2SNPlVVx<=2L{Nwjq_l=WVqDA^n9$44jKc1BTlz#GpfyXER(sMcI zuhR2zcV4*o<;~adyo1M2<0tSG`1Mx0P~Hh3DtEsdmP%jR6R&2>%`_@Ee;TIc@Yh9{ ze8nNEEOvCpg|}^ebj5`~(YCl;tZ#$~`{ciS=E2;5QNn(4HB5M8>!N8U_=Q(e?d*cz z?#TD`_N)C`O%~CE5XDyCaWM>s=%usrhHg(>@QYyB2S4iR9zZRo^OY#c-r!C;2si)n z`MB%dFwfY@4|be?bf1y)`-WzZ0{yF?`v-r^`7L0$H&&6J-^$}KmC3tUJlZ>IDfFZg z(EXpW=umxraDxQD4G)^iCFsHYZKM9;_5SfUSA^Te*JW&Eki{+T2uCP3P_KGFF0bZj z|AG*bx~#`J|DEeLX0QcsNqkRljjL=~=zpFAUI{IFMlH8N>ny>^^(k+o=Fv;*pLu8% zvI=UJfcQaEquGPWBfLc|GRQOF$LG@V-%2o0~@@mbPI#IdLFDOc$1a;S@*n&Q}JIcUGN_|^|7H_aQZ8H ze%D+9G2e^5)OUaU=lOtWt9Qn@C{XccLW78}xG>`@;O99sPm2FpKGr7}PArftdMdTp z3#!fS!j1a*GwS#M+>Ir?5x9+H0U$&<4kvs3wJ(Q5@E>x&%pk88ONNDYoo$wULkosE zyQKb1%0K4u)4Ha}ZgJ}C?P7-lV5o=j1{rpGr=|Z%Ibq56t3)(|_)saLzSZHi1J?@t zy!%=nj*mLzf|`BmU-Crzt-aa$oyBQ73$D*%I212 zgL847`%^`?_ZN(R{pdZD|1t}98yn+uuYYE~%#34vh1@@tC;gww|Nf`)eE(B`)b z_X`feOA+@E5XmDwq*vagS01Sc&o2wIa|Uti!@2<3argLFjmxbzHq6D=?fo_-#JmZL zI$YiJ;9b9rP9FR{Cdr#;T3au@k!@Pf)D)Nd|Rc5*$B zKi#;w3xf7CzeHMMpyHTPxLY`m_U>}nx3H>QT}mQc?GOdvKr_)-9s}lp4T~bCOai^% zJKsTy=ri6mLnf_cQ&S;8yK-fH%L+7VOuBq?LHKB1pb7+&PEU+`H@kouIe5tN7R`&s z-;x6OPCEh}K=B7F>Y}3YYNjMCf(llWZ2#nKK5X!Yl;04Uf0v0@oewj+2AW+>H_{?k z%wm$`c=uJn)`yH3=jpwFD|XOK%51p5qFX@qcHHy5Wf4-3^6{m`ns>FDSGvkUtN7E= z*diDF6Y}HL`y16;HlM7Yuq>3sY{|f|YS}TQdEO758O8cqu5hh z=l~TNAn<;x#4HI}v-x2093G&CThHDxX*ox4+T~l{q$ROkxn~;7$1HKCabLEK`f?HP zc4NsSRA;m!6=aQ`y~IQ$pOcRKb1(|il7$i>N$>GPZ<-`4OXqvBU6{$NJ>R4$f`#BQ zQDqj$%d8>rd9wuLx`Xoj$g`vO(*ReLnb-Do9wQ>DmSif;0lE=q@98PcT^;J#f zmEn>Pw-lQ3h8A~5$b1faFu1Tm(7ZE@dDo9fZH9Rgo#m}2 z_T>W(dJ7+(gOu}Mw|VP}i{C0W_zb`PvkE7U%GG*g@L`Oc5_C&8aX@OYTVcl4LTkTW0htDfD?-5S89yGM|F_`C zDvNA#*j)pyETy)@Dn(wHtJKir2vH7LGosLEGn_E#BEvBT0*?t3%;3mB5%qj=5X4)c zlxP>Q5QcU!97pcCNWqPPK7oj?I01JS2vkva!-T4!ZYH}l&)^ZxvX{wa_2wZ#lv}lV zV}q_9`wzG{?v0{yaFRqD@?B^aQ}4i7kHle%uryngynJDwgaQ><@$9ZiK%COqr)1l4 z3*0__W-sdDFnQERNz>bv=-!|u;dotU0EG^=HqR-!(P$rLMAr>Mc#?PVq~Pb+X>OD* zKJz$G5*2~~DgJ1CR!L282xOl4{5~AX9Ni%149NO4F1yVoHYeA_NT-^`!$*#-^sO1Ii$>edWpuEddV<(HDu)exnrAy6vTIfWxQrR!JOgeZuX ziBjqcJbErnK2-tZxW#lGCQ6uJ5{8NqDJFF3Cl~%cQ$e%>HQ+~O2--;F{$nhXBFQAnx{}AjKJl=^)Xq3?Uir~M(3O?4Fy;Pq7S?xrg;dwS8 zQ#`#-2(!Yo6rm3;P4X*eykapRTF4c94D)5GrHje7udifW@o9;SJ;(cVB-Q00yJ7~f zDU&c`Rh$z1GCociQ_Or(+5e~DB94#DOS+v&mLrKzik;}g>g|!5IE?29*kklw z+L=mlo8!DFdXkE(Ra z!?xW_%tRAqW@O+Lc?ziy=uCz7>dc?3xjV)fxCSLt?gX9DtNDNK@hQztt821$-I;rKC!V-|65+87KPf2aN8r z4B7H34A)R=Hk-4CxvD{x_}Jh}vwh5kWa|!5<-KEE9`m&GiOWP)64QD?N-Rv~ELPI% zD{M^;@EUxjqq!i#G={`IDMm8NnimgGafHf>uN8J_aF=tD_ZN8yk&8yP;)ymbCn8mb zhac3ia|*pIRR- zNJ8ra8q?uK9P{UzGhcTI^dm(duD5*K8YNZxRz-P=!8o%gq?H12NMv(=$g#@`1tez# z=Ry7)k)8Fy>Gx!!UX139BRQl%70?z7?kl)@B8UXTUjm^ckzUeR4=L0=QOCQ5L{s}n zESCeTJrtQ{|BfssIJ0AnW=On{n`PXyu!d(8Z)l>pt;lDa9}eSUo=G-(vy?+D z77uF#{4p&2SKrES`yH*T^!f!eTc^Vm# zcC_skawU*k+rXR3P&0xHD{?eg6|hZE`1bxbzciAP5lPpAU=`CwB2X#&09G8-;?Unx z3q(Xjh8gsFxV|aD{KW9oKT$1wN{Ngliy zODZ93Hb79($fx}vXxWQuZP5a} z0^i+o3(?whGu_%_!pLTB)o|bx@f!OrlL|bA`EFXsEb-_U}IPRKCAX@5U ze&KcZSWwewhW90`Bf&Vt;sIYHi^GB$#s74>maU+n1ontDfUyiQ3C_M*M+rsb16K#^+aPkEyeHLzF!s#Rs|J%>fAGv=7jHtBO^vO%#L zZ`d#-=;XI6!@4e#NM<2yfoCYzYRzZceY#%sF+-@jL|K2!K-5!|62E#)P%$tXb&pqa zc0bNG^D1vTxlt1vC|i#qj1h@pL9j~5i+K$EGMuIIAWCUOtutx|{HSn#d~r%+VFThT z7XYh}?<4>&gn$<*b`inRg90r*USQkqV_+VIqQFZH9q^>}|;{`JKbHaD+&LJ~8Locgvi`A>QLSaL(moyDV-49OHdcx?G!^Uv8%QGB3pT)!dIXPLI;p-$lQD1 z1b?Vsb83BXH9;8thS4O8g&s(eM9%xgRwII(C(y{4w3+5bj6xMD zXPvIbJTC2(xt11KrcHnqo2#;2O@|!GDdaC)5`GK8{zq)zR2>v<8FWg>EUWW`$|(@M zCU_rL)JY=*6^M!L3P_48Kr8`$rGI+c_ZnIvatgHyDTm08B*0^TWghhfDP;`$T5Ngxt+P6XHX6fFG*2)jHrL2EPy+;8Nrl0#6#bZ5NG6X^QXW@*Pqa z1JKRSMSR|WxB_P62zng2yDMSz3D@$%`1gmQeu_#E6VU1@Ik23%nBQUt&t+x^B-i`n zS^x?@+7ZY6)nLJ_6E$Hvav#)kV#8xSw!iZv~2(|nrz`q;|nI?Wp zshsD+eEo!((UKg7a-B%g-OupRL%8uLp(ZV5X(1KN4lJyBij4zPA;m|9U zrC(vX)1rd46H;w~B{QFhiO-Wg{g)7x+39>%KZ*R}60YSCIoExlUR)y5o&I8O6gKf~ z=2I_j!)N3rK4+;P9cLd|$eZhC=~~rD8!_!!+%gkZAVlD%;8)GAC|F2! zGiDJo(UWq1b7sY2@UX;xnj@WCVdId@L~+Q1eB4Y<t=sg(qyyoC32+ro0$6oD^!dl3iD5Y&@X3_%0@!aTDO z-^n&PSE(j7Gy$?BcE<-M-UzaIWd`_4fn~yBGJyCaOr{UiYKjy!3Uj{6^r%d1o{p_3 zE~zK+hYIswTp|w?CR>a$5av28U@(+J{5oR&(&FBGs9BL(P_o1kndDDXVv+_OL~44G`E12fQLGyJn1&h-o^Pca{1K-?n!}+(Q>XTi zc^!2~oJHwJ(@)B(bz#OSQec&%lWHTje?JT{W!@T#|1s)$+(~C-avcCuSf{HbGVX^5 zhbPVLL`cBcK(}J>_o@+k$vODYRR%7`ACf~%_*gMWd{No3vBY=?O+;x?TLb(bOta8^ z1Z)K91Iv2Bx^HlX>?2t6a2i?dSKU9@om@;n+jHNA*wc#{_%lcKJt7exM`AG7bTZ^TWVpO{w+l@Dsa{kZmH zZv4PXI3Gshy<)Ke4(BBMQ0<;;%P|GFcr`#Yg~|LG>*yT16hFu#q$^bPRFKmr|A#mk ztY?I%k9YNt8JzQ^w#2L)J^N+%s?e(eiM@rdB!BPcTarNPQVUT7c9TZRGEQRb$VO8` z3XSR{?YH0|x1!)Q$zZG=u@4h)vz(_8k)oXg)1Yqh`bet82C&RSjjU!+a<2yA9Bu-Q z;Am;5zeMj>5usgdUNF$BCW6(>BF^1JhNg4%yE$#o7eLF)A%sPX#v#N9JhxYtKWm zCySb3oN=vl&|F=Gw}bkKon%jL|A}hWBr|Gdb##sEv4B40Iv+HsnvR2+_zc58nw0K~ zedxj6W_>tOTK_!j(kN*j_ZKYqJvf3bN}m*t0Ui*3k&j~Ao%ie_y{0kTy{hrQ4-l%l zbB%tW$7+80?!pIk79W{h8k|$Nf;*@*=st^sN1tyZs7Z~0a8tzQ%o!1j)R>l>br?x8 zDKwin-wR@h+wxWJg4&i#r@TimyFIT@duS~YRDs%VV&8J9DFq$N&vrB0*mCHkgvopx z;p^mZ_Q$F!v9FZ%)P^3%X~z70obVU1mjtkki|UrDHu8vERub{H$#^5-tY1K=KIkTt zJS=jfZZA>qYUFFgf+>1877qW|PQS~YxmSD#wu+)VCLzzwH3~->s;lj9 zFTKv4CR0l+J(lwWR&WTSHND@^o6bsPXa-tS>j3tYyIoQXiio-JWi2HoRCMss1cE<` ztAr(&>@H{}<584Sh&mV%+_KG5I{R{*3Ka*WC&~9b$8I1NETgCIq9svQN_!NpJnaB3 z+qr#W7S9tI3ynxd8fRmxTb7$zkv`LOG}?l_uO;>-CD48AZ%}qY6`8r}2HuyzFe5Lz z04WcZv}O5aWeFOYQyd7PG1)^tSNq(LX;#ditN3hQoM zCXWR_F=gawMGYylcCUqmbXU$@mdps@_Nr^9sk`UGV-(o;gVR~h?&&TD?q$&SqBj~% z?4nRMaj1A#RaH=JooTWr3EM&@mfwkJ8Mii5dowI|Ke?o9`)tQETq#1ZLZ+swgJ+G3 z)~c@^Mmi4om(wVvS@n3k*)WK6rx6I9{h(TvWv3fO!!*|(>(RY;CW(=VY+ZyYjm9;L zY^4D&8&b9uO>nO{F5#0vz5B35IRdFR{{`U`X+|9^GbSjW9G;_KDi^lKaWLUWUt3xDMP{0Rg#aT2aNykA?w^y>}KHUy86zY1b#MI223}-GB zsQq$_%KwBf7O);zIT1)zy%;nzw4w--xis+Dgcvl`B+}p;KD5$-g8#xk=x^t3xP%WP zxk_YonrfIy)u6dCSENnniQX>}i%+GJi(6-gx@1CL-&z=QT~gO@vN!_`hWp!qvaHRA ztR6qX>SV#|V2Czmxt1BB( zIa39ivz3a13S?-O3_H%WDC^BAvQv3yfvz+_{;(|@LO=?a@GYFuNdYMT)fByWf>d(2 z-HK|iRHBZg5vsIBk@p-rL`I38oYE5G+hQSrJE z?c*XNnN&MDV6y8m;Two=8kskNVPd0>l&RHG$h^gdof-@b{~!C><-ai>brK;zWA>%P zmdRh*2ldSGI2oP*FUWONbeWMAtmOnR83Ya?akx1C*n3`m?XKF*^wc>=AoSZ?PcsYD z5&UC6b_u&R{iB`4x9+GO9zjN8!%nM4c%vw|)mB}W-UWvr)~zRc%$m@UE^=7(} z)c}GZL=XP!=Gs&tAQi;{exwIk>ag1MCF}#FMqYVKn5t1{KJX(JlB2MPdKLJE&YmL- zOkO7E_#>ETOQNR^jEQAQTAHU$q`9GI_$QQQg*FsbU4M!VEaS00p2_}Ikw|J@R);JJ z=x{AQraCmgEPqlMU!W#d2ytZM=2k^+FAStQ%(O?zWdn;cymzRc@bn?-HA2g(hN_HU zYl+KSth>ZmNkT35>|lez&d@U9NgLGaRJOXsf7-#e28LPyKjx`Sej)oiC3Uh)z|Lve3Lm+JXO8H&0B*M)X>>1W%KW4jp0?HG3h z99yWkQf#E1e|UZYTDs{NPTqT>rY=-Gz=LQo9zGPCuBTMBOl-~$GNaVB z5FEhIis<@89~~CmpaJqnuG;*?eoe_;;Js+p!lV5Bx6Ncfsdxq3$j-rHSa&GX`V9<0 z%@O4G;YHmip|xjXQ;dt0Wv6+Xm^+pD0$yCS ze1J+XCfw@oVzHMYPIpC%g>7Z>NlGr3@cwU91^$!aq?I98fs;vPw1VSC9T{qp+K*5! z&_2hDXb@&>$$VUP<+_26k#6+$iPG47=Y|TE-!Y`Ac&q;^8}>x@!*ek{7^oVBv+#T- zjaj*GMPK5q#R#V2&7D^k3Jx9^8c-e8_AH9+WHtt^hOF%VIdEPsQy9Z?Z+t&h zB7o&dyzaOyqZL;_dwpcBTQ-?;uiW=V5=ZifJ^ho?;J8tm@P;xA0-YCvenSc#H7Suu zr0N11xn|~hnWS@T3J0}Ju&lbTn-tp|RTX_=0bPmeD42`Ez+w}G%<>3Y`iz|+iCOJf z$uHnYI$fFB%(OunZU)m_@r)8$A8s}!cg>615_&M)us!3JG0bsPzNQmnikh^~qmfW% zJGY*dW$N1d+z^(E2HsaDGoJ*TQ8JP@wZA6@Qvwe&yk}xa~=kD|m~ud)t}LgXB6xjb5ca>mq|zOR0@U z&FTs}$vW_vf@Ix*2OSNb@Z zlD`SqXr8AY>{XYFJdVmNCG0Mgn3Gnpia*kJq)S4YdP65g?_70~V?K}jF502$2cv^WIE{E1EZF#`HcSFsCtIe3$_+8JwA^w1RfL$dzDR)o`aq zP5GRtf{C6@sdyoGe07*e`#l~=GgRb(Qt=~p!=nt1$Ghcc4%Cd!2enJdvlvxw%8qPh zvx+N1+0?BWUQRWAU`2xouepA< zNj+O=Z&u6FJ-g0JKJpIvCOuLqw@Z`w)uU+gAfUrf4-@e!&qK{d5r0=LOysOaBMh;F z(qLZnO5R^heEQ)(BQ&2x@h6r8d8L_I=4B zYT_$g_*|9La-R!r>JERP==G{m#+CJc<;fFEkD1S;XdA7P7nvTga`TU-v8oi+a3#>q zohusKKlDv6ITXl;Yrr_#Z!k^6d+`N}vqx0iU-%sk=C%@dDynGl>-P<$TYdbgx8nZA zZ*y3;=+CEhiWV=w7ZBWx6Hb3C?jsxspt$iQ+7l^R;2qSUyP+l7t1InO9uQ)?9VXew zDOs=|#N+w(CR_JU?~9b*5cp-K9Nte`D3+U(_&KK@GSBSml`oL_Nv9oJDofau3sCtH zrd#LFlzNue(E8n^TQAH|hL;n5-OZ_MWw+(dwLPWMnPAiTEc9?a;6>PQYs23|e*9Qk=k3Qw zs!l5ngXv#`heNf8%X0nCe0?>sar0*;*U0ZIkleyH*y-HDdzoQ6K5-SQ)biEnji7%N z5jF0$_>=VJIn5=s29o<`%%>1APL?xbmFgz~&h^0mE-F+`&GtsCA;abn>+1Ow@U=Vc zNBi*F^AiP2OTY{K@Gm5{qqvqexWNu)2}BBPcQ}VgAoD`wU7SqHjcv;FDq)3<6qUA=XSr>dH2;k3n$}Oa@Mx_$P0wcue)3>o>WA`H0wPH zs2j`xZEWB3ypn{aLs1a~E zjJ6|t;mJd|l>m2kp3FN!JGmxe`s?0~*^Mu`XO%;T-F!_X9{p|v{AlGmc5|zcZpWKx z0m8l~JQTWBERQbq2=+VipTLrQUt!$O)0f`}k-a>u+m!&!@pp%UAKLbjwt)}|Nj{%URmLoxly<`eE6{%yXR>&Njwxd zi=xfrcp}*Xm)~RNusRJ8zxxGSWo_@9v1fNVQDDa(%s5?Q((&=A$xm!s)#5%UQ118e zU#NAq&WVT?n{{E~8Ym2Dm^FTZx#n*=Za?Ul{oGcE)kNtwNzU`2{BUL4(7a6yIm_23 zwO4H5IJvvb5Jj6y@OxJDd}$NNLeai^WucgYDKt=9FkK%_=bi3bdHY{he=SB@4-{T@ zzZ>ZkSAX&1F**@=FgqbHjNZJPa8mP;_h9qs@|Nd5s{71mbP?mBsL_$L$ho%R$`9?~ z-=^oZJah{C$H8wSxxe2zKCX1e-_7f}Oi$wHWw>AWuF(#y!E~R>*Z5=?&7+9Z(n|lO zr(|6xWl@h+|4S1-{^tAVCr2=14-F)6mLEq|VuZR)JR;hI{%Uf_lQmHq>GO@`gdI1j z7DkC~yo_Jqd(I7~x%eezDK(;^S-l8vhKGSMGa< zTHrO`>NcLXV9h*j2t7|o>pFSl@sBlZ=)(P=_3WG>6we=GA6FVgnqo+1O_%;vdV&;m z7TO&TEst#zm+qm8nO6e07YW&{bk8IG)%Bb3eGo#?j+YakL7GoBoB<11I_Z9aLrQ1P zr|<85%f=(5GrQaQzKQy~!Vd*J3+nAg_bhKM;rE~!;iDnAtGqmXldIR{AJc>}I$zKI z>m&3fT2S)r<}(=k`4>!h4TQOM93Swt_sW3kwKJc69dypmqz$~R3qhIiv%{(l`Z@iO zM?yyMi>=PRJcwI4urD5&Nu^VZdPev{_wMIi#b+`Hz$TSnW`_O&u(22%i3mQQk!?5T z7oh-ta~lNX8QC(G-|~(D4RCf2*^XVAVri>0us^;7WfpF^jHPQ#eyD&K5gxp3ZjOu0cQ%?YxRcxYztMf$C{U7ovMea?m z7Q2HZs<)?PNCt-&#)3`q+S9H9<<>B$8M+PqlC^JJD{1AH=-3 z_4;Lm|L|)j*PKLu{z5O&RIa+iDZ3f@=hd|Lpf;lz2Gr~$UR2X#`UhJo>uXoJ*3a*3 zg}FV&&p+tRf-Ii73)KeNOg)@m;)Gt5-}GMIlv$n<4H9ThGSG*cSC;1izj?Iq#uy>m z0z^^%?$@m9X+g;&JlBPR`dK5~(IfZ%IQzr3MBQixXA>_DKDo(V+neTnk8l4(m|J$7 z>)s*i0Dq96L#cM+KE8V9^_rD=<>+*0ol3rdFSttF2jBuIQowZu8`^Fi2Y82-9jQ;~ zOTPX`RZRViBmGhNcco)cW z(V2ba0NLB$JAlrP%e`>O%KU5xd;@23`6?zYQ6T`;Nn+G@rIw-pNMvdIDk1{k*@THH!>>gESu>c|KPCir-#bb?TpfYlRF=87+Mg^$6(E!fkm z5;s}^hnUPhF(aG}fdB3ryg2=QZ+`at+P3_^`|ttx2|MfUFCC$CugA~&R0(jqJVgAE z|M|9x8`kZH#{Kxl`?L||-kH;<>o0`w+!7+dA)CDh;wk9uK*KJFtU>re)B7ZLQEQAr zkLJ}^BEWX?7U8z<0e##qsubl7>j!1&O81N@ukNVBLxg)4q9DQ2bC>0zaD_kkrXM0h zz#n)nL!=+u@EC;dEeE_m-VWayRczR934cYxk8Pkhvj@Ka<>6hsoN5w-I(Wgl)>1~4 zx0_pU;ywk=<|}-58z>3!A$^k1>fHJBhM1t~Uy))Zs2m|w&hrWOyLK+$5RVAJYvD~) z!fSD#E?lvJx})MK5!KVHb3*mvmh$Ec;LWc7f5Rs!x^*Ct3C_+B5KX*aVQ!Uae&4ZO zdLPp-4eAPU7Tf4eEbq;%3Q}%8w$s`P&E)a$gMX0%T)uwiwn;c$ma6eO>fF(Lv_gM7 zi2vh}^Kw?SwYXvMGeIe_+?psjuUM?ICC`HuYQfQ~DQm zw?=SkggqHaGEH_WUL!~zO!xo?)qIB626UhrN4q}H5bVB~B?Mm*b!tNkU}pXeIjbmv zsC@zQCzalCO`)5Oh(owCeuD!8ZK`$WsEk1CXb*aqlTswmcB&vz&w6EbVP@ zi!TlIs4hhy4F@{Isw`pzfI|u?Ftpyr&{pqp&>{K;Gr;GP?0(78H7TER>@g7dqgm6K z`}|M6b{V69OAKeH<)1o+su6XaX?UEkKKedm&a=G4iR)ZfOz?{@&S!3xB4wL9dgw2T zyRkJ-@*N(!Z*c;|+Kbq}1Zg%HB|QchO_yum6Cj0R>_4pK(Ll-wGM4FSQFarl@Lf5h z_X7VfC;VJX)VoRa8TDoP%QV78q5l6x$DF2z*#3Fb@hU|W9!gEPAJ`@@;`Doz&RX`N z+BC(tkFGRdqS;=#=OaDw{72(z7Wcuih<3xg?VbN(iVkEHzh z0r>t(%8@bWeF7rwD?ps}&6ymO>Q=TyG5WV0P?1C2RS}4EAiW{sMnpMJiAmSlUvP=s z<6Hh0$c$bk0ss$s)%J*P&xdkN{5Ai?Q(m>QH$aJ?o{VDLz{&nQgJ|+|ThADMrADM9 zaii`v1X8HBEib{*dM`{e@h=NM%FIU66XtMivG0$4)MD1!|E$u zvy14;i?7%i$i7Z82VHf5RQSvyn@cajLSCA1UX62UWbDLnob{};b|w9qf{d)4`E}i? zA^J>A5Is%-Nimzeg&SoDZ$*QEtZ+HfzA`=gjt)m!A2G_gS(oX4b?6%l4`@EK0HLmC zO?=^cI#WgOaQIawKioGHJwb3@OBgXCD{x(na1+vM#D2vGoH@?YzJg~sHD3y^uPX;H zM_!*s6p5ry`ZGS$6E<+c9S(9HB8R}_L|OdIAv-U%)}DCQp7@qSU!ilXwf$DmvH1Xq z{_sp{&?L5{FF~_p&9ko~iNP~^pUvZUjrnC9-Z~tgKAqVux4)Nb6`c6T!1Ez*2>L&G zCII~TTh~s1|9{y)bmx{L`E35`A9NjN>~xr&WfLgBfng~7^(5!Oar5sp?SGOST*Ae7 zU?2KaQ@%ME;_U9!-8#v22ffeR`0Q#Pw*Gbgr~lG~pY7v@>17AX;al!EszBn|(7EaK z`MCM+O|BY+0wA+`VfU*{YK+@UK82mx32pBL%fpa(z3b!OawGTk)dxq3&u^(fN9Ecb z{EjvQ65kN&7^zUd<-fe*H&s`CQ@c!V|7-oV%6j8(A}hODen;;4z>ux1yw-e`%k}bZ z{R;Qf)5Sx7`2ViD<{>pe%$^`PtzDJhST=NiM`Jzt&rRG!3~4|8uK)jnbzWi+dMEx^ zPR_0LX0v?%&1cY=a^*j}k=G4sNDC#j8Qnv@Ll6*d`I$S5eLW?kbjs4H-=6Q{ME9BXZw>yA9(){khfwNx^$|%IMN!uqi`HVaqR?43|a)7V}tK4AZ z4G&nj?@QS-dx#Io=aFS6*KXN)Tr~Pe7DYq~zzi)R7r)7$CuNq=JD$kuOpI@P3*~QC z&JqaazwQh@eu17Osh!x);s3Z20kYJI0xfGLWG4nR(Wp}etz8G8yM*tdB;VW+2;Etp z-xRAx_}CY?1D1@V8-TGy_T?=tY-X)&Avx4bwGKZReLO|27->KFm3w~h?p<(0u2Xn{ z8a;I1thYLX8?3%uqx<6;LiR+03_MJrQ~al%M{I{m|dMFyPAk{>Ve<4{xcpGe_vG(ED99z&S(S6(O8@l;rh-5~v4=^nb zrFRW|IUm-{zG?lxd^nok&3$GwyoQa+N9*6C)!qO&yAs!XuL~>tTI$*7WtiK-`*;ju zmaiW<4gWJhx#MJw$HIl4&XmXa#9Wp;{3ibLzY@#J36-!yJ)LFKA_4w~NNl7g5OLhz zOHU42yPAXH>9j*nj&yoZJoD`0)wL_LjA!`wl5a~_M`ATqx zCeHeSS}==Z3-Slq@VV-u^@(sDNb7y&y&=~s_l@&_9tm>MaP=V+Gs6##J7fA=<}gIx9ZXL`JhK!k?CE@fG6)h_ghukUrae_%G??xpFL zojM*4m0OYvR^~wufaa74gT!c`uG;U@Rfy)eE)&WwNPRZQCEL7`iySeweI- z&q@OyNficpKc=hFh*CdqSC7MY8i11p_g?v}x{iv49UwMavB6i<(M@I zFuevja#@s&ya@ndqp^uPXwV9m=fJ z?!G0FEq$LV2mR~r6cIqm;(eHbTRBb+9KN32D7YGGFlwB+5-kxl11^h27CGc+)0Zn& zg@8B1NC)r{h-b?P%)Y7oYltcW$HHhCa&qzOq8(~whh`BPC$2=t-puHhG1@bz-Sncx zW&L`yTSheV#R~W}uI&E52X|Eyln|+(D7+dLNyRBNQT-$UYL@#|1|uHXt?<*IjuVHK zi#u-efv$rhVZYrXqm6QERFQbXPZa!VB{v}ta-!g7$C&s(d;={9Ngl2cCyeT*v8nMt`AG0Ty(#uLfN-qM2X~4AI8E z`7~FATgF=W^v}%3ihNacmS0nh=R$}km)=byqr%L#kP0G<(gDv@g#mDod0R0jl^-+J zhFU{EMvmMHgd0V!;C5l~6_4bArHMxODVhj-E0wf@nB2RPFM&$-m3D(2yfggXdlfpG z|7xcQHUgye^YXm`rxaOcJa&FkIg3|0!pn2IPiXi+kN6m@1ztk)1z+8zjSaJpi{J|D z8BSoixJl{keGNb{;@8ia(@TEg$Sjl{WHOZf6Jw{qldIg^X`~;aRLJPQ(~jrWwmh=C zb@&s@CFT~^a@vC)A8r2~9q@t@@QmL_n9z>P&MW_%_3qWi3x!ypHkp`|V~V=AMdE;7 zv2rDf{m-!C`RNJD<4w*m%H=U0++sG3rB{9#6K`gnwf>u4Sp(qM;$q}j)=i4v~aD9Faoi*zFMzZnH6qq(#7$unYz zT$B3?K2wwVNHbT)<7v-!jttU7@l6cetcTH?BtYMF`PO7~hMw^j7QmogW?T^AH;X@l z;SfRb+*g_Tb^!YhIBpr?ww|?sAmLQP&i?vecqX-SY(Tpm>o@-$m`8Qo(M{RFs3VR-tS3I%88~bT%>rZ`^ zda+d-BII}|lAG}6zYeu>LxmSL;omjCRrcV7{htc%G17i_I1P47xi!-*&!^a`Vjuoz zL=~rk#Lo-#TVG`sZ0i5dv|AVS&0=EB7yXL3AhC5ksQ^mdH;-F1vaZzAty{*{Al%UO zP5e2q7a=NH;%Ll?kDt_H)tVfK5zsssgACvyMJahSp{$q8UZ(RM2u+?ujk|z zv=PlvF)A1|^A066`$H?e+XO%aXSepI_`v?EA0Am17MYu+hxwWQ%lIz|hL8AR2mdq7 z-DHw70<{;RW&ci`NS*rF-9+~rc$j5)pSwg2bbpdN-Ilw6rwhQAQ%63ud-t!!l5(!# zzM+J4T@vi7i5*__`2QjYuO;om@AtcqNGi-3DmJ$c8TJ)T55Tu#a0QEw-3i2={=-0K zHhugXfsi*`J7P+eaI`#mmU#D<5H^BIj;Zht6s z38(OuZNd+XOkby7sNsACindYgS(7HJ`#$Uc;!|SKCT7F}Y3_9)M@*Qa@xU_AT%T0LEA? zw5g9Ag)(~Z0{2yI-#h$X4T`C%?)<=;}9 zn-z`3-~(RTha9OBY)rse&y~WfroaJxcbXbtS87)b-Om~sd4UJ9@5;Z(!7(t_a*ktO zDx#;LwEa&r;)Cr;Z-w)xz6VOa_cYS&%11c}jc=sx1;m{5XV{Fl(gWxTf>_2RZ>XUD zzfkMrAcz>`wMfs>fej141*RO<*TkxL4>WFu+AD(FcC;x{rab@CJmtV$hLPzmj*+>Q z=gYrn1;){oXRVi$?Oxp{pTdpsgM22S;`OqklZ|~xot&2YMrW+hEGpj3lMZOoeB4!W zUT`-ks9&$Le?lby2-00;z}JoE{oSUb`~D^T0bkNBih4;^m%O}IFt?Zpi6ZND_sEe* zMVnZLCGqYeKmxcu)ChPwSLTOdB2S|86nX^SHM*Z8TM>>Z=&)XupP>tvj#oVVyGJ;3 zd>3J?q;OB&bshH740TU8M`W%>mQHwu)Lr9|71OpvX?tx#gRv`5Mh<(q+v2*jy`0B) zZwPF#91d^DCxgqbr|Iy>-q6e#Iu8GQ`?u5ZuG3rdZTrZZ65#fcEcZS0$T<=j zEn(}}umMX>%y*@qdpI*PN<=n8yGzIeMf$9*IX`Run1GGqX#p{Pc<7vh<6Ah$xj@Mrros7z`RmEA2kec(~2Nx3uCRyaB9M?7TU9+E4k(5#pN|2VXz$i42~<{R(*AljR|aQR_}w&o#k6e z+eYRLPL+kZk53ZQR&6t{OTG!8_uP2Wm3OC=9UVe>wq*Op^$pq^jvVy`nQ|O_)bJ}r zc)(N*#o$e9{&d(C{0Ua~qdYdEy(dd{J6o>}V4o!cqSI@(yO!(wd8b32?!(u}6BgV0 zooD=;J*NjmeC-W+OY-)MzaEFy=4f4&usc8Xm_4(Go7Rc;9H5nt_78vT(i(18K)XDL z&Mi`&Iw0}qaYs3pXr;FdAd^DkR961pQ$e`JrwVx55$a>up#hEvcop@NbVlR|l?JWIad3hYpk7wO;|L_)0)3{$})zD8UVA zsN~uy=ZrrGUUGVZi(fLo8WR=D8uL&p7^vFVjn2Z!hbo1z<$xopZXlQB0t1G53Moc9*!PmSE3qPcSW=WePu3_=;UuQeSV*|- zXhM_~Q-#fN{GTL;`{>9TrpzyEb!4H-k-=-L2jl$6ED#* zA{enP(WCfRZO?x#9`Rl}65zGIg!ivYqQZldCRkI-!=kx#feyM2n=LJ|IqRcvqVpuUDrF)H@=p#BE={u-h+2Q}*rP}rbD}jK5vr4wY5tSNzUv+q9!2-` z+92oI=x=%3(A6Gb6}D@@`WD|4dEav0sPu!Z!S@cnG9-&Rq0=e8L&Vo~6doeSK&W_r$dWauwI1hSuw^FWda`&KGPjj|7x6!IO zP1>&q@!B3Xn3eF`+h1HQgerJTjpohH9?+O-6Fj)Q_?Bs4$%I7|6T-Kk0!qy9Vb@15 zujZ@+>gxsTeP#Gu!YyWj+vkCjKvBJJpGU!MOkd|00^C3E+Cx_8@ek&9E%%WpVR|G~ zt9oPS>FBvC*c#(qtDQm{)2X_}m^JFdzJR%+aljc#1vx6SHx`$`MIkYQ-+$)RP zlV$wC4d3z>q;nm(RVM9GvZ4)F2>wMfcOFofyn<h)U)N`xnBTWqZ?5k#VB zpvQ059Rl9@prsJV;~<8Gu=V-eq$kCIwaG$G76hs}Am2L({e2ZfZ1fidRNI{YsPNei z{TG+G)umX}8HVcOQ|jy+3=r&CgUxRzf#B)2eyd+Jeh>H4i%9E(Xd;1=H^xCWl6G!V zYo_JcSth~gBcy$8ZgEy5CJ!Rb!x*|iw0c5oPAE(pOCw|HFy^cwJ2EoCB4mUz3YUnm zwyoR;^TaBo^jkHA-IL#=jwidoAqYWCSwSrHtMgLPlfqg7Q?6b|=`EOAvMvUAnBX(? zoFktbnwZev@?v4r&?W~Dgsxp%kx!>ben+Z1_$zwCL%1+7MN>naM}kx*g%?E&au+y# zJ>4sUigNBoj$6T~-gQMKFUiqTdIX2y3}v&FQn*{mNx|$I%?aU~&D7`3a-*VwrjPA2 z(&8WtK8tB5TO<;}-@`>ERqIX6tW5byGdWP^CJw?2oZY%lI+&*pM8w{Cwf?B^On%rq z^6Ezeyd>BIpWr9B??G-Kz+gyJYfb!ICp)q%WfM|{%{SBY)XM_=;b+jhQh3X=kr%kL z>>AmP2A01k=^A!NAK}+-BXCHb7DJ&8vrE8LNlNF2TY!6t;-vtV!9Lf5FFeTLA~|#e zAjKjFh6PMlHErNxQkM%%rQrA+`rUiL&^DqN2bKQ9Z)5330169&b7*vZe~1} z;kn2OGCQtP4h;pjHir6ElWy_mR^C}N4{w<)VzG!t`pIAO6MVIB7jiKeEsV20DdCU5sKMjsvISuU;a-Od-3lZAOVwU?9uEQGQEWoc<8 zSIniCV!}QGe5A~cT3|61!sJI2D-`V}hsY!6BPNV$dLfxnHMD4U7D-PkST%y92vtaM zDOt*W@~lsYlnCfJ>d?1iTWQ*;JuH9Pq!jeYRgNc}JRK}vD4XHr)^i8j`?e&*29bFX zNn+uUo<<$5p2887C0HyI%ldX({Nk&=PD43}B$h=lJsKGmd@i>;YChCWrs7mECpgeO z7HX!M?@cwE6Xz-C6Agjs(2Th@X!&Ho5Y`d;N!u;r@Hvm9@Q7vseCdZ7t9?l~OrRUs zRS=jQ-f9=`NR1GTmr)Qb$PyMa_KJj~Y(YPG9PaPQnk~uR;KqV(QpFUbdFkJR10=~P zscW49D&i_#_(CsA|Ld_5twW3%^wol&4s6V=N-N zR-MF39Z^Dg7T1$0>5w8{5)7pvAX^VVdjmQ&*+7av9I1g#L|JT4ZB4rHBE}-NxSJwq zyv{lIBV+LdMHS&m)Pbf3x8A({DbZ6PD^c^4D~3dyo*b` zo<%yMWCszm7#t_l{}&Ux5he)#l1ClSdkR6XDnyLg-pVT^#Ry#Fufrx7G`gI6n^1N$ zIJr{BwioF!&BP+LEc=a{Y?V&8yK90>l$M2bt2stuzZ05}q956cOORIbb9FDmr^R_< z%r^4X7U@|$yQZX4UQ;jkU(!WGFvRx~aGGdqJSnNhhO$#4U?kH@QhtBP0&}ro82Hcv zKLOvm?FXl<2{bwl)t$b+R5R|PBOLlUB6+@_#^fD(J4R%UCyYPB;nMXwBAVlx2biR* zPBfxBxv>b$Mg~awx46e3;uVezWmQlrR_szLrXBffo3rttMe*zj$)X{QEXFNe&f*93A zSN!1wAk;&(!Vy@%wr}MAY_~@$HkB8wUq_O2^`IlLf5b4!PusPkg@i&&%U0Ncqv7M6 zlM1&BQKqWY5Of2el`e&1_ne2U4gi5aM3f2QH~EdPF%w>51N2Oj3MS-xfP)3M zRajk$X|GcW-G>gCv05`QWO#(5KpQi!(FauQ;#33~;uJ@rWIOvqZ_{JY;6Phe@LBnl zAQ?0TtN(heo5RRTJLY92?Xf~EttBM@#e75v61+#kEkax8t^bs5bTe7;CBekFD zO@5sJ+;07T417Vhr_!Y1qmp?-zeGi)40kl1X8*Xfe5Dt+G}W;~8_oIg;?Rd*cvg-Q zzVz9Kt0jeIdg68$Vcr-;X_!8~9a$VJ3_emJyeOb)am_KdV?wAcNvmhAGTt_<o>=@0Zy zPaBr|1&AHj%7d zNAFicK*JX;%E>?sI7Mw*RwYAXvVJ2Ijq`h=q=?Dl&wWX?)Zqj4IvMmZ;iMM_&B+V# zW)v^DsDw;z*i)R^53OL4Bj4$^97_CI^j@qA2;Q}1H_2!Dr75#SceTDi0ZT~1NBm%1 zB&u4EG{NHU*mz72{xLzTCc;`GAdqYg1bJ1%?dl^PI8kl#C0;RJF7nJ)eX+JWr}McM zT`~a@AoAcMXL`O4!O3x019=%1If@NNwn{%e`iqGfzwB>m#?8N91jV%(>;tZ+;~HYk zi{o2Tn|T9@)$WGK7f*cJCt*;Gzc4>ce_{JlIkGcwyYef4MwGld?9^M_^2)|8Mh8N} zyHnV+ub3HM@o99TC#o4VyZ)f3wsp7tOb&02CDI{ZedV-%6=m7_)2FU!cZGbm;}^wm z%>L2mAZys)?&;ZUm2WbF5fcDravjepg)lSckB;N*UQFUlOL8VAlaL%Mtf#`tG;vK% znsd~Giy)=Bay5cDgR)_;eiQrT;?#8 zRZL-9A`m4)P3EqH^JB0<i0@0P^tC!qiO+(g0v%Nl8oC~v)D>BE-XXqj<+BEt(MEEUqWqnR4l93cgHVDKiO1mY%T*=(Bm)u*N3>Iz&M_r9-*} z1{6gB0Vz>XIz>RFB?Ke{-aWwYyyrXTy{>Qm*n6*M)w7J_ukDby#$HO7$G9Y z$_I`bq;ZCvgGt4TDQ50kMPFgKG;0e9ZMZcC5L^W7?)qrL0UOD9_*T!JTTfczD6BIx zn_sMEvw=#iNnHV|(>`z% zvvQbl$d|PdQbbEqQ9E6CW)@3*cF1}=;myCE17%Vkg&a3s^V9h!nrw8HI|3O=61!P% zs?xv5Tha1s_v@K$_iS@->r*NTc2PP`>e?3f*|Wl=bMW1Rz;AF0e=3sM=~%MgzLuE& zivN3;+4D3{QSU2{A*Pt&V5go($)one^Qn5X9!nfZ2iGJcKSu3eMOp;4Dm!jH!^vIn z^wIUhgxSUhUl5J#wDy_*gDc8kY$skUG9dVIluh@TSILx=%6;h>kTr&&>P2qT)nYnC z@l`ubLm`57y}Na^N+BbBuP1)QmQ{jCCZ9!g?rxGS(iPQhc2~PwRn3E9g_)IN;t|{U zb}^iSn|YLd=~}x7h(TrD&6H}F>E9sr(fH%bo=oR zZgEN|$6MW^u@&Nn;j2@*Eb5hADa|i=w##?O7P~!Gdunp$rUPwVq-FG-_PLP11{%K7 zL97iG%se~0J9qPaRiIBO%$Nlm0wh0;8kw09LDExxDKm`Y4B(299K#hw2kUFI$!SiA zju8Qd{9+^q{6}wB&~9^3ALqeoj_PaIXTtekdB4~02?P6vSUk^;Du=>Y@)_*!x5!Wo_Z$1S#siSu3&sFd#E zp1f;F*X~`tu@(YGgDp4UyC>JFt335qt#n3dacFOO=F^kz%L@&v&B{6`h7x*YO_Cf> zv=YpVrc@e^;jhf>Bst(uX#E%($18d7=|4;bnhSyx2YwNRl-2hJOcm-`>QZlJ`1;Ii zWq{KS11-izqbZ8e#El})UQIpu^*EI1j|3`hF#4mq38Mk+#8F|1^IRje%3F7fxTqTW zve5Ls58c%QP-{A6Eet{50?TA2HaF}(@CgK)8$Bg#d2(aFb6vT*`sI_6xKV9OR>~s( zs$ZQwxFi+bwFy6Lv!FzR9aXh^oke}0g0?}ST;Gdtk6TLfAEV9Hl-^a%%-bstiPV>j zw~t$V|7C%3=R^vM#2j0$;_46w3(Xx{vQf4t1PZBlMB9CCZjc|1;}Y*|qcOajxs&24 zT3zwyJ1(l~8;#N3CQ{+2T5&6md7;n#*sQlOK zi7&$t^7P-k{XV;UeyH_0pq#2C!jEgf$d8i7ne(nUnzB3KN8H@(`~pcq5GX1pH@pU7 zNO}L_zM|DXMc&aGvO5Sn z%W8kab%=0Powx9(DHqF%N74^o5t7Udys>GaPtsLHOqAFaxBXMN*Oo%88{`sS$@ECG zXp#SgH-T9(4Nj=89mW)|St+cfUGcMOEgyJ~kZ9^9?zZ#7A&TEIh-owfjjV@g2^gD4SUQ9|gESxt^enNm_6aF9s_&x@DIlZCeu@Qj} zu^58gz&&xn~PtvQevrm`Cjy!1mRtie^x`NTS;R9B$)QO6w^56_N z_TJ4(Zc48rHx$1WwEG&1o!1@B1mCu4SzY6$6gBRjqZ_UC@(~aYJL1~w9aM>G=GOb& zmeiw+mB1ke?`h4kT#2f(l>^#Qc?I07qB1dAh_V(HVa7Xl|6CXKSip|?v1r$y1Ol$u zW`!5U5EO1k17?(%k#Zmdp#T~Z`?H)-!`17g_lNa!j`3fTO{8(hW;zr1jhJH1+U_C= zJL(rWBPZZnd4?&qZ>Sbr&!7`#CPoH52xg!nZ(p$W4G0t%iaa_lf*DAjEqUr;c5A9->Wm-?BMqQ&^ ze%W{;rb*WkWthzSs+9*tEsM}=B{XDruzvD1>DepU+Q=OfR#LQjO+o>N!hpcsP?`_* zs!D>Uz-*K^o=}!XEZ#_-MxMx&<4*Y#Jj%r}+0EWer+fi)apM;ZM#^N_T1!^|(o`i! z>m9;lPCFV_2geJfsV%UTYXdOP01NtO4 zF$Ahoowxy>EW!lJ8ej?*Wyf1F8VG~Wn70VJDGayV_%bG0E`1+!hVmpp4Mn-Kqe`Q< zq)@>zu0|;R*ex%VV4Q0r3O|0U3N;(=+JkCL*jhlvC%T@=StYsBqhZNgP&8SJs}_1` zczOJz_nkS?K4$(o`M!RExq!YPp}G1#0pYpTzHjwlDbUe~oTkkF>qvvg>oJt9#1k4Y zJSh}qE8=0*^kD7*hPc_l?}nkc1&bww&1j;|kh+V2-^Yh9~EH5NT}>t$BG zNuQjP!B)U^EG`ea?;RR-kh9K2jgW_rp=EnDvGOj~&>UGHyE zRN_tteGTJftBX#(0Lm@HEi4~p!al4DQ5Zz5UZ$v#^w+uPml zAJL8*w70W5BtyVM9_egCTu*;2hk~m;)Afa{3x6bpfg?Ea*<&(lIv`KLNbmGEp`R0^ z$pHIg8u_gwedMlMBwcc7!~}&E>9$a!r5c?1rvdSezK*SE@MqujbTEe^nU!c)$|_Q{ zJ3SJvwo6C(Izk*|_3e)k9Mwa^q7WA&ZY^GdQd48G&Wbr)?~qFY69uIg3UdvR4e57f zA0w^%(#xgQ{BHd|jyM#udhi}u@yS5VHC?`*7R1;!79&p-5ec)Z4r5Ff(NkiyUW<7` z9T6#M1@A(}4H$H}rJsuE1v6UXkwDoaWDr)xy-10#ntASYc97AA9I~Y1!@e-L4Zm73ZaAKabF5o#9Ensq9$k=(ch;{|C0IZ&M=QG&D~? zd?I2D>%LzAMYiMwoQ4&D^O+i5)@$YuXxJ!Nn!ZnY{JMd~(XDQ0HU2#_*oJUG$;7AP z;T%(~0_Q%vPTKnDl;z4~#{8=qn$ntuAwKq>zP)RE?`kuuk2d^-0_Ibu%0G+NMnJao zbt(iHPIbFl4bfz4)Ec(q4x=t9Q-@>+tLBHxQXI2CI}_X8JU0Mx_{o0p%e*bhbpaJl zMYp}0VB#@fd$BwF$5xm%jF-sC{*h~5-ZW1C4l=IQA2Q;56^vP&)OGLA$?uVB@9NhKj@w?@ldddkY+?cwk-u(?N%6R;h>G|6?yieRj%Tbh*wHB#~Rexsm3qBv; z6<~C!Go@L}HanwPV;WCw5b@+b@J|18x^>$_Md$ruY_Zdq<^6q01)fGUPqnW_YyGD2 z;P(3)Q=;}3_*bQ;f9i#Fio(SX@929!m8RQ3Co>ys)`3pe)?*yfPLJ@7m+A9f7uU(2 z6f&kXzL=>!n;6VE(%2X~J?akfBIlKEYu-AJmL0TEcek1FnGuNnlk1f7rU*YQI3QzG zWaEUAHMe68V;3l?Y9`(mCNLQ-3DCqTr3L4K_i*jkELF_$aud;5dIcJB7fo^v1*|<@ z&&u{No{X4Deskh}J8<)NOxU{E$0bFF?9H8|j^C3>v9u0Br_(`)hX&GqeZiDZsXCnG zaBHm7yiybNI^D&8HXc4EC zQc>}^Dz_3@__kvPRbjn=(x8S6uT#5=%9aCoFExrqg)?=`32Yoj7YzhoFZHjdWzsNtE$N8A_Rj9|ZvNGt*@xdH2p1E+)w8HF11PdGp@pvy8Mf&g))hUCwHJreulhCq;0+rvZfxCL&SGRyl!v> zB{ug@C0p5f=nw-RVj$_v>SB1Y^nG9B&mDo|*Su|iRlWW+n2QAj1d8%42sY%HuYN2n z*%192(wF5^^QP8o$2XEGDQMxub;N}&xUuqe8FFMiNE7J@tqeK|8plb{=O>-0Qyxu> zblxCOseENl-Iq*T&$b9l>%?&OTLwex#QcH(8vUEdLDdWFq=FPf&Lwh4fkW-L)O0># zkyF3wL!b*UOCfJ$BW3q$jaj&$A!>ls>i?5+P|I{iJq#cd_s{e_1g^G5?r^e zUJtw)>D|u5Jp#+ZCofg|QCjWSs{hX1T>NIcMRJ1*Z8z6ng0Kjix!Y>9ai7&LAaU8T z!`+^5A{Kg~RNK^DApko50ysuI^nJXbmGsDcguCBpLB^Cb ze7O!?4yGAxsSfX`%&+!g)Y^+IUF21neOBy&1e%-mqowE=Z48b&xu#6^)(?Mn{Qhg3%k^;xpSsv3s{~6<0HE45zqyFwN<$5z}5| zf8LI!j9=JC7H*KO*D#3{M}x#FgAmgcD^$x5p;6AI(uy42xfw@q+~;-hi{#``BH+&*(%~-+mH3G1FNan5hyVa$`PO^S;wghs z9&i-|aQkHlvhdf)$w+46?O4|oM}e`qw=A87=TKPvqXH&vAU3~Lmn{4MPi>L-8k}yP z{a+Byt1{TE36FuS*QXj@H|S=4uf*V1OEjjW#|+%B*W8@C^au#T9Id0`o~!pDG=4RJ z)X35AV_4=EU}mPG@}tgYKRhZDC!;9I)#|>LeUwfNJI4;s2z$N2Jn2TW$mWGwco1tv zAM_hs6sI~w&u=oE`ZKJl;<|R*E&gd~PPJ0(6!3fpVG^+SEtBS%HIghPO(!9@LLviO zO<21|cz7^BPVgK1LCea*C&i#Z^VtEPGElS347b6N)GY_$fsmJ^KdHw}3Y!j=+z(r^ zJOc?eD^gXy(UJD9olkb|p;mV*x>PS+`EJqeQbzHm<%Fhe5%KJ>(Tv>WbFgZSaY?Sa zHCJfihL3t$nl^&BWHn%!QhD%#XJMah?AXuQ{$SDZ1xCzDhmVt2Z8rR(zg49DyZ3XZ z_o)575&fgf%QGS>!52K7)$c{tYstU4WX&_0#%=4B&7PfR_zYu#xNAZ$r36Y2P*bc5 zwZ~~DI-Z7iRsP}j$Yffsy|u3%IBbg-Ody~Mc5pp=ER?ei*kVR_@%ceQ0RPDLz1I}9 zwCQPj_^WFFkW{R#ZsW(qM(S8qn#xv<*cI%?oIw@Oem|S4 zb7R2XH^{<^vyIE&G-k6~0dV;;A^3vi=X1u=&y@F7A6M0rf^aV~A|>La zzIOw$%*8suj0AL3M5;Ug?C}TTbH@xr^GM{3MZTozr_s%VSG9hRh7y4(qOf774XZ`{huf2yU;P`C+D|5-|6-? zh1dM>>#NVz-+A`5oG#$`(z5_6q4Um)XlL>B^71((AsLW(_ZOIgnwx-oc(@Id*(r&g z1nKgZxkZ?o_}96`S%A-!>JB$p3U3Jjt_&)(p{2bOxTc+_!u8{s$x!7rH4PpB;(bHA zP^kIZ&?j!-pH{Cyd2Sae-932RDG`ClFCV=NjR zI0@_Z;8-CD8NEIXMy8WEYXQr3#|67-u)!exFP8vUNp|vRYVOT~*7=-AJ55Yc@qApJ zCRU5juQq;feI#PWuEC94gk6_vRQri@jmVPAGc>GU}-+bI!g+o zemSbTeq2wLdVED=$TH8F+wHB_YHdjmX7SD+`86S+2k^(p5x47Bvfy#j)D}yt|Mm#iJB~4UGE4 zqzt69u4YKTcGAmM{?tuNvh3j$er3}>&sKGstvi-SkZ=k4SC9I3MMpg<=vGM^KtXa) zEsvC!%usx1P3iH)b11TC`GVP@Q~kK9O>{)14B#GFXFj0GjJjW;;a1+8uqk1`^cZrn zM-gShXRtNeJ#r;bj}GbxO%kz$@E;{!g<|z<`ZzX6J_c^nW_zxp(1loV-R|dtd4XwEvuM%dV7XQxrzT z1wOu9o+_?$!QSfaQEehA0DPPoLuIa1kc(n9aO*)bXwxW#p#YFH!9|5 z6_>DFF$O*@IL{KEsxH~bLt!T&F8OB6DIQnV_MT@0 zlvOd;aeWu<`RD2cxNA}6544V?RIob@GyOve#`&f$V4%%jw{v9`lqyPbs8D-Wi=IB9 zgFX!AlD*t!=Vzu82tLDv;NO(trRuAVD%f>OIX9zB>Z3NUN9C;FjStB9Dn2H8@bki1 zRnHY@RNYI@j{jQT{Ud-s#=M=PUS#cuK6B0-QUlHJB}LhFPWdtI^tVb)GI{y+TCU1_ z_8DBUY7gas4~iG|n0GKuLNEFJxHZltAdbp{O8F^_obPsUilq2iGjyAmmf7;smSqXd zpr+yBhA^N?Byimii`R^q^4PX-)bpcjD%r^i0gQFURpR8$N4sKU_mYcPd=D=MgRWZSSB@2%!&2;72Nt3m zy(fiVO0#y76*KbHvN`_KmkWkxzMoP*iFX-u(r$pjcja4O1AebZ z06pKs@KIA*HkfRNgYO!>_;cN`BI3t1NNq16Td+fyI~{oRder++#*fkAIk$Kq=%Sy2 zwbdR7&Ir-VYPbXMUg(xl@JkvZ8G63UQ7SlI93hVHSJlCNxrY-Pv0{=^EM;EXaskuJ zlF_|Iiaur*+K(kD&%RlR9}`H$dOmppY%NSE^O|di4*`61j)62;Pu5ib$mqtNQ+kx0 z0#Ke!$@zTFz&GUfA~ZMpVTUULoOY8zXoMn}!J>kbYxYSwiK`l%|I|PgH$u_XdTO1| zHTDcMA{lggQ-}Ukes#d>R8YHNRv_WG->S&Z5Qr5)>WGn5g{x1i}8%0pa582?#tu*hXj*N=f~ry%-S2w)8^#3sn_>#8`!NyevJ> zb;pXqScxps1C5OZ2`Zr-z0sa_R!FQ^-r33pW#?=I64bYImT~s5`$zC^6=7AmsOaA< z;z1~gaPa~P1QQCX+Mzr^##nP|gG@pHtD^Y7a$@VcP!WOjL^`_IU#(14I5(1`&b4 z02BQ`=>VBHpxb}Qpu*t)l8Hn9JFgfRXzzdIg@OM&uNVv%6aS?1bVu4bqTMftgSLx{ zCkSi)^Kq=~Z0!O9@?VDJK*o|#sIZurI9LuUBO@=2kQarBAY{M_U{QHtn5+U62K;OH l|4(v0_I2$1&{#VHz3$+#Q0GgS$&`ch}(V?oM!dxw*N&uj;E;@1IjO zduF=VbocJP)~RYrMNx4E7DjeB%Cho`N;no0W)gd2D>yzrI3`6Wds9~vfD;Lgkb{wl z1%O0cL6Jlq;N)y+Z%4w)$j->jpdv4%s3NJL%0u$ojHtbdt1ZCJMZ(F*!NStSnN^e) zj!DD`VC3@q1yLgx011sK4=XbZHw!BZGYcC#3p?v4W)^B@W@=hE0RcFGo#{WGS^tNC zgh>`)XYOJ_!uESfnS@E)(#GXC8YXd@-?l^nCibQPlHcz+yZm-x3->kStYhpOMO!T; z$B!T3#5B;Gu}ml=g5V8McrbXjQtQnnn~U1wGeLvnk;5>P{Vm`dp)PJMfackl zsC!Mbf{zD-d$X$#-&;Q?*CxOBUtIQZk!Rfan1Of{Q z?VoO(UnjbJ_f@aD{Pz6x${v}V-#w^k8YD#`H zicHDz{VL&4oy#k5zK5nt3E7^a9XhcAu@>z2Rf3;fI%U6_Hs4_y29E+Uh3+Xs2psAh z4C}d53G9BmJU`oZs;4qrqc_%VD6$%j3AD-I?V_dO;C-5~KSV;8i6N7e7^Qt$vJcf@ zVQkvmBNvWvd!?d8&)fwWMfHZsZKk66T0=)(9yZw+>CbtqnmTraAGOTv`U;a^^*lwd zPr`$*LSGJHb?Qm<&^GpJl&kCfe)3-6pqZFf`|FB+4&B>v*Y}oJNIk0KgAQlb)oNDh zDjlQjytS@TE_ed^{o%b+@sZmL_-<-@$I)2oz=BElJh+Vf)41Nmcv7nO%NZZ;YjJE3 zyzIDA2Lq{t6>QE{hy7BmM87GAoW)!VI0^6OLr}#W#?TKZ{!30vJ&KK_*aWvOON_)b zg+$zRp8oH=p)Q>)5{{jij{Cffw6N3PtKdiF4VBHLZSjKpzuWw5VuiKVKR5~M$J80) zzLzpXwh}faD@_f0klP8gtQ%%oa$58p_;u_1tD7g{@J)A|kR^^nM;e3P2y2&H;MJs8 znLqr%@yjq+{RMu?iP5DdD_b6mCP{&6OZLDsP0=oH`JxjBHHXj5x=!IPoqQisSkc&Y7QMUk?u4~Y> zKR5@D^j?1!`O_j99W=ER``ER~LRpwuR`|+Z|7`<*5o7m@YpScqxHpgzMDyG&Js)_% zDfRx;FkIa~6uDE^3o3I?s9v4oh{0_n_w@eBI-I)30ZE>!nU$i-<>PtsM;m*kQRSy$@2lLTI-Fw%J?4&R(5YIk72W0%&wglRY~U9_%_k^2WcY=zr+jf`QY z74Bs1#hhV>*VuhUo2-I{8Op-u<7Gm{^b7X5F2V@H2N>PAZ$^{czGT<_gn}h%^$?`M zUoE{qc_TvM_+c9MYShy>w`KOdA3g;vgf@O*#Vf;Q@y7vz+%8l|r%%qp(gcLjUa%yr zS)*+eTQ-9Lg+BF!SUZm4QbFZ}VukDm#{UQ>f@()$$Mdj~;N}l7L^E{t-keL3MT$O8 z19=`lr)1f5Ai9s1^)C|aI^w~2br?kHRyHZXbFMr2EPowk%(7hGFSmFo@pvrnsrnUF z$LV9>j?CNnh+)*V(}VLl;M7D{;Q?kV+hFSQ4LcfMMTPIcAH-tu8krt#^@3eb!?}b4 zhEwn1(^uhMUc)0W=*P&$Q419UvvsZ(y9**+|75<3K>7jaft~Z8yi(fJYpq|(5Q|1* z;P@VnKQp%nccr|@_JGg9eVlJ^M%DO6f|L#^!zn(YN^}qF%{C|=43bn;?rvPYOsDMC)J_MdP2sm`q|_L z!Lljb>IqHxnO6GPRA?*!orkB+Z-?6l9v)+xI;ZI=MO{PZZSuvdP1n)fz`;Ij9A}OW zkPU1jh2h4M2S85hvosLnZjwo~UU3~|*z4*NSNU*B117OgK-zVEa=JXBK*VMB!o?57 znQ(KlhmVXG*EL|^3C+R{>g?FxfvvLSou>&KtZaB(stqebBM-IsMSEwbPG+*l@ zi!z*QhAoYqi1{m8tD@@?WZyp4PQ(1PCM}*;6F<3WV60c*o;y{2ZZm~M zgCp!hz`3a!A$&b8IinqUI{x`2!zXzg{+FT(FQ;=sZiLzB6$OGkx;6*@Q-gf-mFE<-%@eZeQP_l zbLbnfBrbXT^gdO5Pm^qZlO zqaZp-b+u-;XQ0s}JOx<`or61$s$x)tmp#WEClxRQr%); z3fYX1ppgqxy&^B>;yU#LKsiMm)RBX^3D9$7kfwNch_hFg49P-EsgU)XZ;o3v_$E@Vfw3yB9x#qi+-n-?uIv^ zK!uG!)>+(uljjt2&J$$)s4n&Iibjctz_PRIGqk0W&ON6Z#PYK!JhC6qA*UVI7uEcv zS>A~V-tGT=ztyHy!<;+O6w9GtvmkXNl{y>hi53B`cr$ z4lAg4y=PBb8f^$604Ws!-_2Y!Q3py+Vpr-tAzUv};H4>@MXBCiQ+ne~Z#+o;IF=rU zd&RzF>;T7L4%QlgtPn~mLKFEj8BzlQS7w}7TUXObVcs;9p{hFsQ~E0*R~{5=22P;a zxJd!TwTqYoiMtH+X`KJ%goze-D@-YOJwfaSw;?Sp(dp;N>(OY^n!v4Zc0^NRTS;jF zqs$4IqY=!laouavGs9C`HHN81aMyXL0Rm=Jk#MXppt`+x6w<6%;r4?NXgfVlT92Y) zLj1L&tkwX3E_zsq0n$E+6%e5^b_yKutlk7{2H~x}f?i4}4Imq(KN%~ImI|$kQV0VN zCle{@h)Ro=@r{4L4gYrV(OEv<7qJ_F;?9J|{kfsVH}uTCOmKb5O|U_jB?+yI2p4c} zKXR}oOX?JD3aVNw&{!;-iSEmu6-BVy2uwjPXsomC6hk@Moc$rb-FZ7%g`DImD0&|R z7!HR+{}(7t{71}2t7 zPJtj%{gU0?a zP;_pEF`0FOtJ{HX$vwmw}Ic~h+!#jtWj zL&Ias;FSbG7(p-O%L*G(NTtJ+hjaSJKAg$sQH-e6l*}SNZwU{n7E+O#Oln2n$+tUu z$@ZJzXzm!qC0%dE3FhuzGLzPP5P%&yui-i$4WWw}4_Sb~u!+OM;&VRZ3n~w$3mIEV zuIixci{O*7h^Qcdgh7$A+^9}7D%ylCe7xSs;=V*v)WFylk!+8i)`e5X51mE!$D}Hl z((;m#1PtL=^rYR1Dq&!JRn8|g(i}(`wibxRGRr|r;F*GhReup=wGk$Q!H&Q^Qt+ly z7fYE+a&xQz_G192!|6VKCuMHZCMYcS2)n_gva811P2v3^|_gIhtJj zDA5!Q)SrNY_>10a#Af*+@5n-%h%7<)zDg9nkFue-ec#`W7PLaM0TwgsKVZQ4*;tG4 z^HaBLK3)@O@U2-%3WE!fn3&L(?D}zWER48j$id@*sGmtP=*ZI^$%CiD*--+MQ3GBr zN6cg8Q5yGA8(yF0wT-kzRh9>*$O+?vi6BUMWXU=?$;=xZ^>tP~ERH zESKOyLKVJ3En~}!AP>b>GWI5hx0e(zgMKHwk%dEXTL=Db(?nuhMv%__oGss@-NScf8NmTVEF@K|w6qUt}DTWxuNkvCD5Uej&8yA=zZW8Th z$GZoDL(qw*P~~-FAT{0(%5ui6$&1=i_>RZU4#S9uei) z-qYssDXSb@dhAt@Ny}OoF#zwr#~(#fMAHLRg>a8+!e56orI?fARilPkckh)+!uMFU z=@`k_Zd{yjT`8`{k)^`P+J1Pen~l&s7|zt{H8_K%6fM^f(FFwW%RIyF1{!tGqzkcx z)5QDHOf>+oSi@ma#S*ZX9Z}-RD>pbdC8iB|D(oZb6-mh8f{2C80x1y<;;hcejMNaa zF-JBzTg60u9avH}nw{C@SRe7nntf4t<=8ce$F4Gi?3d$`$>?unJX8yj?I@Jd5kp7F zXd+It$%6xe2EkwfJ}_itg2;hM3%M+{_Y{n}x|?A_xMYzww`C9zPC(P~Es1&3#~?^I zAY&UHK@A0ehpUL|gC!ioEVJ%oo~sjOmaC>WRaIR0nO(5!#OEJ^!h7&h11{thS0*G# zy4^#=7lbvR@&X+ zvYBHO=cQuVns$s7j%!wQXxytAIkatfK#B&Q@Ze5GGgwp_GDdKa)_EWcL`d!(L#ZMa zN<0-J-KJwrdN{iy(`BHZEd!gn1t>a-I{btp+fW>_73PAO9})(NIFy}gfUQ9wyv}fWZ!kq01Vu_f z!7ZdGtPF+;e1xbt0FhN?&m>B*0z|G3PNmrtRfg;?_|$Ijg~)ihmoLOahK*H4GjupL zbI`wje3xKsxtBCVy#EvgG-C3QC?<11gpteSdI6Z*O=Em_niG0jvqzSQJBKcrb(fKMo_Gkj(7 z(uR7GRrR&d!fpnNW@t*5R%}Hjca*=SAzk!PL%8=SUk0gG*x4dHJgfO9piT{&WYTTI z4oNlS8QOua@C-MT(_T_db4eOyYF>DzDT`z`-=P7sfK9S^1*OnZMm=|bX2t+TJ`kOM zs2aT-Un{Qb_-u;w3?d0dH?llaMLMi{7Q909>Q~W>B44(aYv{qggv!Cm77v1~ss;CX z(z$YAVd7Df9gmnB`yu;;{=$2P2Jc|Lu7J=^9yhLgEjMXx1kIWYRBXhT<{jzVSm%|? zC9yr-PY>2r-6Lk1{Q?HK+oH@|gJsO+R4~r`b!gwzQbEk)DIl^-5hTckoN6ic**>-{ zVB>r^zW&UBrDP}MN6U!7qQ<1`znfT@IEywZrRl4nidZ$59+Fy5?}-6Mr$Xn2k9cG5 zvO7zBgNz$Kz^-{^+YFvd)Ps4n*D7a|+Ap9FNG2A&M6VH(GFr-#DQ=f%9j{3MiAx$( z97jmo)y}iMK@%IVPd70FvDe3=<#Tq$0EnVe)tk#f5EIbRe=%l=U@}vla_pIEl+e;- zOO!;7Mps-CMSnYzTqSoA6s2%E>DMxb3+UO}Zk&}v&&0qK7Z;ynugga|C3DJ-w`4yP zE$wZrtHeo5nsPrdqNU67?$TUHZ4dD&+>Pyl`(Q!s{3@^m-g?`f(2oIVMCY(FGfN>f zaaJddDoAD{ltbN>l8p?fg2Tu90J+-!Vj3@7&zVu8DxOOzU{y3q8;EM^e{P><;I7Mp zBabX?E}unK5W|co+`Mk-Evl8_1(clL9DfzjGBswt;%G0`6-2Gwn5mm<8Qf}4s;G8k z?ex+MOz5{zX6IF7ttM%K#Qd=J)Z44@RfJdtr%cwz;g+EaKWK?bZ3AE6ffq|vFV*lY z+KDFTjini{_Z-xn&ZSWj6Q^I-g$ne-UM13D=Su!YBXpvYIw0;V{&m+{7c}Q4N zAz^GRNOPP1CZI#lo~94n!j&uVXU&PW9(LT}49@1eQ?}=-hUWkqSv`CL5|N69UCDJU)a9K)v3Y#S1G`AcU2WWA zj^(vrp*o}jaJ-n9G%rrgGodA8<*`}SF=!isCMRIR7q>`JH?5nhhW#DqAXw84Rt^jH zq7#{j=qf_@n#~2f6iH=l^-o0{<1MhE7tlZ3520G!p;$-IY-fwCS|Zj!k>C~6Mh^rC z!wp-O2;Xbk!fI!x50N$%twJCe?~DijWHWrI9Pt?QxZSWRd_{ z&*$dOZRh~ZPu1+TGOkkbYar@h1;GGkr8|_N6CM0;H4(TFi(y~fgFQ@|7lxRvh%pv< z_y$QbceOVoWj9G$)B#^F2#)9%%S53tf)2EkFLAG3v#c}OC!r4IT`HYpa7Yk}tOsEF z{DoXAm-6a}br&N?x`nl=+puV$x4ZC{8>&FKj@Xx~T=%CCkz1|x9Pb)~uCz7iPPb#O zwHMvD+T2F18{p&l-7{~s&tdsjNIJ0CAP!ZbjvKU@#2bQsX;%_?i{sWWS~29KYzuo= zil;PsG8>dTn%(h~{FpD1NEzpOXy5@SGmkTfLY7jtvfW!e@zg9JI$PYS8Ae+W@?-e+ zjopawb#aGS3Mx(BpFux4j|YeOJW2{joa504_ZzBaNNwgvq$&d=ZEW)N)L%E$(fuwCSq9VzV(i6pS zjMy^37tWH29~-GCAvCNLn%TLWdX(8 zNRg5>FBHr0L_<5s`dC95LpcP55^1F9qQEsN9!^Qpk{s-bXGm?Vjt-*GL35djHmf$3 z(O1yIWnb=vinACGqSldwV2yD^0l+^9mQ5oU+2qnoa;yj?Gsr>%Tpa-LLc&z6$h9`x zYLa4uKT{ZN5LzU^9My*OlkQtU8x)li8<9gBG@^(Xkk68gV`W8nn;u0k_sX}paVX@E zV=0e~Ko$Q?WzYpCM#@l6U_r$s6%hNiqS)_IoPX`_T~tyZoMIo7=w$tdt=%j{N*_js zB^_V8@~a6YzRDKL%F5tT=Dn17wopq!pgUShzgd~u+|Sj49^(`AIdln@S&An!cr<+O zCmuW!{jY{63&>YYcPs!``m_+&1Mk9`C9K*s90!wlMgmR%fc_!`kGiUt87@r`n;l7| zcIqmr&?pe=CTq*R&xIl53jhFYFI4S@+z%_AgM^AaVXn5;5>Bz_9Jl`5HwKk%Hnm6w zV`|A2*x=S%U+@y!umh%qXJ^hZH|2!r-mu`#hfH;BXU71~l8JlaSV`rfB8B~yrc$ee~FGoIH@6Jh;;zQb^(n9 zy&M&-GFhax8&$dzQo>E-0mgCl$X3QNF^{LWqmV+H_(B5Mtg1{qM&7OqR~-$1 z1|##ml>uNBT-UlHql7DTrA(fJ0)Uv5u}rPy3cM&JlheZOc~%~_n^umx{(i$LW>f&x zY9X&g1UsN?Wxi%6PFAaWl!;;G308-3Pb))yt@R8_BT|nMN9$`r9{0#vJCcoF(1uI{ zPyR(G4U58z&|`h(R8R}|Dd!^25XVLwtEFB|@j&9f#l=KXJdKdY#Tp$NfGhu*HDAy3 z3(Y5TDSd5mia6qtUo)1%srXVYRtmZOv7)}mmX?+xk@O~&naoL)Rs*Z898-!=Do2`{ z`Y(1Aa>slFGnIX3gQCyy*$Y&}qgQu^g??fWP)eae;oFQlNMXb?QVRg3OMGQ$iWz5gBcc!Sm^nk!&rA z(Ni->I2zKAiI48t-$>Tyi=a!=x9_}4v3M$x*1s0dm%RL{e|AmJ&f-`nEGgFE#H33) zQWr&JT<<9nD#a(pOmS^1&10lpwmJ=c0k-7_^%Mp?rW_d}YJLdM0x(6oC z@w+FcLTQ#aX2`L?JGa|x$A@!waT9zAv(hDt;`DwkixHCa_jLqk`Zk*YpvV?rvmb+t z$&2B@Lg#W4XmSTo7$R8tfiF}PZMe?QN{Kd>lF0p`d0#qiIab>O_~~{R3ZxaA(Xlva zw_0{%D>fO^&*YBM;dmS$$zDNcr;Z-u$m5>Wy(gMDF5RdusMYQmlcMbNv`&)FowuV) z{(4HNNoTOQ+NhfLGN69k5fQmJgO7*FS;QekCoX57p(>iOVO#ph z+acm?_I6h#KY)2snG?u=`r~6AldtmNlqA7A~ zp4SbNsiNtLjz{YfQJubiL$PAmx&vOzal`YlHgEKo+hMBVqD}!O!;eO_Ppk&^1L~ha zI(&4Jk?yiCTeflibQ#gi zT+014aRNlv%TYHEI%;j?Q54nao2R8H3$2o8)S|n*b)=T*@f9Ekl-^E4mml4OxZ*|G z(J4waAL&E*Tt!(KO$`l{{Dk%y9$#b1RVY%@!+Pe!pU=ou=uzS)d_E(Xhs{%1Q$nP8 z&LEn1&r^6vO;fvz5G?Bx%O)?tGr2n!Da#hm)+$(WxRa9j&DgSI3p{=AN~O!xB(nz! zc%tuM<;z&4vR?|GQ|FA7%HXAmnG4g3?`l-b4yB3BKD%2TqgSi?eHY-6X$U#)YgFY- z709#Zo;;oW@o|28+six)ea_w04IVT?g9fD~Z1|Lg@$u?cKa0H_d9?3^f1_7%oZYqG zM+IZa{CxbyuiRk#BY~~x%Uj!~UrS{tw(plWulKs+u6d@pzAqp7lb6kW4?m!P@T=^F z-7b!we{pEZ?rL=X)cOW53C>AP5*cu5$OQ<=r%qMkkTd{0W)riE>qJ&QO3sWQf2clq zBBh&2MU z3^Ox~Q5ZM261Ps`!$RkiH;g#*AY`Q{HFKZVQ3y$*5J|jDnA~}CnN8yqbmtSd(EsMp z6L;4B1T>u$j-Vg^4FGJ$JaUc1hqwSsd;j=8WoTNS_)05^AH;Gn#ZZ?H`jXTWqHSrDmltwGMWC3tbVvAA$^J2lh`r?T(IncL%!fV&7HPSMRUi+BMo-yVnf?<;v9FV}-yHQk=|#WM@Q zr01UR?iPdBG^eydZQvX^aE+6L-y*0ZgL&6o67MEiBH)G;_QQwb_)YKuBGje>}A!AyVA34JbuAt z(A;zHENb(}+GEG^F_?6=l~doH53pB=kT0ZoCGNg+8lJ|d=uax~zB0Ow501eSdP!`o zlKfrNZa>tBuRJ`|~tfJ#6F!=dZ=lS#l!~?;Tphw%p%UBA~JdbqpDYN3=1S8B^r*%dRP@ zGwM$%bbzV!F*I`r@7;?RTQmFQ{rN(?m7#JEU(@w;ai*LlWz`!5N0-IKjsI5eK|{!3Pwf@y2NLM`>7-um%d)PH#``@(US zqhswYINZfnjLq-|_3sAphO6m2MDn z%qC|C>_k@a=`Cvd6;6qf=*Br0^*d)mr$w9ZH ze!%`;PBI%C9zJ)){^?E~ATv+(l^x|zKG6aT|3d${ur>s2N1Q4Cw?Und z|Go_wE`T~Zf}i1?mgkbRSqr5HAnb#k3$ff##7wMaM&+L zi$OJ1ntSqbqEX*VD6dLkY1KKrRR{h0R?K2g<0;E$?2|e^;{XnVcDF@tSTtLds;1Ij zJ$@dy`&?Hc!q~^&RqmBkz2925>VLBkhVcPHsbIh6pU(QcJAiVH^;AqY0D~wZ4@qQ> z?Ex&ZUoH~qNM<%i38}I@WfpikF&0|RO^_i=Fhb<8JLJ@$XgIl;b|=oBnlcn#vvnt@ zjTGCx-!0F6JWet>TS3(MWh;hBG=Wl&cQyG4tfTtC#Ty3XJZ5;9FII_d&y!m zYDrp**ku?5e4aes?V9%vBUgaqhtw5+5_p7Ay~%tnRX+NeZEye0ZJM<8>fE@k&R%B5 z=pAr=ZDl)q!a~V&q8{BsEMr4_;w3FEt^ikXgRLG z5Ut;)-dyI9gZ#wRGUle<8nOv+(w)mMyO60toF2BT3HqvjN(Wy*Zh=~&y{LWWhmqk` zes|K6!ygZLq3G_#JB890#||XbAS%W-x~{S2FEbo5@fafr$&c=KR@ddSul+i?!k4Kp zaJX-oTUvhT87zY*{-9fbp)z|U&=j4m6#?By{S3!0_FA}<70EgDSV9FLch|megqxVy zcpsDZ+Enm@N6xv?Bw$wMY}8`A611|K9X!%td6o^sFZk|ZH%7x1obWb;V;6My>34hT zL!2q6=bStm@*}0M?OXwJa&(Pb`&G3fj+DEp2v}jsvL~xCm@-|-!bCZ*Z@so|dl&U1 z&PFkdx%sM^_M(2c-&Vw!?!|O|lPkq9ocv8z{_%1ewBck97n?iG`JK*E?7Qw~UX|xo z2A_Z4EPwJg9?3hPcLhDdHxf`*(%_Wrf}5eHTSMu9nKqm?k}J!_c%{)%hZMfzwvG11 z&7X8>7V=DWqB|}bNj9z6C&hTWswp_?J;>1C%E+Q|>~mqu|A19&O`Rr&EUnreF{8sr zI32(*Fn~N}BeaY2H7A|x!yteS1&#k;TSCepBh3D2+yTxVqOP%Zz+X+|8n+!J+oJm#TpwU+r3M^@S! zE_2QN4Ig{)OSe`-S!;vzN~^$la>R;<`u&l50FCC!xpbzX}zSnvFbD zTVvPwh$_e0+V6-Yvr8OA?rJGNL&6$a?t?3uj8y^7G;N&9ArLh#MzTvJ{-gm`YpA)YAw z_OKY%1v3BlAa{@*78jv={IE^Z7yOSX9FK|7c{ZPz5HO(Nrx^qv9G0g!g`o=e{p6@a|I%fXhEps7yKxEh{gQPoaIPd zhh<|i;!;;|{?UEMe}&5o9})P?jIlIcajUI`FKSwLxjp!ekD&HsMxE;YCac}(0rP@W z%_Yd4THTZAADWvq)Szu02|slpe*E$uGd!Vxj~5w1${Gube}%}cOyB}Y$Wu_ME5E9BTKYp_-l~|HSF!HxSad7+Z9YMC!mh8h5l1FRQAZP z-D%o06JFS{n#NAFX9e#A{m1``yVCj?o%GlY?`Up&ht8i|K6zb;BM+pdO@U8IsJvW#F zY{N3QjWfhtY{S1KKdEyBkdC(Vw!Yx~KZ2%3RJwt;q|tk-`eCK;kF4e^ZVJ~4{?TjJNw#C7+Fhya~b)Wu_5sv#a$PdkDR;` zVX(~LYgc*}`&YcYkR)$pqDkdYm`kti7h$s%P5x>keG;JfE@!;z(24l-Z|PgP_g!@R z5&y>?zjt1DY+l%^JpW6zRc(8g@h>)@|BFS(wwpb`6Tje}g7*Y12*0>yGPica{kVBA zX=Fx>i>(8`4^(e967&`Yr`dI_Z(l+GBu{+97X1}YyQHdHSki34D%OSioqG*;Ik=ci zxRRySP%O@;=M{2|o`5klgSlrewr)6To6Tf!f=paJ-V5lIPqKRSXb%@TA@6&;+S1pr zoDVY-?<6g7pWd^N_kGp=2Gxi4|1~u-m-c&V#2N`%?txfHS&leu0AAGGBodG;XgkQh ze)qBtc&}Eh;`Vd(Q{KY9{lCwRL^i1YZ*Byl$t1+Z&w%DNgJ0IKmctW&Rkaxihv~C> z25ru=!cuccu}$ojh44N*v;|2Os(U!Kwe`Ksm3H4 zP2(NcZ^$3OYE{d~nPy^BQ0)gqnP1iJ^r^VhIP@sWWoyW8rC77q(eu{ak?83HPj-U- zM=n44x6%3O!wu2hda)~J?F5+v-h7^NkN^K;BMcnBX4T3l##XWbxU)usGL8XT$bhe) zr-(9n_sfX6S@)mi;dQzbUbaYB`&y5*zF71L1Vz>wms`jxd%;mrIz*EAgQkg_IoFAQ zop8y9ip=4(hd>DHgU>$2nspTrWB6_vUwLY;oql?gj#b~8c_Zz1^kjc=qLg&4rhtQd z`IX8lJY&_F`9oWDe~T}|=?MC_>dQEqVTIf5gp%w- zI>pDUwyEa6iPE*!wttQIS3u>T!4a+BgCk>;CXpJ0OV+Se2oayw2i|YXD`D+_8ie$V z><$bY#q)?wf%i~2`rw0b$9Hd(k(8Y(6+R!U%Cg`EiHBt}W3*ZGiFfs(c_zMAbb|;?Fc_Fqd z470aHGQ~;w)4)gbbgrT2NqATtlV1b+w}(PD+0~co(1NHpe`F8$xqjWdM~G?D%AVPeDA` z#4MQyhd|~=A{6kM*~JNQG@38GW8Cq!u?q5g09U^&*WikoR1r>YRTMC*^@`m35ZViHR`BzV z5$5^L{x4Po)>)j1NgOe!J)z$s133jmu&4|pM(ofu973zURswMZv9yvX-9$o~z-Xk8 zWLVSK&O`dQyKu2odV|0RWVZoEwa*!{pHA#$;b^wOG(d3@SAI_+)O?|Rzjs8hS;UXnrgNc zmAo*a_^sqFJ;BO4UaGLfjyQjN*_*Hj9iW<(o4K25{-$#e$!aNefuXPnk?iR5h7F9U z(x7@eG)(TE^hm-2tspS$(#p`w*K9-HtxYVn$Kf^r{2ZEZ6H(MtXiaWCVo4A6G8m%Wn{vLQ>8{P?@7{(;Q6RPrc<>ls~RGb@wo(`7|{@Mc} ztdO=-W1KbYIFO8u#!8zS9xR>sd#F$7mKJ;Bi=`+{rj!7`GTVf?lFMYu-8r01Gj3p_ zN}{)?tUuLGj%%=>KtoNBG=jC9TL}tw!$4PnDw#o2Fxs-0ikGp)$HTUDc?!IL^}dW)UknH0Vj<@7(&j4_3vzS&MS@41>qkN{ zFalW|HGo8gC;Y;6&!wp&Mj73o zOC&frr0`=p+%65-)+Wnr#0`y6qa1M?0472RqlJ_JO5CC%oLRpc zMqloX*K!xETRCa#csVaUvHLS98$z06huOjlukCh*hoXBf>js-L$h5f zG#>4M6b{k{Jt&H0h2lp>-X2s-<3RAQK-w!?oZjBZ&xyanBKmGK!{fxXKy(@#jYiUJ zYKT^u2}}%eu-AymguzYhCwtqrKAV(Ia3tx*oL@r5N{V;yyjN3a@X%X&s8js-*3Y~m zt;9TKY!ei#30d8Td5}$3<(iWpVMt+!XoxQgK@I(&6c~;cait7iBi>30DsLOia-&Fu z4}JxL%FoBw+^*5jD%cMh?im@E(9NnA;4M0Cg&wV*jBnhFdNIfGwRT1l_NqA@ycH}- zoLCZ-iVz8pBXSeye;8FL_=_yiuRAh@kP(HnJxHvQ^-<9hgYAHztM{Z)6Ki=C5nL}f z$P=x}(S%=3vk%I@I|I%yloAe>K(_x8;14?59S%2QJJc_*Whs6@A&3hTrMvTLE;weM-Qf+(wqzBn|2sYy&j$*Bi%1m;GlAdLZfpvh|62qvSGe88ie zgxlX88V)n;P|I^gvmjxp6CoMSm!EcINCqwz4$cQc$#jMajcq|lm7F(PQq(g-z7YaC z8jruBS&jf>R@PpvK;g{7N6$Fv1hJM^$_j^!+{+B<=XG0+kmc5nOFF5_51M#}PWqHU zYHMX)4TrFz_|+Rpj%9FHOzzQKu6IZ)k_M#J7@K7SvgC~;(W>t;evDqWi5Y95hG&tjC4WI&FSUcg&Ec2P-l5_&B>sz>RA zq6Viz6_A5`*o8$krxKAvF*qEfMPA3vc#oNO*$4xTr`M-{No*LCd>oW_G{9!+UK894Ds zv2tLt`ZW=jACBgIAac+?rcx5@=+`}lse0r6rue#7b&@dBZfRD~B3Stn8Oaah8mLGZ z)rzZo3X1M(@UPTazR=|QsI*}me8%v*`NkxH^CD-nScJk26wv$Kbi>*T0jHXxcgM^; ze0~^MVD``==zChBmNa);HIgKO(0R_%dZwjvX>^(dx&t>hsp)(AlhWd2mQdlEA;1YCVpV!(q8W+;f24$rWn6{A#KGfL z59{^s|Ku*V&;*rMu0z561c6G)0G$yZ-QM4(H*#TTpC(y>>Z5dTTyWGShS48fL%0>% zol=BoseM7V!apL2iZn~qYswjqZ5<&A(I;sv=Hq3sNMEu4SgW~#f}aFLoMLna6&CfH z2>m@y)@69?Xb-cOTG#7w$e4%R%|C;<-Sr3+!FaW?!<8pC7yWS{`T~V*hSIl+@kxHT zacbfk%RvbU=DzEXLan}t1(OJG2(6^wiK(6xfW;L0(^1x@7LFNf3T~aE8@DZ7KItM> zdk{t0Z!-hnX{uznA|JaZTHJM@+ZPMoM<%tihkCmKLU{ewAcsN0U@E8#j!F)-lrr=!HuuthM@e4r|Rx!G(HQo8Cb7Y{|OAuBSBS=WX{+1B1f|#8kYfo*krAdZi{hQ)Irkf<& zuwMHxH!YJ(XK=r?OBww<-9zMxsiQdDaziDT53F?G^MuMxT*1mR+tG*$tg=ri8>c9h zhmivH40BEE3Y(B(n6L<*kdDnf=1z|!bv7Z2sFW13n$H&=qqr#6>V0>M8Ob<}T)xzW z-S>LeL&L)M__3?7OK~YEtE%_&l!PzbaUAbSiNr|35M@VH<7^blw5W&-fvvJEzF^ zV)lYv*oLN7L+wt+=iz%;CuC_=V~UKBbw=*FNktn%7Ou_FTehtdjZlWs@&rz!V~U>28M<6A)su5_hRW0#9Q<;g66!#$R|R%*{GQ$#4n{kNggW(ZdQ>` zkYBVp`|*|+KPl=MJcPi8kUz6*!gM@Bv8FwMQhiPiDB9G$hIS|I40aHenahmuH#N~h zN;CT7YAM1lVv4hm)malk;yB@pvUC(O6cC!a0l~hC9D&4ICl4c2{@kjG`p8x%e6cIY z;AkrrJbA_}kP$q%>rT4N!7#g7NO3jJBW&T?Bql8rfs$rua|VS#%GCKeUU5$VN8o2G zjHTDOQDa}>oT0<$trtrp0sGg*Aky}A^DS^Vhr(Blj;U{4GjPi{eZ(`Eagq@(4*~O0 zy&Zk}{iOH9lUvjcsM2U#J2Pir=^HqpIty(JsmxRG*Q1kS1s+B=o;U+*^u6f8Nt)Rj zd-dB)B-Bivjqt-94;)oG(QUUyVSHneSAjORCm4v7Rz?fGxt%M56jn$U{ToC&^(|gdXq-BrG<#ko<|J;GL z!Bu`wLs=O!LPx(M>R0p#G+m0~AbhW>1caDwpQKqI#7$>vMTqai5pKuv%Vszd`o6`U z_dT2}Bfusw9>S>d)R(Z=iJT%BXB!M^kMJECU!0A6Vii4`Se)XBW^2y)In#f|bH6vr zr5O~ut!>X;5{YEUNX@wzC!ZZwY^(+k?rXZ?&2>;xyJKA>ak{o~o4Lg6C<)~tW8oxV zK2WW!pm|gGYCD#fRU|ER>{h&NekhNsp^?9gzM5Fe=PFy5y^|5tYW^4v%Dk-cEpJH< z@sovQv~>cW$-pQL2plxF3E<6zij07-h+sUz26XZz$cn+Rsj9yC8?x<7e*x>^Cz?3n zWD;J3fzO8}=<$0+60+em@c;o`OQSR`-TAxf{c)u&t$h=(452$Eu}smHLj@=58ynlM4}CNp$G zm=RlsCJHOnO{}q$%oT`!g*4CHjst!Vr!-9^vXyMFGF9Lj6E^PR$O|usV+;>n`BA}A zo^EN`%7pW{P@zxKb{*v3k=dw%NWpONdG) zwuWGp6^wXoT90aZcJ{%j%lfJne)UEzeM4!g;TV^T5tu=eT?_KGilewgkb8R@`IG$b zCMilxU1j3SC#?H&Rx@;0?Ss?#i1j_Tz3S#diA%qQ05&!>zH+BVZ!5tls}(UQ)pr7c zZQn_oAC_^R>i~Whb|54+K0$3?{7v&Gj675$EbF%AV~JVqa^+mi27i*(4$GK0i9-LD zH8x+*DMAh`nd@b50a1605pxBPU$XV$DhC7_OHhQhHjEyAO&Z|>?JT!(Fi}y^t$V4z-3cDRXD;}SPN6sLN)m+7iWC<#7MlJOG95JFK^;>k5P>4 zz!-e0L%p!!EUsnhqivQPRdB*W zid%?Wd_GDh^!3|KMh`5Yi?HWdsSH)XvKC5h*vPNI1|fLdW0mYEpOO2N?GF^X7=|&EJ)a=Y@y0~ibP(}4 z&pn#g^sf*SHB!o2FCEpOdy(@GwT6h^Oj2kXp_#wd<>GRz-&%g-F zd6jHoJ(12(BA(dfG1BmrwFI5P0F?=RNTIptc4m|J#Xt z{>`)fjKgR!c+r6GIy5D{Xe--WSmojMeO-(QUkn^zk)iLdWg>&rK1!BC(%w6t*^uti z@Vz^eUVufg@1eq9Vr%;1iq8Kq965UvfuEGZ#oSqW?VL&QTP&{b30fSq4qaQ%uwqNB zcWUPd!PC6LN$6Cnx#$B!(xOPOD+)~&8PWWbkG<1wfC@EQ4Z$k1#}|xklva=a3{Of} z=)Jf+Az~6@WKuO-`t2zLty*b?sVDx>&jO@kE4!_VYMqvk(f{x`PI2?kh{zvf-t#+i zT3995wW^{-6iw8CwgCP+D_DQFbm=dX+HFF;q)SaB5_EbOy%C#LS1L4lr;UfQevss7 z%-fx(KFUG3W5=KUQC8b?0~W~?sB7&EXd#qcc`J&1As{1SBFYk*F2r!Xj0eHA;Whk* zB6d_$M6gY7hHmm?y%3l^-F9TPqUz^we_QI7y2*Hz?I=^AN=?`@zAFEmG)$J>Qei`2 z@Q7?Rqvcfj=?+7yq9vQ?M~o&)fQhTiR3twZPm+MCuZMQ9oPpa!2}L7In^Z4!R`JlD zY(UFbFj(Y_uPKE)d!TYvbQ&p>qQYt#X;y?$NIwD7bjpG!36cT#<5EeS(4(UMBD+wTLymKA~F+uUw4l zTTT%w{S`fH0FyReEAY0s=rW={A$#uChzzfCY0iwQzAu>Zk40h@!`j>u@TNOT;L|Jk z=BE9QZ-R93vmUz~k6sva)x-?X9A+}3vWMFLSRxre!jV?mTwOm;a zl<4?2^(|BltWBLH8{6c#RMa>BZXeQm2H(W1+6X->UD}f5HnOTI!f#D#nD_d%CVArO z@JHJvqs?`+onNoRadW9!6l4>rMihEeqDB;H)4PTYbFr~z7k?8_(@)kVC?u|Gsp=Qr zccTD-*$#Mxr`w(HAX3XMy_YF{P&uzvGA!Fl$;;R3$`FO@^F$sY;Qbv%PPe6zA+MHL z?N&Nb*R{2j&j!|oEkTLq2^}>ic+-ua)O@_jOSi79^FuAVuo<#!Lgt)O1vYKVukh+q zmz{Kx&-GX8B({@RWxDx=j&e2s@_VDQPL1U!6{-1J;-&L6$~dY-1cj6aA;S;Lh?Po{q^mILtV^3uaZyvcS`w^G7C zP!AG0ul^E**hQ_sD0-vdtu8V9{H}f}o`aWb$@Ns}*EUyxOrvy5>Q(MXM-ON~QR9@! z$;}PdeA<9if1WGhER9bS*b~NFyBS3(7buxdP%`EBf(t5#I%%L+Lsiak&$Enq%0y7F zTPU$Q<~{mB5mFsp?)2GNSv~75&#LZZ0!6Q1ojR(tzlJwkEG1$wjjDaDQbA;P$il@t zoX(;`^ouj0Zq`En_|eIal%f-X9JmII-$xB5$$0NSz@lssm5!E%=eG) zAYJOC&pefmE|1M%UBY9|>XgjikCzZ!jAGA@m5vYq0w^xLakj+D=6HZ=bQiRETMgwS zY5)cl-mh~Bp&J>4EjL`G-Jv07g zHI@^jJVsETKu;>jI2G|e>+`sT{%id#xp?}kX#u@Hm&_oq<7nowMx5D&ui@dd%U_hm z5-`bxGPS>oY{A!n>Q`p|7-fzFom}hw^{&rYi+}eN zaX!W1=_8@$i^0i?wE?R9<(?z=v{O&S=cj=hKd0zP!4TS4hS(}_Djqmmub@EX_%#ctafI)vgrOFsVN5GC^_aGqlP0@Mcfyk7`(N94BT)| z{j1Ezhko!!4{xgJzJ1bpRH|NUt0y`+VynMq;%4$BPqP^ZnD%o%dH^OEW$nEaNJT|S zBIS8{L-&nqEhp!&)^>QE19OS~G1s3H4JXej#s!Fy)lFX7rUf^Yi2`aszy@XP**>5{ zsXd{DIMCu?nf%9lHbJsL4_sX3j{v)Y8_Lvw%U_|ZzBCgn?yZGn==uGpV5Ym;q6Lfx zhlH$yo~XGHAU388LS@(v!c-?K#A;14Lr>`6H)(q|39QSv##+|z(v*SK)&Z@xrgy=t zv_Z{^Ot7t6ar--Q@dy0J6SA0TfXCw~6SnTm*p0dOChX(QK4)sBUx9O3Lazi;UiD15W6va0Xf?)xusbCYS_ z*fQMaPfjeGCJSzT&I!tb7V=#!8zlisJ*QCJKm<)CFjY;KWK(T{+s|25SrB^8peUnc z&17Ti*%`F(Z)b!oY%ca3+>dvnIwzV3miWN4(6hJ{6%Gu2Q>nB)_ihLI$D|-s6Fv(* z;}y7g*fF$${b%5WY2N5EK>az9Z1TJT8##IqgjO*hK#dw*3~5x1X!oD{+eg4uk+EG0 zcgvjw{tUSOCx~9>62)I;@@`Kz0W9*UK9<&_Nk{$X2|)DIzk&uRVpF0&{E5bvNNYU{r`EZ;Xeh-Xoy{j`XxgspS?R=(5yGQItjAjZUnkPVxl_wnDB^92t{5%5NYSwV@HOB+ zmoRnHGnsxS_YQ4{=jG?*i1ZYBdLrDM{@HO+4d^)n{_8qXm$gIbmR;gv>hq`(5qYV4 z^FIHhH-q~XD2A;YXv22cvU7g`RiXDBfL+jK3qqL*nZI$7I^(Ju&~tM0ml`y=fNM#{ z(IRVmW-IiwxV+z+!}sN^e={zDX6(G+mIw4^f-tH?#OQjgJX+ZviTyi{W!@!<%>FlV zK%5J+aN;oD&s{_jT9aa)bn;*my^HnuZkYd6X9phfy(oA>9+kY^ifFXtbo`9Nizmpl^l$$~tW2QDF}^$dd2U14SBRIlgE$Xt z`QP}%Gk*>WIF#eYz0HwG07f!y&AHS`)JIx*ciNaDpKY13rPEV@xayMii0i`z38f#=MM9uJcu$=m;MR=jQc-UI;2+aKbaB$3h&cnsP zI6|25Mk41{{I18cnf8X<&yf_V)N`fEvU7+oSp7$a$&`5H`rmfo9Y5_u(&%R-dop!z~QXS>(&KgzMB zqs>4m5La@1eqjF>BBF_x>gzrQ$hr6!9f8T^eES;`v$&OPxrB8W-wv;z|51(=OOVsp z>_Ke)kN%lHC^1#t%~$3BnVz%x(?_#_cM>^xqf)H&Q zT$9-nA}!FCIu;DD`d{6FA9bUv2;yWMj>t4}&R%|bzD5BC#lNAhci~{$BR7(rbm_Hf z?q5~OvNUZG_Z6SC;TrkmzJUEV1`tiozCP7!;{Nt&hiEmU*6kGNaQ}(Hz)0zZE#n4u z8^GeCc|*E>^5gOuJ@!1{Z-=iD`WP}meheADsacY@2)6=bUtQN0Fh*ydFBPW_5zEhY>)EYl0jk`a&!pt=&-?oM4O1s)e%q0 z_1#bh7fEMVMcIEKHWq%;KmoacwuI<`p07D)*CF)1T1aMI)k6dn%AcXNWPIo&44)iw z)coS!G|pHa7j){EE{h0kw}y#g!|{|?oM+e7Onn^#uGzLGvVF!M2j53sY%}HJQly0lk?aCA$D@?~7Xn&=SZovUA z!^nU#MX&7bQpv3C^g||jQ;sCi3`^{Tf3vYaH zPmZ|HgAo1rfZ6G)tv8C0?FzzI7Q0jb>K^qM^X`{!JbFRG zhTw`m5c@$(;wn`Qn-z|i$zEQpK#Q8gvoV{LxPg(ikX)0a&PpPNZZqb~1TNF-q4e_@ zKIUH`kZNiqA_!!Ywa|?RmaYIbX+reK-%{@xoPk{Yr*!(7Sl#-Fom~MI={wJ+oEbTv z5}>02d3(-rR44<1I-RR9_%J@lR<8DnOnW&+j^H9Q^@0%->XpUu@qLr;4EGE5&GQR6qu|yoL2iV#8+C;Ex`_zUwyPa)noewhtW+jRq)p1o+LQK z;OPUz*82Ga#OB~JAh3N^d&x<@+j!|sOT6@y_Y5c}c6~>v{#2INVI%m+YS12}^y2ji zG`5321QhqsMT5+G1X@yRe5IxwFgilKTQF|9W`Mat?SO@))pE_&j$%+x{$uV{+=$mW zsnm!n29wDNBbse@TFYUlb97hC%E{gHF*BtksJJ@&H)^)U%9hh?yCP%Z^M;VO870xs z*$H`fwF!=6t4X9TB`%-f^HoT!;K|I!>7Slch=*4Q99SxJHU{`s8TS#08soagjfePU z3BU)|Hw-vF`yB$ch4CJUyN#OE)LTuS#x!M{>Wy3c0eterEG|m~R~DPtza^-*ql%xf zZ{d99mCK=Z7`P#m>ynr9@uyBoT=mmKN$dz^5U@-2#w=D$0+w4$$GZGdWTGM5I-D+@ z-{LS_%&a*NgkP|9!OefWq}Qisf*BnVQFLxjCd}|A{I9Ky==SJ2;AD|SO5WNh9bE7f z-Jf6gaCvSnTCOL0?r(8|w0ad>tuATnf#^qjuJ2`c)~Vh+Y+m^vU@n$hS{cOIr*zwH z?ZGzzs=EW=v;XnISvypgK8Bp%fv0sp^e%SJCD()Sm!eJBg&yLMfxcmEu@O>p@sbhQ zbYZh(?)K+mvw|DotmFeIHqIh{5UP7$$0qJF0)g_dN5#kH1q}5cB5G4Q=~oV5pJVB> zslr+nk~Zyl!9FRBaRDOj_?Z~3Gm(Hh`LS=m?u5IIF6mKuQ39jaUt$qS377go)Ufhp z&F($K5)WF&-~W{?o18jx4dPpE9}DIMezATC0G$%35qjL)QC1S*z2j5NhlsPH(>*=B z*rG$enBY%F%j@SA5YYqG;>hn~8}Hoq$)qy739#9JFT(#Gh6Wr$%`2B5Y$SOW62wP1 zBs?=;DE}pXF}>W&j45O68sxKcx5a#o&OaidUGM=*1&)tO4BO8lw})qJ%9!k|o?KD| zRCj{`>Z#>#?8q%H?%0)0hSwkTu>Y!q@L+!~02+0A~VY=kJ)w?Idfl%joVLGqOT>Dp+!1>QR#K%}>dcgTa$cY8? zGcUm%$sdRl;B-m@Sn44BZNqs=G!^+vc+1N}UohZ{;a?N}VpxtxspotfI*Yp!gg9R_ zaFh1Ivd+9mNm>jOVO_s5PX}_mdtbVMGO!l$)D!;CQ;7w<=z0?!{3qi;4FlnUznKL0 z6rZ7g+$$fRx4#VkHC5Hy)lsj=K^@@C^aI*S;){#}ugCkzhSloibKA6Tc2Yx2#MI^hCv!}qJgP3v|YRp@tmQ? z*=FmDYZM<1bBuU$Y^odLq7oer|M_#sx||%gG%veV!P|D2=kKhQ94#KdM*0MvR1Ca! z1SqeG?SjwJ*pOWkA|{?Lc6Z6?(!=yY~vv~)1c?MqbO#q#K zlG98cqNxJL`TfqTet1?MO>vLVaQVP1cdy!MD!`(Bk}K-RD0(xsLk4YX}En%f&H(l6VEW2*?9b zas3JKVa=B_tDe_$rN_@0REdn(stOS~nXl%M$95Lal5cS~aHB1x7Vv*w;u&o_J&a$> zGW~+-;HI$qJSL@s0B}H0?BY~b*J64Dma1bUS55P=fQqg_CkLE7)bF)vFC|&V%gh7U z8g>f%ogs_4zPFhETCJFK270hhWh{DrWesK4Tp7n%*VZ`ZTq`fFo&*hfEUz}}H}MH@ z^OUJ(=PkRIQat7#E!FV+EiehnrDl6zcB2@vF4CMwQ9Z;%kpO>1ctCHAFCHuFSzlDqo{m>UH#?!Jy0u1%C+3)HfGraV_jqtjcEK#ZAa5?Y{ zP7Z@f5F_qk6!*Z-TLHO9F&JyimdL}Jd87o#Or+1f;i`Wl)mD{l_c-6hg4fLO55CeD zJ^Gj5a8CRMB{+e4YHJuBHcWvsb?3nfew=YB9k{d%1!wbW>kRK7aAF0G7va5W-&cW6DQvb zV>(8k!j}=t3>7wok0sF@dlkcWuz4cBvMC$N9T`WwJ|F4_4t6EsHUt@LnGNf*Ix%$2 z#F~IBKR>uJOeGo4{Q^!MB&zM2ud{8rGsOQYAvmsMKe9<{v*2G%!4_M(m2Ws4kg-5`NTR+e=(By*3 z9T%b93y3DF@LaT&pOF7@t7e=ZalDXvd?ZZk%FypPhL4XD&~?Jn6*~1H?=J@Bf1Cs$ zRc&&vv*y$qX_YL1dkOtz5n>*}HCT^C2*6prnk#OBr}@`Jw13~wrdn3byY;JO5@5(}L@Ew>GPe6*7JUJ} zUG1v|e@R33v#|Zj zcR8E(SLc?C^CdH7>WaVMR2}xyiGJ3C%*+0jH63!p+;#F6Fv|bE$lDvP*z@e@sLRuay4zR5hWgDxX-#+jus#SDGyh2z{`kj-b-~GH zMVJA%ZT@!ro7E6F#s0_Q)Q2j<-&Orp8l)p~7p&*F>74n&tU>=;EK?r`J4FBdqRb^; zDRAwd6WF100?G~#1tC=@Cw;Jrjaph_lyu9?bSEu=D`)?9e!6s1S~={0XhW0B(6O}H zas;y)H55Pk?fp6-1bKi)b1qrgcG{nuulVy*&|!uD^|G~^Z#9V8bIcF8f;FFgzJue} z70#rBbK{%vD7YC+UrWJRMMJgcFz*rqO!I1hhb(Yy78Xd1EDL5wchmjI|KxcG+@rJP zj_9#dQjn;wn3|~zdFmg%&?z*`fnx&U;GE=`g|Z}=lI17Lzy4=M`CYkO_&UCS8Kh^q zZPI*+>Z)Vl=5+5-m-Vw>h;a*it2L#+fR_QDDK}sPJX7wo_ceFyNpMmcX z_ooJ)J?pZi1k}7G9KG78STAYPfp5>KT-c%t!HZZvFZQlZJlg2&L|Cl#+UNv(_^`PB zVLsG(E2nGxf|=`b44hmdYbpw(!>@)Yc0Uii6}NCST88;)(~b$Cm72G~Q4V=RFz(&lRpSAe|;XmS5!! z8>n2&#&@)8sULQukD`7-;8ERqfAPJX^{|}RuvdgzJnIbjvyqd+{c``-W$^E@awg`# zxG6foPz?bodGOnZm)A$msGv2Q0brvBHH-oWL%!f2nHDuK<(XuKcH>O9B z7St@#>_x6f{vQD0FMYubUe!c2)hpUlb;ukYap+M?G@MQs-Kx4QURXR(I%m2yt=#St2e8h!uxAjLTFoiuOEmA?-Ka7#1hD>P#fWjBACY%Kmu7 z$~L7EPHT207ksJ%B>aMeLCKnGqyCW}0%5Tdn0W#D+ZmfAwfFUVUAg7N!9OR@f=PvRs(Ac*7*ZL;J)%-R*frMEM<5fL&5p#NfoyTut&4C5w$ z+i7N8U*Tgl{>Yq>x!b<3Sy)sL{_VzTxY0=uRS@=p5%$TDGTr;kd3c4+;;mgkN$4j#Qf7d5XDKJuez zy*<4X(=MOtotrpRO(gcD(ompB*Mj;nO@nted|RAj&!n8m4Izwhh^ZWCq|kz6>x2xY zT}8en@B?X#18#Z&pxOY3BDIa;KH_(S5z!JB5DwuD6SCxhP88?fL$365G1--Sgbg2< zgj^Fdn&!g){P_A5_E|SX;_N)O6`$6~$N)m+&!DXT;0CjA9a0+teul&p_^yOM4#k)1 zK2c&&Y8o_q7LJWC?(}=Npz0n!;)ODDVQP1RE@=1s{1d=X9zm6<7g%(Sp%IXjj2kM` zW!!!70tujGuP>hC! z>G<Jc*(ggLecA|{4t z>9+}3I!M@|rXa-i6(f_Q8-x&kfeOR;v{X9b-DgL!TQC z7Pq~l&HbVVJW1=oI~RTuxrlrSeMoK-k<1Di&fkpH8=YZgTNKOY(JJXNPt5$fK91zsM z$VBoCG+3GYn>Ln1=C9j;3RM$Ja;-jPZyo-IZp6bWmNeKRiqNRHZ#Fpy8 z+IMZc3Zxjn`C$QE)%(fkDH=uvSda#3>2YfQ=wv6Ae$fyu>JaD9q`hYKx}E6 zD;uNlEcrvmcZBG*_4k(n!oJ!4%e0o_Q5oM`eNt7!+8O*{+6*Uh^@!Pl=jT(MXMq$U)nZXK6p@P%uz~|2U<9 z_e~NA2f5>UOG^|wo};!+G=N84qM20fvuTTB7W&DPs>U}O2=`DVVWfqFWoARcR3FR! zNde8dy+Tts%EZuCNLcHaH0*_xFN5@jdOE;#{fl8?uRJW@Xul!9K&vKIx}z1HxV@+X4Ii?|tK{RItBklo&YC9;3w< zqZ!Qx(cmITapK9q?Ya7=NNEki>!{`w`c;~H?QH5190h8*(h5O(x_dF;|1dqMvqV`E zL!HVq1f8(P>DtutlhB+f^f#bUmBC7~KpKokDKm1U5t?US5J+eE_AT}sfwTE69Y{`JN>ZSLTF|q3xEmyi& zEhlU?>(h)N4jTbIio`D_5mH%(*j1_6owi<9gHiB-p9b|ce2|)s$*tf+#!GCqi&7|N zSQRC^DJ0^b@l;pOcavdOx`w#2K#0K2D9-NhO2Um)(ODeJyH;ES#Ib-y3o5jpN6e zQ|JwCZ{5bts?4R=8^Ngzh!ls>$)YH=kcvQp2j4Vgbxv>(BV@imZ_TAZF|aFwIFeK3iL0KZn>`f%({Ws@kz-l_U{ z%Z9)Bk;Ibl^ldIke*1>#ki>F53W*5LQIut(JD$&};^#0qB(CBY-FM8#zH*N0bf7}r zC*^k+lo~}LJlKo>ClU;n*yuSQ9UWWsL6!3>!J8Ynm9PmGKG`WP?)$}Q-`(_zN7S=f_`;?`A_w*Iy0|&5pxEc3f|?GbEdr|KsbdEf`;Z+}t#d}4mB^ERf|Tycp*@0? zVY#BUEiGtCWo1k?O^>zJ;laUxPuRe*Ybq8=iVa1@!7-&q70$M2iE6J~oFU+d8KaxC58(r$S)5YdMM88$%#zvev zbUX{=o*6XA$QRA4L`iDfGj|^b(Z16*L)Q<2VGCVUu<;wMJbjBRkjW~3<5rL!^qYML*dKwhFV6f>4F~xoc=`Ey0kop>YU^g z{ie#nE&nbYml~Xh)bAOIY#CM1sf3y)i{LdI-uP1P3&R5m>fk4c4eP>8^9$AXPn-%N$=rCyT+4N|6DGyzvH8y+fyPpcHhCl6c4Lcf zR=yPFU+)%W^DOqa+smcu09H~)ifFf=vTe+pnnM@&%9dh% zQak-Q5lmONdN51OxD^+o4WLH15g>-%zAB0#KC`?(qL9By=!*8o0iJP2s#xnckznCx zIgGQNTn=<%sem6v2gtB)O5eB*6xgJlv0u9H5-g@5ZrI$FGZJ>b3Amx@#Zooq;uHLd zo`FUM$QoG~$j6C=K)tDMNjtl(Nq8NTwhLD~)54%-6{h=<(s6;`9XQ4wYvZnE4RNPb z6rJ+H{s0X(DD)K*WOV6?FHF8GN-R=K{}CB$nTzb(Uv*NyU#sX|3E)Zb%S`&=R6Z+91%=T!M!67B7VL3g~lc zAI=g}o|}Py4_DySFyD}NZqvCIS<{>0q)ik+D8^%OJ5!54?uGvSD(qkCzv0kgnX!H@ znj%cXN`u1l%7TZ>K-19)9+n3YS}(yXijXx30`Yo>kDvxc1yZud)C!KW6I;S!g*#Qc zMNrrb9ewB-#R!AuCK~sO4>t}C;k*`OM6${`Sczg|K?9e>*ie0scmBglQ=*k;aDntwUPePj?W+1P>RZ zJYy__l~qTEX(weJEQwysCLZGH&!&E+qXYyrsVIh6q=mCS42@5P+jY&1Acx%1c?5G~ z&9Ogr%ko{59SSdF`dq}h!X?I0m;k;kiSI(;Dm;B-3REH9K*r#sFl zP-i!$qxW_^j|QCE?Ys=Xg1fHavem{7OB(0hYTn^|BcTNqE~1tfa|dIWusFk)^9j#| zlC}@ELLU<}r5S9-0U5Y@gh|Lm#h6P~T6H2Z-hi~-`Z;QULF_t*TSXeR*t0P||4lR& znjLh=TK5!|02SZ=9Fh-pm(I0}EjUpMJp2!7*-xp&A}I6BjoaQ~oE|d7iuNY~Xyb)( zHYJdpLE=VIO$j_s|C$}rpTVOm4A5p%rJK0vJvRr@KUOL&s;H(Wqhz_O{l3U!W{tRO*I?JB3Yb5QI z!_z>^j5@;u?zfbo9s4Vj^@%i99!~&Pw+6Av7$MWfxJ?iA&2!Dd{5Z4GUSH6-H>(is zMfy{~O_hs0ME#zzbqgm>P^OI5k%S= zTW#&$GYrPQkRq-XYoWE!nv1Pj%#O$CtFfKG`q?ra?7gHm^d~L4Kn!-zIU<5cQ9B7vz@2Y z-$hL28nmSxwK-5q9=RyZr6V-8Xj?-vnJjS0Y5C=tRr(5Nc{$EVvS3YC`tT=NU>XJD zNzdi*sKB3=3Bpd<_2luAS+|H@Y-Ai0BvKqgI!2;&z9F>=PqOvM)4I%kM%>c2WkXhk z69+kLE$Iz8<+oq~F*?R2io0oHOor+{bj*-}WU#{K+52uftZ68e9^f|7pS7-*Duj26 zyQk+>YEFVUa1Lfz?oWakPmr*&duRLyLK+8~^4x~56+{5mz*Q==rA#4!L#`WC>KQ%c z3Te(aRmG}i2Pa%a%3lx0RE^kDTFR;^)a>0i4$+6)WC^`WE?zXoE{GOQ9DJu-*ayDB@5ZxkC}G+}GrIbff70?HN*kk+oT-TE zL!=74f5V{PN;I;xYWE8y*2%#(N;Qz(;$_sehEZ%lF_-`1QWJ|)GpsFo(v*b6v#Lq` z(>{6drI2#z>zN&XMYB}E!is1{{YnJKlVWj%fHL`#QE%!E%J*B<3fet!+iS-x)xJjG z_3rI`#6AwwO)ucz%omk7RYqmU10Xt2E-|f>#8@j%q^>>gW-xm65*v4Ukv|Y@V4df! zcLg%3NizB7h^VV5RSjjS-#@L|XXDrhh>fyKh}d3o{Yvo-#PTX(e_$16OT@C{6Z{d# z_JiW*x&a07Z~+j((97n-h$-0+0W@(_cqau}rZp_P1~1r=BD_uhEv_p2Pkab1L78&_ z2D#*7PGxG(BuYj)V6}M0=?6;tc~-O;W{`@z@QwB7Mn6!#JG&lZHMPr^}V*3-*F3Y7a}eT8o(?B%IInW2$wH>KlLtY=(lX8u%G zdz?bx4JbSkGODdwuTJhNeWK&Ij(hw+elr z$V|q%sDBbL+Y5qtkJ17X)yTO`!?N`A{}lF}VNG;fxY9(Ts3=WP2q?V;2tG|OIEtd^o7*l~eC-KIE4D5Yj9sqd^}r!_Xz;2Q%&C*V{LJWI17G_oBoTqI{$A!WeZ&;g&^@WebS*Dmo(* z>g`xlF8{jQO5CqVc!%zH!}45VrHs)#MaNo}d)ua?s5vVoeqEUv0rj&U&$X$@P9}*(>Yz!n=U27<7-&Hj74x)ra$xl=+NmSB`GGhCvFQ)4hl zB_>I=mhB0uU*xCzhBR;iZW5wYl93Vn*Bq~9>4@y^ zNrIb910Rr3E8dk`ve*eJsnZX*p?t%sDR>9&P~Hrat>7)i+FP$$wW`TPLK)lf2%kh^s-=bu25*` zp`rDye+0%<>GarP{5^>EuAk?1olw>ENS8My(qI+MXHivGx++-)D}cz^i+U7U`&Wmh<6n1#^nSO> zXtuJ@3WnNDmZ_R5`9;dDeCwwW@Q=+$E4>~4JU2*homm7)UsiY**{3QNzt|bFyZIcG z1ouhn%S!3y&!krL&bApjisE2Vq%)y-_<&0=9+zq9RyqWR6UIOjP(Y_#&rExhF&^W< z63S|3txp%9<$IT*-=Dc&`5Jk@{a{B4#QNEqJTx;}@!jE)J`9qc!gRdmv;q7-AG+lP z@g@zWdrz z5r!`L$mnlIt`U`z^mC6xp$-=9gx1(1*CXjz(U~&ou8)bP8p^Q>GiAdUt7`R2i%Yzq zRbC;|y(~A<`n-K!s5^4V&u!&d81g#s613;vj$Pr7es%lKE&Ek%wA8iQ>Bbc$c)XH* zqN*Xdxo4KA(jDbnk_n1J@~3G|VME$6bp1aL_KlW|{GtsDuc6t8duGKdotIzwq)*=I z^iVL5V1~-HVVL@RzPD&w%FuZ;XUF)jr^z){anbG?4av}%Lm)yOMweyj%weA;v^9ma zP)=xEZ~@&)0Hvy|VH!)=0K}XlxR#FR)^d!jS?G}4wc+ftyhzT%>u{WMKjz{^X@c^b z1>8tmDEMX0UY>iR{ncj7K(I{Y8``(*-PcW6mUf8+EvS;er{vwD%!{M)pY~}Nkmc_# zF4Ihw)|CNiw2Lael+}0V0CU?4ldL1tGao{VCA9Md^>sL7GxKDrat(9~K?v~DBi~Dr zpNrqkM6#5ifPQ1_@7g=J%W=5orgBemSE?~(8%+ZLTaDbW<09+bC_V0fe!=5D%qsi zG4&I)E|H1EvK4Zx+?1LOm5iFi{xiIC6!0iFMp<^HRU9P&cTu;NPwmXO3I$KJn5b-o z>M9Xckw~SRw$J8F5}bl8Mog!5CuMA$Gc^pOo_9evD71vRk;55yCvn!;2d>6!OlCnq zW5;0wvlEvyRd7JTSTHwXGluj-0AHtjFEclfvvTm`vN3ZWukRSEvI}oI5676tc%5Gc zv)7J^@p|oJS}WVg+T0hJUxA&=gD?4fy~ejrjbS{*twbcQ$%e_Seq|Ko!X(zWwYH6) zV-CG71`1dXUzP?($rZab;A|2M7(&Q$veg@LUlOXgLKX_M*_v>&iJ~GQ?d93WO}Gz< zRdONOb=hA&;h0{FYKH_iXBRZ%!e3V*LiD?`{abJcl*cEWQyOdeG)4CcW}$FwH8j0w=m3;!6jY zOfIT1Uu1^r`l{6Wx0pp`oA*8R68J4b$EBCCs$kyGIS5xAY;RLjNv)CFLSNGnDPD?Z zpNp(bl_8H8q%NG+?Ur{(2MA9}^#O29RJh`3 zXpPYY!ln}D?t8NHwpB-5=Q-Kq?zgK>rJ!^DX$A*;u)@k3*gC%xs7;(HNF5{CAXCQu zeR$?lc@r*GFb}}N1U$k3IGFQronJXq#}>&Jk1ZUX_}U%1T4^m;Z#clQbu$dcc%%#= z+~nryi;_99kaaXm>}&n}T(G;M&!b`ee`mU_N3-b#|5_nJX zTfIpv*LJRS9vYz%yKoDki`=#BXBaJxi%nb7KHs{hCo1?2O=>OU9{HTW7?dITfp&%u z_jSNTUwH$nOG5c`Hcg(c^5N_A;&3Y{ZNY@4TfNeGlQB{@tB%-9fY#2Opv@Mg+(8+@ zA-CVkTPl_bBOl_7in~>L%w~OeQ77HA{RE}75V==NG}S#D^Q_}3mNlmzpm5#X#4AQ)tgU`5i#x#`5yIcverMgZ zz&MP>H_5TZwnlTPm}u{vb~*H}Ev$^*w(GZ_;e_hkvnPvEwREsE6D8)0ccTpDljsfI z?V3lfNo&$9>R7v;S|$Yk4FHPnFVerNtI}Zf%C6FwAcHr#PZbrL>-2X&bsNL)rII z#4teJ!6VR!;Z1_%m#S4rb5|JkP60C@mCpz*|Ak&sr7h3i)gSQuZiWf@c|7oj3qmel zEur7)%~H%NMe}F)c5J?}#Qg;$(YdHpI}cB1q{_OU!Fxa|?)FxRziv`M^ny44=Hm=z zD%o53i$JSezth;}9r{>v!KtPkaS|9pI4O~ICk>;ns#|EXjJQ(^h?}J8N3$(QIL%1@ zAQ8`}NwBH{J`3&FHqN@z036W19KCPs*zOtTsxrlyo_H0cGWnMJ0O}f-U-lK?(4GRP z=q{-b6te2sz83a1dT}NLky8m@m+BC4vn#3wSUIPy-laYIscH;TROiq?EgNTQgIE+} ztdNusXE8jtK*dOv%5_!8w*Yk9`)SOC^B|@Shf<3dy5~ARFnS7d0;$aY;=8nKM-j4B znbYB^nQ(?%dxDGIriO{q2lcg3@U^O(1c%R#X6uvaCA=rok*H|MGJWj2HImdL1f zILp3-HD}N5t-2i^LtERDs@+{3_2X0AC3Rf+YqP0)EjV(|@{Gr($2t+Gk*%q-lk@Xf zrRxw0u@N8s#?onCs-(u0wZCZtSv)N{^jP@13U=5(v3yh8mV-l%e5HPI*5qVP8E721 z5IU+AR#}yt(y!OIO9enGm6Jm_ny%*yO|~RDm!XOv<(U*f(iyhYd;5vwkRhW0Y`&#} zC5w#~zWBNR2jpz}dHa0MsTh@)4l@u~W^0`u2jWar1>d{84JGH>UeK{$bV2DB{#12* zGV~aHtP_2LC>6rxG?fIX0dR8rz$zoyL4CrqxLXsFI==aPj@O2e^k!5fsGlmLW7@E` z;0af}|8@O*W_L}Wvlv}5U*|{UxU1B`6Nb)R>_~UA6noxRAxke6s)*Rj`7`S@=vVVg z6$^gxwP+t})x19b<{Jju!WrbcugVp#I6fBvJ;jGD zNX7e?X{KOV@l+(6Es8%u!|b!mV6f6L9*;&u1l(OE zW%^~_Qz#}C9y`rHiVw<|j3%Z6*Pl)M;M$pYQdqLosY28}DJz1svq|>LxjDM&T*VP8 zfQNoMfexDgMpvdqF&nm7>-{*J6N$-ZrW^h zG>xCH@O(9@BC#8r_w<0>-+v9*1FjHtiJsRr(T3jC?c=i>CYHSu7>Qr%)k*J~l3jKW ztj8pO6?o#JZ{rU4eF)#}`!`uQj<0Skl>LAQ5MR8|Jm1Au9VTRy%}c-`KDgwO9b+c8 zA0AA5ZYZ;r{->CNu%5G=AFa)lY+`r{YxLzy=bj9$@{u~5x9pvBUWxS@e(TobGi#8< z78ZV&H~5)axF^lVtuk@Q=A9G%TqTX~#Eg2Zm-Eqq>xbXL_TC{2H2cx+CQ+9+CWaUa zh9vSC-U*l%sg_@O`S#cQPus=P$&>4$xCjriA#Zft(VqM#db+n2Y5dZMnIDflo*5m} znlUartQ2^@)+0?>zdm-czK;D4`P?1n*w8QhFL_pKW{ImM5lN$M2($=8@l*K#D+ZE` zhg0bFp1_E$D}NYtye5-2Kb>3iCT$?+ZWdLA50Pa%wLw?A#Vz6{RF0v}R`&HqN+$c@ znB~{#T+-lzPUW%wOjOOojl-w&v-^cFKo@pfKClA2zL4tB^)B)B59@ZlCLvB`_gK!lM+QHZeqNpu+ zKj$o*;72Zt_4BklhX&95q*Tq4EtL;*IIX^)FEBV?74Qr#RL5B+oPB$#W*# zT)g`gOAQC+pqQ0#F8PEDBw6x<#+Lf%mLs%h`$4VoT*70wc;r)+V(&z?PeJhfQK zkP>&f-Hq2^JN-GJpz!sT>}a%--Lx z+rQXnkWA)8J`+Sx9lHH6R!wtnf3k^91^Ag`GgE1v;5H(9_bSHFd5BC2vWgG(K9Xp1kC**|&l+wNvA z;k(Ao@>fTKtN;W*J$nO^rWAm!{x}Ib7Hp6#Q+#!_raWK;wE13X;N~=SP;MDXk~zB} z=TAL5MbN-RY(_6G3u5eRtpv$M#lL@pbW> zhhBl8f$$6^V<*dt?J*r*N`Mn`4$f>TDsCO^Fq>-(5+_+eclO&-bIM32bZ@^elz{md z)S7LUlPp|k;8c)Ia9^)W$k)XkmgTH%T5c^|#JdS0s-vt;TFr>!d$6S9$$096u(%GJ zK-2h@X^O1H>H4dD?s#S89d~()%9S9^uaZ{>5-Sh*0B;>SM8z=JykOK2+TC;t!{S*- z_wpnMm0Z>;I{Awu^u8VFHSXcv;~^lss5NCqrfvQWH#hl|AqVUqS( z==Y{aX?qtSbM+cT53khfU^_Re$@*;p6(v)C7VUZe&RC3{Ckgdz1~kcmlAm{8$nHg{<&=fHz!xO(j3xaAJ)BN6?#GAE?z?N8hi66i8`m6Wpc z!IuZ{D@$Ox#WBQlU%KdpJOcj$nv=WP7&?%oW8%j6&P|=>`jja~+N@+FLgeNXuJkG? z|AA3LAsxhAQ-$8Y>-q$7-C9M~^BJ;Hf`&akvNW}go3d1At6kfGMCIl*%H$kV*e~=? zC2xb&g2la4HVECNTt?GjH%9$)@ypcQM|L$pvHGJ^9*nDAxe*6QoZQo}%w{sxATwzo zcQO-SEY6h9Xe3W4-pvtAWHx@O=0(JZ5&W)sr^O6*GO6Wa%9m|5;LUB|ld+>n77wZq8y0K(=UwzRdT?+CFZ$r7W5@mH@oPvzV+{`li`eZ@(9u4bUH8D&lo zN0q*&+)sMKPXYN4+C_?C9Hz zR2h6qCv*@!(~)g)N_u^3UGKfEf{T3xryY@J9V{Z^ppBfrCVECS<6`wU8wn8_GAQuq zr!U^X6R%h_f~Jh}T@3D@tbdgu-Px#ySR7YZCa?phqY#rzcYl4r3H3|wKBq0i)6OrEq@_FZU zeM=du{mn>#dd_31n4;XGhC}XKW}NTY!wafzQ!vr;99*FNa}LD4PvGoH!ab2|w&PM* z7M9GaqtFWrM8M*#GkLJ^keOWwb*!%uRHmQv56wR(E3<1Vvi{89vTDwq`6cJ&zIuZ; z(KhgSp)c>g*gVgldv+Ve_IVVXhhtX)7vzB+i9!*a-H~f=xec5TKcl_?qked=oAN+J z-tMUI#R>Z;?!JNP7EQnl8EKPpZeVZm)8Q1xe4jqbT_(y#x>$WAZDem!n)dV1l?g8S zQuMgIX^#5_urQ-Dg#E;m4$JPi0dI|Yt{vcUIdw#49uEG@D*D!!gL>c3O^IER>gd`T zpU|2wpyV>EPU%mzTpetkWtd0%39UzVDNgr&u+AD{*H(5R_(u(%#Yd7+T%FhmY}bB9 zW^});h7a<&MXy+i+OxnUNdKXitco2coyW6txWJzs<0M(7evi$r#iW~86RxPQpYhoU z;ll^A`_VO5&Ylfu_ZlDJpg{I|c*5mw!BWTZefC;QfZs)u7V94PTp%%ALw9^-R7R9r zF#MAOfRBBP>Mnol`RS&gWaOUX+e**h=oi*MDo0I@=*K^C?51A5J4;@WqW3bAO$~X8 ze?O`B$iMyoG0G#k!zlg(U4FdIcQna({HwKoU;TJ}%LMJYTkd(VRDS?s9!GuFZc^Br z_TGnYH&fGHZd@TfycHnkBG$_25#i^FNNur|Y+)>)_)dzbSUI?EUE^K>Ip7s<+MSgb zC)%4ht`=?au$ud&iW0T(E}g~99Uppn*v-w8GHM*{3(jw|9zHoZA2jv$=s12iYMENP zJHuxw{`kuAwC8a_{n7RpOHYpqjbcwv-a`iBx$qrN87XZUV1dQ=1(ipVE|4fiVA(0mUGesL?ZTCMDG!Pi1Jr)f6qk}Zs9t#K@!FVII zKoSyvw7&~n<1Iba{!~>tATwSe_)|0NiSBqYKVBk*a75x$!F&oxloJwbZH~Z;W$n$; z7S{GwU_L!-`v>-p)_(;5(GXsh(}w=jBaR?GY4lT|LVggRvbBXH*bwhdEwC~8Ulm3E zmc+Mps-iRki$I~R@B+MJ9sjjd1p(;6?!xob-qs%NY|rr@D&TwMj|wMNh>L^y&vG*M;nuE5ydQyHcf=wv*b~n}1z+#Q0GgS$&`ch}(V?oM!dxw*N&uj;E;@1IjO zduF=VbocJP)~RYrMNx4E7DjeB%Cho`N;no0W)gd2D>yzrI3`6Wds9~vfD;Lgkb{wl z1%O0cL6Jlq;N)y+Z%4w)$j->jpdv4%s3NJL%0u$ojHtbdt1ZCJMZ(F*!NStSnN^e) zj!DD`VC3@q1yLgx011sK4=XbZHw!BZGYcC#3p?j0W)^B@W@=hE0RcFGo#{WGS^tNC zgh>`)XYOJ_!uESfnS@E)(#GXC8YXd@-?l^nCibQPlHcz+yZm-x3->kStYhpOMO!T; z$B!T3#5B;Gu}ml=g5V8McrbXjQtQnnn~U1wGeLvnk;5>P{Vm`dp)PJMfackl zsC!Mbf{zD-d$X$#-&;Q?*CxOBUtIQZk!Rfan1Of{Q z?VoO(UnjbJ_f@aD{Pz6x${v}V-#w^k8YD#`H zicHDz{VL&4oy#k5zK5nt3E7^a9XhcAu@>z2Rf3;fI%U6_Hs4_y29E+Uh3+Xs2psAh z4C}d53G9BmJU`oZs;4qrqc_%VD6$%j3AD-I?V_dO;C-5~KSV;8i6N7e7^Qt$vJcf@ zVQkvmBNvWvd!?d8&)fwWMfHZsZKk66T0=)(9yZw+>CbtqnmTraAGOTv`U;a^^*lwd zPr`$*LSGJHb?Qm<&^GpJl&kCfe)3-6pqZFf`|FB+4&B>v*Y}oJNIk0KgAQlb)oNDh zDjlQjytS@TE_ed^{o%b+@sZmL_-<-@$I)2oz=BElJh+Vf)41Nmcv7nO%NZZ;YjJE3 zyzIDA2Lq{t6>QE{hy7BmM87GAoW)!VI0^6OLr}#W#?TKZ{!30vJ&KK_*aWvOON_)b zg+$zRp8oH=p)Q>)5{{jij{Cffw6N3PtKdiF4VBHLZSjKpzuWw5VuiKVKR5~M$J80) zzLzpXwh}faD@_f0klP8gtQ%%oa$58p_;u_1tD7g{@J)A|kR^^nM;e3P2y2&H;MJs8 znLqr%@yjq+{RMu?iP5DdD_b6mCP{&6OZLDsP0=oH`JxjBHHXj5x=!IPoqQisSkc&Y7QMUk?u4~Y> zKR5@D^j?1!`O_j99W=ER``ER~LRpwuR`|+Z|7`<*5o7m@YpScqxHpgzMDyG&Js)_% zDfRx;FkIa~6uDE^3o3I?s9v4oh{0_n_w@eBI-I)30ZE>!nU$i-<>PtsM;m*kQRSy$@2lLTI-Fw%J?4&R(5YIk72W0%&wglRY~U9_%_k^2WcY=zr+jf`QY z74Bs1#hhV>*VuhUo2-I{8Op-u<7Gm{^b7X5F2V@H2N>PAZ$^{czGT<_gn}h%^$?`M zUoE{qc_TvM_+c9MYShy>w`KOdA3g;vgf@O*#Vf;Q@y7vz+%8l|r%%qp(gcLjUa%yr zS)*+eTQ-9Lg+BF!SUZm4QbFZ}VukDm#{UQ>f@()$$Mdj~;N}l7L^E{t-keL3MT$O8 z19=`lr)1f5Ai9s1^)C|aI^w~2br?kHRyHZXbFMr2EPowk%(7hGFSmFo@pvrnsrnUF z$LV9>j?CNnh+)*V(}VLl;M7D{;Q?kV+hFSQ4LcfMMTPIcAH-tu8krt#^@3eb!?}b4 zhEwn1(^uhMUc)0W=*P&$Q419UvvsZ(y9**+|75<3K>7jaft~Z8yi(fJYpq|(5Q|1* z;P@VnKQp%nccr|@_JGg9eVlJ^M%DO6f|L#^!zn(YN^}qF%{C|=43bn;?rvPYOsDMC)J_MdP2sm`q|_L z!Lljb>IqHxnO6GPRA?*!orkB+Z-?6l9v)+xI;ZI=MO{PZZSuvdP1n)fz`;Ij9A}OW zkPU1jh2h4M2S85hvosLnZjwo~UU3~|*z4*NSNU*B117OgK-zVEa=JXBK*VMB!o?57 znQ(KlhmVXG*EL|^3C+R{>g?FxfvvLSou>&KtZaB(stqebBM-IsMSEwbPG+*l@ zi!z*QhAoYqi1{m8tD@@?WZyp4PQ(1PCM}*;6F<3WV60c*o;y{2ZZm~M zgCp!hz`3a!A$&b8IinqUI{x`2!zXzg{+FT(FQ;=sZiLzB6$OGkx;6*@Q-gf-mFE<-%@eZeQP_l zbLbnfBrbXT^gdO5Pm^qZlO zqaZp-b+u-;XQ0s}JOx<`or61$s$x)tmp#WEClxRQr%); z3fYX1ppgqxy&^B>;yU#LKsiMm)RBX^3D9$7kfwNch_hFg49P-EsgU)XZ;o3v_$E@Vfw3yB9x#qi+-n-?uIv^ zK!uG!)>+(uljjt2&J$$)s4n&Iibjctz_PRIGqk0W&ON6Z#PYK!JhC6qA*UVI7uEcv zS>A~V-tGT=ztyHy!<;+O6w9GtvmkXNl{y>hi53B`cr$ z4lAg4y=PBb8f^$604Ws!-_2Y!Q3py+Vpr-tAzUv};H4>@MXBCiQ+ne~Z#+o;IF=rU zd&RzF>;T7L4%QlgtPn~mLKFEj8BzlQS7w}7TUXObVcs;9p{hFsQ~E0*R~{5=22P;a zxJd!TwTqYoiMtH+X`KJ%goze-D@-YOJwfaSw;?Sp(dp;N>(OY^n!v4Zc0^NRTS;jF zqs$4IqY=!laouavGs9C`HHN81aMyXL0Rm=Jk#MXppt`+x6w<6%;r4?NXgfVlT92Y) zLj1L&tkwX3E_zsq0n$E+6%e5^b_yKutlk7{2H~x}f?i4}4Imq(KN%~ImI|$kQV0VN zCle{@h)Ro=@r{4L4gYrV(OEv<7qJ_F;?9J|{kfsVH}uTCOmKb5O|U_jB?+yI2p4c} zKXR}oOX?JD3aVNw&{!;-iSEmu6-BVy2uwjPXsomC6hk@Moc$rb-FZ7%g`DImD0&|R z7!HR+{}(7t{71}2t7 zPJtj%{gU0?a zP;_pEF`0FOtJ{HX$vwmw}Ic~h+!#jtWj zL&Ias;FSbG7(p-O%L*G(NTtJ+hjaSJKAg$sQH-e6l*}SNZwU{n7E+O#Oln2n$+tUu z$@ZJzXzm!qC0%dE3FhuzGLzPP5P%&yui-i$4WWw}4_Sb~u!+OM;&VRZ3n~w$3mIEV zuIixci{O*7h^Qcdgh7$A+^9}7D%ylCe7xSs;=V*v)WFylk!+8i)`e5X51mE!$D}Hl z((;m#1PtL=^rYR1Dq&!JRn8|g(i}(`wibxRGRr|r;F*GhReup=wGk$Q!H&Q^Qt+ly z7fYE+a&xQz_G192!|6VKCuMHZCMYcS2)n_gva811P2v3^|_gIhtJj zDA5!Q)SrNY_>10a#Af*+@5n-%h%7<)zDg9nkFue-ec#`W7PLaM0TwgsKVZQ4*;tG4 z^HaBLK3)@O@U2-%3WE!fn3&L(?D}zWER48j$id@*sGmtP=*ZI^$%CiD*--+MQ3GBr zN6cg8Q5yGA8(yF0wT-kzRh9>*$O+?vi6BUMWXU=?$;=xZ^>tP~ERH zESKOyLKVJ3En~}!AP>b>GWI5hx0e(zgMKHwk%dEXTL=Db(?nuhMv%__oGss@-NScf8NmTVEF@K|w6qUt}DTWxuNkvCD5Uej&8yA=zZW8Th z$GZoDL(qw*P~~-FAT{0(%5ui6$&1=i_>RZU4#S9uei) z-qYssDXSb@dhAt@Ny}OoF#zwr#~(#fMAHLRg>a8+!e56orI?fARilPkckh)+!uMFU z=@`k_Zd{yjT`8`{k)^`P+J1Pen~l&s7|zt{H8_K%6fM^f(FFwW%RIyF1{!tGqzkcx z)5QDHOf>+oSi@ma#S*ZX9Z}-RD>pbdC8iB|D(oZb6-mh8f{2C80x1y<;;hcejMNaa zF-JBzTg60u9avH}nw{C@SRe7nntf4t<=8ce$F4Gi?3d$`$>?unJX8yj?I@Jd5kp7F zXd+It$%6xe2EkwfJ}_itg2;hM3%M+{_Y{n}x|?A_xMYzww`C9zPC(P~Es1&3#~?^I zAY&UHK@A0ehpUL|gC!ioEVJ%oo~sjOmaC>WRaIR0nO(5!#OEJ^!h7&h11{thS0*G# zy4^#=7lbvR@&X+ zvYBHO=cQuVns$s7j%!wQXxytAIkatfK#B&Q@Ze5GGgwp_GDdKa)_EWcL`d!(L#ZMa zN<0-J-KJwrdN{iy(`BHZEd!gn1t>a-I{btp+fW>_73PAO9})(NIFy}gfUQ9wyv}fWZ!kq01Vu_f z!7ZdGtPF+;e1xbt0FhN?&m>B*0z|G3PNmrtRfg;?_|$Ijg~)ihmoLOahK*H4GjupL zbI`wje3xKsxtBCVy#EvgG-C3QC?<11gpteSdI6Z*O=Em_niG0jvqzSQJBKcrb(fKMo_Gkj(7 z(uR7GRrR&d!fpnNW@t*5R%}Hjca*=SAzk!PL%8=SUk0gG*x4dHJgfO9piT{&WYTTI z4oNlS8QOua@C-MT(_T_db4eOyYF>DzDT`z`-=P7sfK9S^1*OnZMm=|bX2t+TJ`kOM zs2aT-Un{Qb_-u;w3?d0dH?llaMLMi{7Q909>Q~W>B44(aYv{qggv!Cm77v1~ss;CX z(z$YAVd7Df9gmnB`yu;;{=$2P2Jc|Lu7J=^9yhLgEjMXx1kIWYRBXhT<{jzVSm%|? zC9yr-PY>2r-6Lk1{Q?HK+oH@|gJsO+R4~r`b!gwzQbEk)DIl^-5hTckoN6ic**>-{ zVB>r^zW&UBrDP}MN6U!7qQ<1`znfT@IEywZrRl4nidZ$59+Fy5?}-6Mr$Xn2k9cG5 zvO7zBgNz$Kz^-{^+YFvd)Ps4n*D7a|+Ap9FNG2A&M6VH(GFr-#DQ=f%9j{3MiAx$( z97jmo)y}iMK@%IVPd70FvDe3=<#Tq$0EnVe)tk#f5EIbRe=%l=U@}vla_pIEl+e;- zOO!;7Mps-CMSnYzTqSoA6s2%E>DMxb3+UO}Zk&}v&&0qK7Z;ynugga|C3DJ-w`4yP zE$wZrtHeo5nsPrdqNU67?$TUHZ4dD&+>Pyl`(Q!s{3@^m-g?`f(2oIVMCY(FGfN>f zaaJddDoAD{ltbN>l8p?fg2Tu90J+-!Vj3@7&zVu8DxOOzU{y3q8;EM^e{P><;I7Mp zBabX?E}unK5W|co+`Mk-Evl8_1(clL9DfzjGBswt;%G0`6-2Gwn5mm<8Qf}4s;G8k z?ex+MOz5{zX6IF7ttM%K#Qd=J)Z44@RfJdtr%cwz;g+EaKWK?bZ3AE6ffq|vFV*lY z+KDFTjini{_Z-xn&ZSWj6Q^I-g$ne-UM13D=Su!YBXpvYIw0;V{&m+{7c}Q4N zAz^GRNOPP1CZI#lo~94n!j&uVXU&PW9(LT}49@1eQ?}=-hUWkqSv`CL5|N69UCDJU)a9K)v3Y#S1G`AcU2WWA zj^(vrp*o}jaJ-n9G%rrgGodA8<*`}SF=!isCMRIR7q>`JH?5nhhW#DqAXw84Rt^jH zq7#{j=qf_@n#~2f6iH=l^-o0{<1MhE7tlZ3520G!p;$-IY-fwCS|Zj!k>C~6Mh^rC z!wp-O2;Xbk!fI!x50N$%twJCe?~DijWHWrI9Pt?QxZSWRd_{ z&*$dOZRh~ZPu1+TGOkkbYar@h1;GGkr8|_N6CM0;H4(TFi(y~fgFQ@|7lxRvh%pv< z_y$QbceOVoWj9G$)B#^F2#)9%%S53tf)2EkFLAG3v#c}OC!r4IT`HYpa7Yk}tOsEF z{DoXAm-6a}br&N?x`nl=+puV$x4ZC{8>&FKj@Xx~T=%CCkz1|x9Pb)~uCz7iPPb#O zwHMvD+T2F18{p&l-7{~s&tdsjNIJ0CAP!ZbjvKU@#2bQsX;%_?i{sWWS~29KYzuo= zil;PsG8>dTn%(h~{FpD1NEzpOXy5@SGmkTfLY7jtvfW!e@zg9JI$PYS8Ae+W@?-e+ zjopawb#aGS3Mx(BpFux4j|YeOJW2{joa504_ZzBaNNwgvq$&d=ZEW)N)L%E$(fuwCSq9VzV(i6pS zjMy^37tWH29~-GCAvCNLn%TLWdX(8 zNRg5>FBHr0L_<5s`dC95LpcP55^1F9qQEsN9!^Qpk{s-bXGm?Vjt-*GL35djHmf$3 z(O1yIWnb=vinACGqSldwV2yD^0l+^9mQ5oU+2qnoa;yj?Gsr>%Tpa-LLc&z6$h9`x zYLa4uKT{ZN5LzU^9My*OlkQtU8x)li8<9gBG@^(Xkk68gV`W8nn;u0k_sX}paVX@E zV=0e~Ko$Q?WzYpCM#@l6U_r$s6%hNiqS)_IoPX`_T~tyZoMIo7=w$tdt=%j{N*_js zB^_V8@~a6YzRDKL%F5tT=Dn17wopq!pgUShzgd~u+|Sj49^(`AIdln@S&An!cr<+O zCmuW!{jY{63&>YYcPs!``m_+&1Mk9`C9K*s90!wlMgmR%fc_!`kGiUt87@r`n;l7| zcIqmr&?pe=CTq*R&xIl53jhFYFI4S@+z%_AgM^AaVXn5;5>Bz_9Jl`5HwKk%Hnm6w zV`|A2*x=S%U+@y!umh%qXJ^hZH|2!r-mu`#hfH;BXU71~l8JlaSV`rfB8B~yrc$ee~FGoIH@6Jh;;zQb^(n9 zy&M&-GFhax8&$dzQo>E-0mgCl$X3QNF^{LWqmV+H_(B5Mtg1{qM&7OqR~-$1 z1|##ml>uNBT-UlHql7DTrA(fJ0)Uv5u}rPy3cM&JlheZOc~%~_n^umx{(i$LW>f&x zY9X&g1UsN?Wxi%6PFAaWl!;;G308-3Pb))yt@R8_BT|nMN9$`r9{0#vJCcoF(1uI{ zPyR(G4U58z&|`h(R8R}|Dd!^25XVLwtEFB|@j&9f#l=KXJdKdY#Tp$NfGhu*HDAy3 z3(Y5TDSd5mia6qtUo)1%srXVYRtmZOv7)}mmX?+xk@O~&naoL)Rs*Z898-!=Do2`{ z`Y(1Aa>slFGnIX3gQCyy*$Y&}qgQu^g??fWP)eae;oFQlNMXb?QVRg3OMGQ$iWz5gBcc!Sm^nk!&rA z(Ni->I2zKAiI48t-$>Tyi=a!=x9_}4v3M$x*1s0dm%RL{e|AmJ&f-`nEGgFE#H33) zQWr&JT<<9nD#a(pOmS^1&10lpwmJ=c0k-7_^%Mp?rW_d}YJLdM0x(6oC z@w+FcLTQ#aX2`L?JGa|x$A@!waT9zAv(hDt;`DwkixHCa_jLqk`Zk*YpvV?rvmb+t z$&2B@Lg#W4XmSTo7$R8tfiF}PZMe?QN{Kd>lF0p`d0#qiIab>O_~~{R3ZxaA(Xlva zw_0{%D>fO^&*YBM;dmS$$zDNcr;Z-u$m5>Wy(gMDF5RdusMYQmlcMbNv`&)FowuV) z{(4HNNoTOQ+NhfLGN69k5fQmJgO7*FS;QekCoX57p(>iOVO#ph z+acm?_I6h#KY)2snG?u=`r~6AldtmNlqA7A~ zp4SbNsiNtLjz{YfQJubiL$PAmx&vOzal`YlHgEKo+hMBVqD}!O!;eO_Ppk&^1L~ha zI(&4Jk?yiCTeflibQ#gi zT+014aRNlv%TYHEI%;j?Q54nao2R8H3$2o8)S|n*b)=T*@f9Ekl-^E4mml4OxZ*|G z(J4waAL&E*Tt!(KO$`l{{Dk%y9$#b1RVY%@!+Pe!pU=ou=uzS)d_E(Xhs{%1Q$nP8 z&LEn1&r^6vO;fvz5G?Bx%O)?tGr2n!Da#hm)+$(WxRa9j&DgSI3p{=AN~O!xB(nz! zc%tuM<;z&4vR?|GQ|FA7%HXAmnG4g3?`l-b4yB3BKD%2TqgSi?eHY-6X$U#)YgFY- z709#Zo;;oW@o|28+six)ea_w04IVT?g9fD~Z1|Lg@$u?cKa0H_d9?3^f1_7%oZYqG zM+IZa{CxbyuiRk#BY~~x%Uj!~UrS{tw(plWulKs+u6d@pzAqp7lb6kW4?m!P@T=^F z-7b!we{pEZ?rL=X)cOW53C>AP5*cu5$OQ<=r%qMkkTd{0W)riE>qJ&QO3sWQf2clq zBBh&2MU z3^Ox~Q5ZM261Ps`!$RkiH;g#*AY`Q{HFKZVQ3y$*5J|jDnA~}CnN8yqbmtSd(EsMp z6L;4B1T>u$j-Vg^4FGJ$JaUc1hqwSsd;j=8WoTNS_)05^AH;Gn#ZZ?H`jXTWqHSrDmltwGMWC3tbVvAA$^J2lh`r?T(IncL%!fV&7HPSMRUi+BMo-yVnf?<;v9FV}-yHQk=|#WM@Q zr01UR?iPdBG^eydZQvX^aE+6L-y*0ZgL&6o67MEiBH)G;_QQwb_)YKuBGje>}A!AyVA34JbuAt z(A;zHENb(}+GEG^F_?6=l~doH53pB=kT0ZoCGNg+8lJ|d=uax~zB0Ow501eSdP!`o zlKfrNZa>tBuRJ`|~tfJ#6F!=dZ=lS#l!~?;Tphw%p%UBA~JdbqpDYN3=1S8B^r*%dRP@ zGwM$%bbzV!F*I`r@7;?RTQmFQ{rN(?m7#JEU(@w;ai*LlWz`!5N0-IKjsI5eK|{!3Pwf@y2NLM`>7-um%d)PH#``@(US zqhswYINZfnjLq-|_3sAphO6m2MDn z%qC|C>_k@a=`Cvd6;6qf=*Br0^*d)mr$w9ZH ze!%`;PBI%C9zJ)){^?E~ATv+(l^x|zKG6aT|3d${ur>s2N1Q4Cw?Und z|Go_wE`T~Zf}i1?mgkbRSqr5HAnb#k3$ff##7wMaM&+L zi$OJ1ntSqbqEX*VD6dLkY1KKrRR{h0R?K2g<0;E$?2|e^;{XnVcDF@tSTtLds;1Ij zJ$@dy`&?Hc!q~^&RqmBkz2925>VLBkhVcPHsbIh6pU(QcJAiVH^;AqY0D~wZ4@qQ> z?Ex&ZUoH~qNM<%i38}I@WfpikF&0|RO^_i=Fhb<8JLJ@$XgIl;b|=oBnlcn#vvnt@ zjTGCx-!0F6JWet>TS3(MWh;hBG=Wl&cQyG4tfTtC#Ty3XJZ5;9FII_d&y!m zYDrp**ku?5e4aes?V9%vBUgaqhtw5+5_p7Ay~%tnRX+NeZEye0ZJM<8>fE@k&R%B5 z=pAr=ZDl)q!a~V&q8{BsEMr4_;w3FEt^ikXgRLG z5Ut;)-dyI9gZ#wRGUle<8nOv+(w)mMyO60toF2BT3HqvjN(Wy*Zh=~&y{LWWhmqk` zes|K6!ygZLq3G_#JB890#||XbAS%W-x~{S2FEbo5@fafr$&c=KR@ddSul+i?!k4Kp zaJX-oTUvhT87zY*{-9fbp)z|U&=j4m6#?By{S3!0_FA}<70EgDSV9FLch|megqxVy zcpsDZ+Enm@N6xv?Bw$wMY}8`A611|K9X!%td6o^sFZk|ZH%7x1obWb;V;6My>34hT zL!2q6=bStm@*}0M?OXwJa&(Pb`&G3fj+DEp2v}jsvL~xCm@-|-!bCZ*Z@so|dl&U1 z&PFkdx%sM^_M(2c-&Vw!?!|O|lPkq9ocv8z{_%1ewBck97n?iG`JK*E?7Qw~UX|xo z2A_Z4EPwJg9?3hPcLhDdHxf`*(%_Wrf}5eHTSMu9nKqm?k}J!_c%{)%hZMfzwvG11 z&7X8>7V=DWqB|}bNj9z6C&hTWswp_?J;>1C%E+Q|>~mqu|A19&O`Rr&EUnreF{8sr zI32(*Fn~N}BeaY2H7A|x!yteS1&#k;TSCepBh3D2+yTxVqOP%Zz+X+|8n+!J+oJm#TpwU+r3M^@S! zE_2QN4Ig{)OSe`-S!;vzN~^$la>R;<`u&l50FCC!xpbzX}zSnvFbD zTVvPwh$_e0+V6-Yvr8OA?rJGNL&6$a?t?3uj8y^7G;N&9ArLh#MzTvJ{-gm`YpA)YAw z_OKY%1v3BlAa{@*78jv={IE^Z7yOSX9FK|7c{ZPz5HO(Nrx^qv9G0g!g`o=e{p6@a|I%fXhEps7yKxEh{gQPoaIPd zhh<|i;!;;|{?UEMe}&5o9})P?jIlIcajUI`FKSwLxjp!ekD&HsMxE;YCac}(0rP@W z%_Yd4THTZAADWvq)Szu02|slpe*E$uGd!Vxj~5w1${Gube}%}cOyB}Y$Wu_ME5E9BTKYp_-l~|HSF!HxSad7+Z9YMC!mh8h5l1FRQAZP z-D%o06JFS{n#NAFX9e#A{m1``yVCj?o%GlY?`Up&ht8i|K6zb;BM+pdO@U8IsJvW#F zY{N3QjWfhtY{S1KKdEyBkdC(Vw!Yx~KZ2%3RJwt;q|tk-`eCK;kF4e^ZVJ~4{?TjJNw#C7+Fhya~b)Wu_5sv#a$PdkDR;` zVX(~LYgc*}`&YcYkR)$pqDkdYm`kti7h$s%P5x>keG;JfE@!;z(24l-Z|PgP_g!@R z5&y>?zjt1DY+l%^JpW6zRc(8g@h>)@|BFS(wwpb`6Tje}g7*Y12*0>yGPica{kVBA zX=Fx>i>(8`4^(e967&`Yr`dI_Z(l+GBu{+97X1}YyQHdHSki34D%OSioqG*;Ik=ci zxRRySP%O@;=M{2|o`5klgSlrewr)6To6Tf!f=paJ-V5lIPqKRSXb%@TA@6&;+S1pr zoDVY-?<6g7pWd^N_kGp=2Gxi4|1~u-m-c&V#2N`%?txfHS&leu0AAGGBodG;XgkQh ze)qBtc&}Eh;`Vd(Q{KY9{lCwRL^i1YZ*Byl$t1+Z&w%DNgJ0IKmctW&Rkaxihv~C> z25ru=!cuccu}$ojh44N*v;|2Os(U!Kwe`Ksm3H4 zP2(NcZ^$3OYE{d~nPy^BQ0)gqnP1iJ^r^VhIP@sWWoyW8rC77q(eu{ak?83HPj-U- zM=n44x6%3O!wu2hda)~J?F5+v-h7^NkN^K;BMcnBX4T3l##XWbxU)usGL8XT$bhe) zr-(9n_sfX6S@)mi;dQzbUbaYB`&y5*zF71L1Vz>wms`jxd%;mrIz*EAgQkg_IoFAQ zop8y9ip=4(hd>DHgU>$2nspTrWB6_vUwLY;oql?gj#b~8c_Zz1^kjc=qLg&4rhtQd z`IX8lJY&_F`9oWDe~T}|=?MC_>dQEqVTIf5gp%w- zI>pDUwyEa6iPE*!wttQIS3u>T!4a+BgCk>;CXpJ0OV+Se2oayw2i|YXD`D+_8ie$V z><$bY#q)?wf%i~2`rw0b$9Hd(k(8Y(6+R!U%Cg`EiHBt}W3*ZGiFfs(c_zMAbb|;?Fc_Fqd z470aHGQ~;w)4)gbbgrT2NqATtlV1b+w}(PD+0~co(1NHpe`F8$xqjWdM~G?D%AVPeDA` z#4MQyhd|~=A{6kM*~JNQG@38GW8Cq!u?q5g09U^&*WikoR1r>YRTMC*^@`m35ZViHR`BzV z5$5^L{x4Po)>)j1NgOe!J)z$s133jmu&4|pM(ofu973zURswMZv9yvX-9$o~z-Xk8 zWLVSK&O`dQyKu2odV|0RWVZoEwa*!{pHA#$;b^wOG(d3@SAI_+)O?|Rzjs8hS;UXnrgNc zmAo*a_^sqFJ;BO4UaGLfjyQjN*_*Hj9iW<(o4K25{-$#e$!aNefuXPnk?iR5h7F9U z(x7@eG)(TE^hm-2tspS$(#p`w*K9-HtxYVn$Kf^r{2ZEZ6H(MtXiaWCVo4A6G8m%Wn{vLQ>8{P?@7{(;Q6RPrc<>ls~RGb@wo(`7|{@Mc} ztdO=-W1KbYIFO8u#!8zS9xR>sd#F$7mKJ;Bi=`+{rj!7`GTVf?lFMYu-8r01Gj3p_ zN}{)?tUuLGj%%=>KtoNBG=jC9TL}tw!$4PnDw#o2Fxs-0ikGp)$HTUDc?!IL^}dW)UknH0Vj<@7(&j4_3vzS&MS@41>qkN{ zFalW|HGo8gC;Y;6&!wp&Mj73o zOC&frr0`=p+%65-)+Wnr#0`y6qa1M?0472RqlJ_JO5CC%oLRpc zMqloX*K!xETRCa#csVaUvHLS98$z06huOjlukCh*hoXBf>js-L$h5f zG#>4M6b{k{Jt&H0h2lp>-X2s-<3RAQK-w!?oZjBZ&xyanBKmGK!{fxXKy(@#jYiUJ zYKT^u2}}%eu-AymguzYhCwtqrKAV(Ia3tx*oL@r5N{V;yyjN3a@X%X&s8js-*3Y~m zt;9TKY!ei#30d8Td5}$3<(iWpVMt+!XoxQgK@I(&6c~;cait7iBi>30DsLOia-&Fu z4}JxL%FoBw+^*5jD%cMh?im@E(9NnA;4M0Cg&wV*jBnhFdNIfGwRT1l_NqA@ycH}- zoLCZ-iVz8pBXSeye;8FL_=_yiuRAh@kP(HnJxHvQ^-<9hgYAHztM{Z)6Ki=C5nL}f z$P=x}(S%=3vk%I@I|I%yloAe>K(_x8;14?59S%2QJJc_*Whs6@A&3hTrMvTLE;weM-Qf+(wqzBn|2sYy&j$*Bi%1m;GlAdLZfpvh|62qvSGe88ie zgxlX88V)n;P|I^gvmjxp6CoMSm!EcINCqwz4$cQc$#jMajcq|lm7F(PQq(g-z7YaC z8jruBS&jf>R@PpvK;g{7N6$Fv1hJM^$_j^!+{+B<=XG0+kmc5nOFF5_51M#}PWqHU zYHMX)4TrFz_|+Rpj%9FHOzzQKu6IZ)k_M#J7@K7SvgC~;(W>t;evDqWi5Y95hG&tjC4WI&FSUcg&Ec2P-l5_&B>sz>RA zq6Viz6_A5`*o8$krxKAvF*qEfMPA3vc#oNO*$4xTr`M-{No*LCd>oW_G{9!+UK894Ds zv2tLt`ZW=jACBgIAac+?rcx5@=+`}lse0r6rue#7b&@dBZfRD~B3Stn8Oaah8mLGZ z)rzZo3X1M(@UPTazR=|QsI*}me8%v*`NkxH^CD-nScJk26wv$Kbi>*T0jHXxcgM^; ze0~^MVD``==zChBmNa);HIgKO(0R_%dZwjvX>^(dx&t>hsp)(AlhWd2mQdlEA;1YCVpV!(q8W+;f24$rWn6{A#KGfL z59{^s|Ku*V&;*rMu0z561c6G)0G$yZ-QM4(H*#TTpC(y>>Z5dTTyWGShS48fL%0>% zol=BoseM7V!apL2iZn~qYswjqZ5<&A(I;sv=Hq3sNMEu4SgW~#f}aFLoMLna6&CfH z2>m@y)@69?Xb-cOTG#7w$e4%R%|C;<-Sr3+!FaW?!<8pC7yWS{`T~V*hSIl+@kxHT zacbfk%RvbU=DzEXLan}t1(OJG2(6^wiK(6xfW;L0(^1x@7LFNf3T~aE8@DZ7KItM> zdk{t0Z!-hnX{uznA|JaZTHJM@+ZPMoM<%tihkCmKLU{ewAcsN0U@E8#j!F)-lrr=!HuuthM@e4r|Rx!G(HQo8Cb7Y{|OAuBSBS=WX{+1B1f|#8KbGoF zJ&?nO-3xJP7n)iPvo{r=N9bXbkfl?NEjCKt8M*H!6AgeaT%TvKYFi^7r7V$pg-h$8 z*+`V7L*vaco*S2s&epRN$LDY-B`P;N`l$9qZM?@K4`rr@2VR)4pUp&JL`AXX5lBrw z;R}Dj+AxbMs8LkevgJT~JFUx!pMs>WLR?B~0vox4R~&VgSTLUYf)rgi7AOLM0Doec z48Q13VE@gGT`;VcRL0oW^98Ma7-n#)*1mr~Q3Lc7$D!yRoKEM0u%c8_VtC>Y_JOaV z=DLic=#e_6oc3MXdJ@M|M(QwxGfG2*E$4Ch;Y`>C3UHP5F%|tbR}ItRnsTHCV+%7e z54*4m`gOhPJQJs)lkNaRK;c3NID6o|M0y0tHp8s2Io}BCsYq@%dL}8!bLlYYpNfH- zHPlnoXI-v-f|aF@%6f(mA@Cs-Ppn&T9e-fh(jLI61(E}bwmx6Ox|4MVJBZ88XGZv& zn&_aU8U1p#65|jv#XG?1tcf6Xob*LoJ`NcQ2ugp(_OYSl*n!(JzP zxhKr%XeSXobspv^=|!{o_`FwF7LQLPixZbux>Hx_jbgt2|$K$NsHI@qn9TrrfuBEPQVuW;76 zMu_+T?Q~8Fb9ZAZyE|V1g0+T;Y&T)>H!}%Cb4JsM8zBgpDd$PDRLRotFbSwx##f>? zoxyTOALH=y?(i$JNQ7hCDW!|-`v_kJo1#D7Bbi+h zdLys1@#q^HPG0sMasN;p!Qxfd_>;E1Cr#-cywO~56{&Se;_uAh!Jw9wJ)w}-Rdq1D z3u}w7`j&>aI&OrC`J1?3*(1<&Ig0bcTTLY}#B}F0&E_y}CQ~Ou@&Mt(PMn~8hT{j{ z*Vv1`htm}#_yndSICb9o5{^2tGbH0|!$I9q{$u0I^U;rN;^&h~)11-l%^Ab9{l9td z_s6)kgF<(7zw(qsq5zm^xR&A+v%`vwH4q_vO*g%{4@+uyZHlDM);Di6m-!r}VI1Tv zorKH>s#TS=Z|Yv`#`Cg@WJONgidW2!6wx&`^H(s}5^MQgWeKi9KFO;auV=@Haq#)xyTr?+|vroxh zK{u1N4ofQ$5t#9Jn&*1dRo8}XxMVN)ev=@(YF6owK1RfL%&MAZ;}}cCp0NtHkGzu*;UE0t zmyuhE#u45!Olt_xCY~TUu^VUKpd)lC)OH-91kM2C|8A%^-ao7TZ8Pho1P*2)A*q##3vyD>C^q%mXazlTBAIQFsio;kn~2|Rl)JB_ z?Rw@$d?gsnd3Y6F`s zd>0xgd2nV3^bA!noJk>uRjo_t!0;E9Px*`s{zlWN zs$^zw2v%Fgir1y{s8;0Q7>v5AuUZxS)TmiWs!& zJE6d~Z)D96D|k5;pr>1sAiyVe;A$ITI&w z*q`#o<{LRhsDUN(y&NrIpWI?3Tp{C^?Yy|lfq}+Slwqw6V@F?-M!CT|%WYkZmiGER zar#N11gkDg&LjIeAR1Hap6l|c>uHkQY(J?ig+Ss@HWN-rG+ju*oGX3I5td(2rX)lj zAfZy8?Gn@A@Au92Ji(zDEtDPLwk@A79Azr3g)3^Io_bM;Gd_A`BH75LWvEhAG;zAe zD#mwU3O>`LS=@A%)G_tZwN_T^(hZYj)UMywE70wvoiKu4zc`v^9Y^a!{CRC|NlVcM z(fBo{X|xbL3RkC{xXVPU} z2%;j&+sNGfJ}M>*^*c>Q53Jxz@E16#j8&K+r7s6t%ka_`)2s`qXHz0&SD@#?#3L2A zk!xPjQ=2x!TA*h_3zWBQbzoX=v)uHOl|_g^H-QoQDf))GeC{o#Z7@(12V0*TjI7eG zpAr;Y(6LjN1bVf%(^`fqdm|G(#cOx9tON18IP4?P5hFukubc6N1AX0&Y}wNN2-%s4 zqyVA0QMNm-exhAWQhcnZ9~L)^HX%D4U~ij02K7$K$BVJHed?zCnt(z?|AoGanYPy8 zyNZ3pPXz8CZ7oBG(0b>a8+-JS9Y#?OOdU(i+_g&{vG(g6u&&ZZ-Eznk!l-A0CV`k~ zq(D~ES~6DH5&OidU2#Lc(PRgB8<$n|)vqgMEmXSjkzYU!Lh-uCs@PLKq4ueMJyhyq z62(4x0{!XJHpC>ztViCJMN@5}O7h%+!emcnp1-%hR-WKAJh+`u^B_X+ZxXiSt( z2a}BR+^2m>{{kgdBcrMlqqBhF&7QcZ*F;jEhSs0up%i}}PrJORukRTxj*XL-4?>jhJi5aaJ9>Z*1%@Q&+4 zAxPX3ZlF?wxIQj7j`jMON4;F@VJ%cM#V3^8$u~r=Z%Um^mR^R76M*GQKNL741OD6Q zSvXMzuaa$?N3vNetaIEGIW4Pg}u9$iwx3uFIfsrckg^| zOSVVL|K?0~2@%1ukB)eStL=*~zVIC|dj2YgI3|ItaD^470Wv0uh~ z7kB1#@G7qBRYi$t+UNmo0fKkd@c!)SvRYHRZ6dv7%T1$F^!k^*5nENi)oAn18js}t zpeZm|b~?{|RD4kXSt3cI9=V>KAT*T752clk+OuRi#9inY3eiQ5~KFB+G8A zu_G~hM7EmIaj6Zv!_lef$S3-dV2Bf8<9}u@QXG#bO~5wL$2eTcz;B|0p_Qjgsuwx0 zcxX>Hq~k9bEOI8)mcgGpRQp|Y7Acpa#%3C6R)kf^FbUUn!FH*ZT6`9nmE!MeXcuaM zd;OY+rnH7%!2<0(j^PCoNyXXi;52 zJ;$HV1Y+b7Y800G1hTY*ZRhhoVsmNaEVc}ZS!K8L=VEJV@fFnga?=vtmQ`U!i2UHS zjRz{O7_jmTsHQZ#wT)n^-0tB;PNDe;+u8)twEUKFMXF)-2}(KynV^f*BDV1Qgl-*z zatUsWoFa6F-wbR4%(?`vpv&T-tBCr9?D-cXa)Qd`c{A$zzF?+bmWf%6>+{Q?i|#0) zk1vp0A4^CI3D0l9Tne(iS(bj3Eah!LG!eM)=V|uXi7ze`Z{XfK|7?~<#@u2q+b!B) zhRFENao4+ts;#qfE{HbfurJ;fwxm{K>18eJZ1!LU#*b=0eJQdAh8uuvX?FLx&A_v#D4msO24q!QLf=%es5IPsd=%Z2CUt_FN(Kl(orbd_6$iIU%l;a zq?=m#wuZ%%d*4GRCwh^tt`N9wT>^*HC9Zr$>}l|0GWlf6H{5uR9}b(N;Qj->nDm8a zrX^|DkZPQ?r$OOf=8c`)kOojNHGF5Dp9h>1n=%t291MXkQe2{bmfUT&QFwLB&+i3n8c+=Cpx916?)8JA1e9l_TpEy4Ko>Fuwl!MTK_4ByFB$?ptJ4BQnvdZ!DNic-VdephN ziuu9G9kfe*^tq?X@zseLyi0h@d7X;++sQJLi&53B zZ>OnxOammwbvccrwJ}2t~t!CYvZ!v&9XVC)tlzjixGLc zzGor4s>X3*Qp5`C6Y5C?o1i8+V0)U7GI*(@^aUI} zx%_2WEQ2q1A(!Y42fecJEpW7*Twa2jW1m z^d$m>bXEv-IL3pe!_Jl8D8x z+KT~;3%pSZgEJcQw0W5}8z7UJlIjwF{Wg&J#|r+IhbS7{4vs7FF~8UJ&wau+4twAh zM&7rfL#a12;M)0O9^$M8j48Hr*`#*E{Cj6%+}2{qafDNNa9kg3GkZE=pGU!TVXr1N~bRLH~L=^d9N=c{_f0wmu|)I^kvsSv+g1`ONzL{yn<-8 z1Mo^rLKwfr&a)%!flujW0r7 z86HMwFhFbKw>S{RgvBp0heEDNo3~+(=1;XV^KZ-U|B0Gn7><@>-Z2Iktt#TV{K)97 z^L^lkYx-YjHa_%2{_*gpp6NRvTR^AowXuGrS0J(e3lle!M@8DLIN*$*^YH^{gHhK0 z8<9*@lr&17r#Echgw9HG4qI)9*9B-V(LZnNQS=Oe-388 zt1Vi@dT>a{I_!y>4*_vwx}elX?4eBcvO=uar8D$J{(X|JXN$bT=f-XvK*}6}D9DYS}CaQ0X~?=>{=qDnVP-M-Gz5M*gueh zQcn;Nej+Gv@vvuXgZK~NAJV)rp+(#N^ztPS-D<8k_Ww}AbhxB2XI zH*NgCdOcmYUHs2mN8>_H@MYt#%s}W=p?8WDcIvsnTZT&e^)m@nnertr*mk zm{aZePHD1)8Wu9Gunwg{zL7Q~aG$T7noI}4rwf(0k%s{qGhBduoWTc;? zHQTgZ$(t3z?R!HhhUx4+K|?e4T~8{f046Ap7Kt7k#eaiH7uRkrQ=yo*6{d2u{1Rou z#>1C@|3bp_P0v*NxxyPPfWXVo$r0r-^6XT!IbFbUNdpu)0{-hdQCGD?=~i8m5}y{( zBO>xr^%s2pCvOJN3&;%HH?V+q__7OsAa$YlJdi`!WgAMB8C9@xi6-NBHL&OO=C3pu z3IW&BOk+hhUsBI(lN z<#yrMhyTUfzoAvEM#E)1#C*kL8-B6kzc9npO|;#H<}Ojm!2RJ;ed(yR;ty!&?|Xn_ z>2n?_2IY|t8Ly-YZpCl?T@dEFprVV%MP!bjg^nn-Kw&yVVzLO8Ie=`ZwW{@3av z<%}Xan{G-A7bvOy8%rjxql_Fw^A)x~l_LJbz++%d3NT*n$}n>2KyU&7C-}k__azT# z8`!ejEj(%cXY120L4O9aqWTWSn%tYbzZp%#OZnSME_3dGAw=@Itd2^H_-iY$^!}eA z0%(}SB=0%&>G=CP*Z;K$O0F$Bpgj9-kL-7Qc!2ETT%rOpQkK{YsX`XAG$*wd$-Lcu z$Nwb9k&QM3r$k=O@%fJXUy6t(S+1}97@*+dV{{CmkYn*TC1&xc*l~+~UV1&ce)`8b z)~rEJ<8z0x`QQ6z`(Py0KX1LL{ttT2=8x~q0^dj#5RFQ4?vG!R=H>r$>K5I5awt&| zhE>;-EjZ99pmp;py0QHy>~WAG71q2m>M#r^D zCowpEsL3|^w()~5dT$OVEY^ng7wRA&d%CdAAkMNmZ8No3PSr0o2Aru8k@O9?u+Lz z2YH0@izlg)?RerliLJJwHCxSP?NSy04VlX{<|n#+mVA%u-Lhd~8ftV1>ez_kp;Vig z?eAmWlIy#n4sO!Uu8Ok%NNlWvWPw5o0c{D<13h1I&aXoldUa6DysC$YC{+bub>w^) zA^?vLIU0U(ubStqe-`!Xm#>P5?6yaUW5WqlSDoiJG)#RR1FqS(C$oJf{tUj2x!7eY z#HGv#N4;Rb{V`RFGQ7LMJdNJ=hfe}8ZJsF+mq-z#)F!3vWxqHhSpHhn4pq3LTq0kD zwXrD7Yy_sAlZ}!>V&GcsDjAHo6XGy;#I|TM-wTFjZtL^0aYBD$k$F$9@I+}Q?ojs& zO>_$$Xc@L7=1ueZL$m1ig6*|$u|KqUrML)ULZLPIX0a@Sb@7$Z3EpHvk z<@fI2Y99dlHgeyYtFiun6gGJQ=-WZ6D10j)gtPmJ>&Fqa4Z{-aw`aZ@C8>1O?B)i4!H28gw{)1&t ztDAs9_(MZ*MIYGLK`W9fbxqq<&gZFKKAb?ynxpe^+myJ0(e;pAljF`xV#aPWma7DA z)9a!1ix_^EA0f~h8l+-KXsn2|qa-ZHoXxdqSY4YYB(4Ujv#0xZ*a zpG>(jay}-&Mg#Nqo#Uv{1_Jdu*Wd`@d`_%gzbZ5D=M*_Yip|ywM@)XIERK)wn|fos zU#y2+YzQIl@+%ms>Ezh$Wij;ESM^?uYAO{h>tLB%OIhzQ&uBu1rAuuto{{a@IiG0I z$I#;ApX~_oHQ>DedE0n7cl)ykAAWPnY<%l<&$F@QsV#%}bBJmAfHMy528!_7%IK-E zGEL={c~4~*rN&j*1(8LQofaOGn{uk~ zt;aoSaE9UIJBh7T;GM+g;4vVy^Skzni(;?w%A1a4`7!SaSWe>lhE)BrEU&{>_z#<5 zdyvYr*GKT!4u%kL{391la+^_DX_<-DnsVUSD9K*Igw?ts_9l%34vtRCHG4anVLiq7 z`4>qeKI5cPBkCAzW+$v@_PrS$huzMxJqc?kch5hWDJ4P0)!9GMvn^M*o#xt=nF^ma zMZC?Zh=ig5|anF zMD_O6@snR$xL)`aa_AfeZpan76lHw;X_6Ax{PfWhJ3<+S>{Gq5i113)U`#1&b>N0|sWeu~9K)=jP-O8QvfMYbztVJ$fEAS!9(_ zwDC!Y6h6cB7yNv*GCv=!&=WoXw>VK+y&Aqwm#ob|^q;TX-^%W6QoVWEz4G75T&%Zr za>#R!>2}?^gRer=cZZ;R|I>r3cBm|U95ug#K<9qwP2z%Ep$F-&L|gESJtXe~eL!rn z5lVCMvJv@AVY77ZjzF zSndbYz{!_4yZ4YtJZzbG``5DU3ZGbNkY8*2Sg|h&iw#16m{cH-FyP;gv5|tV9Uo)f zO`H{-?&;yh9vz}(LO2zzXpmPx%m8wWqo9vnymQ+}lgjKS;8y>=nBZF&251Pipjv*o zndDhW6d&P`@WgVd`d9d+^l~pV=8W-cFahUo%Y_=fe@sHR=mU`o8XuJa+Rr0*MrLix znC-0}T~dYA_kw|+Qp;aCP+MHwaVwhu*YEOifaLoURJKmIn|mB!{*hNZC~CeY|0WED zN2bPKqbc)xP=Q$Huwtx3Dhsp=RJF?OkQP1&@-n80HUk{l>fEugF0?(9HCm+DYoN-0%(eoPO0S_Rqfr!ilA4 zT@>{ym$>_N8i^jQX`go>MzA*Vrcw-28lY_)|LTEVD0#0;K`M-_lnu+h^d&BfXRMS4 z^xgjld5=~o8IilvNO#g?+YfVl|>&eXIA4RJy;o%A{eVCW)g%Pic zx&9$BvPKD!MbkG^V%~W?*@L)p@47b>Zxb;mu21uA8nAf8aQ*EdS;ucrsvsNZz|d)& z?&hvbN8asrT;$#S#mCBZ-olRlWnZG#_G<>~zZE015yRaeS1)==-TeFA#4?tAPrFTI z)e{B3z23sR8eMYd$C;?tZ!Pysf(evknoqCTZGn=|uiiFod(0wYU-84Bjkqu%G#c72 z--dY4(c|p04J0*-k4J8jDy0|nv6Inv0p6S2Ant^1nuTE3L05T#H8H(RiYZW=vg|{? zu!?2*hx{IXydp(PA+)G@YK$MdB4NMyJw3-@??iw=s+^EA+W1A3Ig(P&C6u}MoAFM+ zTHgHHy+EHHmh{}0CqOEaRp_FUlv2do4u~}sep7i2GCc$-}F4}zT0?1NtzJ{h^;xY9X39Ut@&vBz9u*O9FVLP$9^Y_Z=RiI z0lnBTgJ;-&7~i5af9E@T=1QhUYIX18h6Yax!8biA7T-3i;e+u0_vNPD!hUDaA`pLe zg{giSbs49=FA!6SUO~&ys=-a~E~|@P5!diBFaZIySizSuZq^XC%{vq9U=}bHQ!&Cu zh_LXZS&@aej8)&?^3I!~Iyliu6V%d8`riWUM26yrns!oejjc>3gmU%a^SCar*c8}> z45Ti_d(~K83VxQy2Q6sfV`Eg3Kj-zGW>+BYuefAy`_ZV*K-+M)Q?A6!eNzMG)?>52tm&KjgRXd%LS`#b0$n&qCh z(@9OIQL1v#Bw5OHOg0FJq2Ps}$A$)BV_b>@VrO=l6#6^E7m7hVsQiXuI^;0%%Xbz{ z7W%3NXopbOYZ&;EFN=QW98}p%N41YtT+??0PlH{|!1}8$;dE0Iqnfe={n^c5nFA6# zaU$0_Z*VG^K%P@o^ba2`30`ULXYe8oaUtD?LqmwyQ|v56gcrYmoM4UDCO@s6u_UPb zkEc>V9LkdQEFV6V;?WKSadLOflMhX`djaJSxN{y;AgK`)y0{!BsvpKRvW9`6m8*Z; zOaF^T(X$(Mfd&K(=01&5dMz(sp3}a~a@7*-qPO0^+Hz61hbl#dc@rlZjgT{zbk>2h ztyZ8cM4WWK+Z(!gUFcYyb?J`x2c4p121F9*tuTL8lxLkXG?$^;Pu6(GiHymnL8g;3 zSa|3$D}Zo@&-D`4=E^Ys%u*WfGoYUSrzG~Xe<3m;Vw*21O@6e~5cCXm?mFg$I^I&Y z`wu#4!I;*|rDU{g zY?<{^RmjSF8hxkV(FF=TZ5G^!4Pn9E#F)*XY41OX`_x(fAWTKemC*<%H%0ALAhtr$ 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 BBRK#7 literal 0 HcmV?d00001 diff --git a/python/tests/reference/Rotation/PoleFigures_OR.m b/python/tests/reference/Rotation/PoleFigures_OR.m new file mode 100644 index 000000000..fb2baa6a1 --- /dev/null +++ b/python/tests/reference/Rotation/PoleFigures_OR.m @@ -0,0 +1,99 @@ +%% Import Script for EBSD Data +% +% Use MTEX +clear ; clear all + +%% Specify Crystal and Specimen Symmetries + +% crystal symmetry +CS_bcc = {... + crystalSymmetry('m-3m', [2.8665 2.8665 2.8665], 'mineral', 'Iron-alpha', 'color', 'light blue'),... + crystalSymmetry('m-3m', [1 1 1], 'color', 'light blue')}; + +CS_fcc = {... + crystalSymmetry('m-3m', [3.662 3.662 3.662], 'mineral', 'Iron', 'color', 'light blue'),... + crystalSymmetry('m-3m', [1 1 1], 'color', 'light blue')}; + +% plotting convention +setMTEXpref('xAxisDirection','north'); +setMTEXpref('zAxisDirection','outOfPlane'); + +%% path to files +pname = 'L:\f.gallardo\DAMASK\python\tests\reference\Rotation'; % has to be changed + +% which files to be imported +fname1 = [pname '\bcc_Bain.txt']; fname2 = [pname '\bcc_GT.txt']; fname3 = [pname '\bcc_GT_prime.txt']; +fname4 = [pname '\bcc_KS.txt']; fname5 = [pname '\bcc_NW.txt']; fname6 = [pname '\bcc_Pitsch.txt']; +fname7 = [pname '\fcc_Bain.txt']; fname8 = [pname '\fcc_GT.txt']; fname9 = [pname '\fcc_GT_prime.txt']; +fname10 = [pname '\fcc_KS.txt']; fname11 = [pname '\fcc_NW.txt']; fname12 = [pname '\fcc_Pitsch.txt']; + + +%% Import the Data + +% create an EBSD variable containing the data +ebsd1 = loadEBSD(fname1,CS_bcc,'interface','generic',... + 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', 'Passive Rotation'); +ebsd2 = loadEBSD(fname2,CS_bcc,'interface','generic',... + 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', 'Passive Rotation'); +ebsd3 = loadEBSD(fname3,CS_bcc,'interface','generic',... + 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', 'Passive Rotation'); +ebsd4 = loadEBSD(fname4,CS_bcc,'interface','generic',... + 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', 'Passive Rotation'); +ebsd5 = loadEBSD(fname5,CS_bcc,'interface','generic',... + 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', 'Passive Rotation'); +ebsd6 = loadEBSD(fname6,CS_bcc,'interface','generic',... + 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', 'Passive Rotation'); + +ebsd7 = loadEBSD(fname7,CS_fcc,'interface','generic',... + 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', 'Passive Rotation'); +ebsd8 = loadEBSD(fname8,CS_fcc,'interface','generic',... + 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', 'Passive Rotation'); +ebsd9 = loadEBSD(fname9,CS_fcc,'interface','generic',... + 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', 'Passive Rotation'); +ebsd10 = loadEBSD(fname10,CS_fcc,'interface','generic',... + 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', 'Passive Rotation'); +ebsd11 = loadEBSD(fname11,CS_fcc,'interface','generic',... + 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', 'Passive Rotation'); +ebsd12 = loadEBSD(fname12,CS_fcc,'interface','generic',... + 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', 'Passive Rotation'); + +%% Plot Data 1stpart_bcc +h1 = [Miller(1,0,0,ebsd1.CS),Miller(1,1,0,ebsd1.CS),Miller(1,1,1,ebsd1.CS)]; % 3 pole figures +plotPDF(ebsd1.orientations,h1,'MarkerSize',5,'MarkerColor','r','MarkerEdgeColor','r','DisplayName','BCC-Bain') +hold on +plotPDF(ebsd2.orientations,h1,'MarkerSize',5,'MarkerColor','w','MarkerEdgeColor','b','DisplayName','BCC-GT') +plotPDF(ebsd3.orientations,h1,'MarkerSize',5,'MarkerColor','w','MarkerEdgeColor','g','DisplayName','BCC-GT_Prime') +legend('show','location','southoutside') +cd 'L:\f.gallardo\DAMASK\python\tests\reference\Rotation'; % has to be changed +orient('landscape') +print('-bestfit','1_BCC.pdf','-dpdf') + +%% Plot Data 2nd part_bcc +close +plotPDF(ebsd4.orientations,h1,'MarkerSize',5,'MarkerColor','r','MarkerEdgeColor','w','DisplayName','BCC-KS') +hold on +plotPDF(ebsd5.orientations,h1,'MarkerSize',5,'MarkerColor','w','MarkerEdgeColor','m','DisplayName','BCC-NW') +plotPDF(ebsd6.orientations,h1,'MarkerSize',5,'MarkerColor','y','MarkerEdgeColor','w','DisplayName','BCC-Pitsch') +legend('show','location','southoutside') +print('-bestfit','2_BCC.pdf','-dpdf') + +%% Plot Data 1stpart_fcc +close +h2 = [Miller(1,0,0,ebsd7.CS),Miller(1,1,0,ebsd7.CS),Miller(1,1,1,ebsd7.CS)]; % 3 pole figures +plotPDF(ebsd7.orientations,h2,'MarkerSize',5,'MarkerColor','r','MarkerEdgeColor','r','DisplayName','FCC-Bain') +hold on +plotPDF(ebsd8.orientations,h2,'MarkerSize',5,'MarkerColor','w','MarkerEdgeColor','b','DisplayName','FCC-GT') +plotPDF(ebsd9.orientations,h2,'MarkerSize',5,'MarkerColor','w','MarkerEdgeColor','g','DisplayName','FCC-GT_Prime') +legend('show','location','southoutside') +print('-bestfit','1_FCC.pdf','-dpdf') + +%% Plot Data 2nd part_bcc +close +plotPDF(ebsd10.orientations,h2,'MarkerSize',5,'MarkerColor','r','MarkerEdgeColor','w','DisplayName','FCC-KS') +hold on +plotPDF(ebsd11.orientations,h2,'MarkerSize',5,'MarkerColor','w','MarkerEdgeColor','m','DisplayName','FCC-NW') +plotPDF(ebsd12.orientations,h2,'MarkerSize',5,'MarkerColor','y','MarkerEdgeColor','w','DisplayName','FCC-Pitsch') +legend('show','location','southoutside') +print('-bestfit','2_FCC.pdf','-dpdf') +close + diff --git a/python/tests/reference/Rotation/bcc_GT.txt b/python/tests/reference/Rotation/bcc_GT.txt index d1fe2e1c8..5d5102698 100644 --- a/python/tests/reference/Rotation/bcc_GT.txt +++ b/python/tests/reference/Rotation/bcc_GT.txt @@ -23,4 +23,4 @@ 352.1156357053931 43.82007387041961 14.074783631236542 1 21 77.82610341510008 43.397849654402556 273.4002228089796 1 22 193.60440567265297 9.976439066337806 123.24637065555939 1 23 -153.65751914298576 65.6559553854118 185.90444335627936 1 24 +172.11563570539317 43.82007387041961 194.07478363123653 1 24 diff --git a/python/tests/reference/Rotation/bcc_GT_prime.txt b/python/tests/reference/Rotation/bcc_GT_prime.txt index 42f32bcbb..e398d3139 100644 --- a/python/tests/reference/Rotation/bcc_GT_prime.txt +++ b/python/tests/reference/Rotation/bcc_GT_prime.txt @@ -20,7 +20,7 @@ 183.40022280897963 43.397849654402556 167.8261034151001 1 18 255.92521636876344 43.82007387041961 97.88436429460687 1 19 33.24637065555936 9.976439066337804 283.60440567265294 1 20 -26.291675350407385 65.60048732963618 354.34378938496315 1 21 +356.59977719102034 43.39784965440254 12.173896584899929 1 21 75.92521636876346 43.82007387041961 277.8843642946069 1 22 213.24637065555936 9.976439066337804 103.604405672653 1 23 176.59977719102034 43.397849654402556 192.17389658489986 1 24 diff --git a/python/tests/reference/Rotation/bcc_NW.txt b/python/tests/reference/Rotation/bcc_NW.txt index 76e7c6182..754c69bba 100644 --- a/python/tests/reference/Rotation/bcc_NW.txt +++ b/python/tests/reference/Rotation/bcc_NW.txt @@ -9,6 +9,6 @@ 134.58444405678858 83.13253115922213 96.91733794010702 1 7 225.41555594321142 83.13253115922213 173.082662059893 1 8 0.0 9.735610317245317 135.0 1 9 -260.40196970123213 45.81931182053556 283.6387072794765 1 10 +99.59803029876785 45.81931182053557 166.36129272052355 1 10 260.40196970123213 45.81931182053556 283.6387072794765 1 11 180.0 99.73561031724535 225.0 1 12 diff --git a/python/tests/reference/Rotation/fcc_GT.txt b/python/tests/reference/Rotation/fcc_GT.txt index b91a80c46..cefae431a 100644 --- a/python/tests/reference/Rotation/fcc_GT.txt +++ b/python/tests/reference/Rotation/fcc_GT.txt @@ -23,4 +23,4 @@ 165.92521636876344 43.82007387041961 187.88436429460683 1 21 266.59977719102034 43.39784965440254 102.17389658489992 1 22 56.75362934444064 9.976439066337804 346.395594327347 1 23 -354.0955566437206 65.6559553854118 26.342480857014277 1 24 +345.9252163687635 43.82007387041961 7.884364294606862 1 24 diff --git a/python/tests/reference/Rotation/fcc_GT_prime.txt b/python/tests/reference/Rotation/fcc_GT_prime.txt index 1d6f171c4..44a9b25ec 100644 --- a/python/tests/reference/Rotation/fcc_GT_prime.txt +++ b/python/tests/reference/Rotation/fcc_GT_prime.txt @@ -20,7 +20,7 @@ 12.173896584899929 43.39784965440254 356.59977719102034 1 18 82.11563570539313 43.82007387041961 284.0747836312365 1 19 256.395594327347 9.976439066337804 146.75362934444064 1 20 -185.65621061503683 65.60048732963617 153.70832464959264 1 21 +167.8261034151001 43.397849654402556 183.40022280897963 1 21 262.1156357053931 43.82007387041961 104.07478363123654 1 22 76.39559432734703 9.976439066337806 326.75362934444064 1 23 347.8261034151001 43.39784965440255 3.400222808979685 1 24 diff --git a/python/tests/reference/Rotation/fcc_NW.txt b/python/tests/reference/Rotation/fcc_NW.txt index e041ec0b0..cc9c95a05 100644 --- a/python/tests/reference/Rotation/fcc_NW.txt +++ b/python/tests/reference/Rotation/fcc_NW.txt @@ -9,6 +9,6 @@ 83.082662059893 83.13253115922213 45.415555943211444 1 7 6.917337940106983 83.13253115922211 314.5844440567886 1 8 45.0 9.73561031724532 180.0 1 9 -256.36129272052347 45.81931182053556 279.59803029876775 1 10 +13.638707279476469 45.81931182053557 80.40196970123216 1 10 256.36129272052347 45.81931182053556 279.59803029876775 1 11 315.0 99.73561031724536 0.0 1 12 From a162840ab6c0f2fecc6798b1c07d75c43f25d7d7 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 10 Dec 2019 16:18:44 +0100 Subject: [PATCH 45/78] include some cleaning --- PRIVATE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PRIVATE b/PRIVATE index 524e86c11..a535b399a 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit 524e86c117d816e3bd873eed7663e258a6f2e139 +Subproject commit a535b399a91ef1b117b88332b77bbba90dac83f2 From c46c18de6ffd59497c93c4d55830dbe5606920e3 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 10 Dec 2019 16:20:50 +0100 Subject: [PATCH 46/78] taking care of prospector complaints --- processing/pre/hybridIA_linODFsampling.py | 20 +++++++++---------- .../pre/patchFromReconstructedBoundaries.py | 12 ++++------- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/processing/pre/hybridIA_linODFsampling.py b/processing/pre/hybridIA_linODFsampling.py index caa747337..80d82a458 100755 --- a/processing/pre/hybridIA_linODFsampling.py +++ b/processing/pre/hybridIA_linODFsampling.py @@ -19,7 +19,7 @@ def integerFactorization(i): return j def binAsBins(bin,intervals): - """Explode compound bin into 3D bins list""" + """Explode compound bin into 3D bins list.""" bins = [0]*3 bins[0] = (bin//(intervals[1] * intervals[2])) % intervals[0] bins[1] = (bin//intervals[2]) % intervals[1] @@ -27,17 +27,17 @@ def binAsBins(bin,intervals): return bins def binsAsBin(bins,intervals): - """Implode 3D bins into compound bin""" + """Implode 3D bins into compound bin.""" return (bins[0]*intervals[1] + bins[1])*intervals[2] + bins[2] def EulersAsBins(Eulers,intervals,deltas,center): - """Return list of Eulers translated into 3D bins list""" + """Return list of Eulers translated into 3D bins list.""" return [int((euler+(0.5-center)*delta)//delta)%interval \ for euler,delta,interval in zip(Eulers,deltas,intervals) \ ] def binAsEulers(bin,intervals,deltas,center): - """Compound bin number translated into list of Eulers""" + """Compound bin number translated into list of Eulers.""" Eulers = [0.0]*3 Eulers[2] = (bin%intervals[2] + center)*deltas[2] Eulers[1] = (bin//intervals[2]%intervals[1] + center)*deltas[1] @@ -45,7 +45,7 @@ def binAsEulers(bin,intervals,deltas,center): return Eulers def directInvRepetitions(probability,scale): - """Calculate number of samples drawn by direct inversion""" + """Calculate number of samples drawn by direct inversion.""" nDirectInv = 0 for bin in range(len(probability)): # loop over bins nDirectInv += int(round(probability[bin]*scale)) # calc repetition @@ -56,7 +56,7 @@ def directInvRepetitions(probability,scale): # ----- efficient algorithm --------- def directInversion (ODF,nSamples): - """ODF contains 'dV_V' (normalized to 1), 'center', 'intervals', 'limits' (in radians)""" + """ODF contains 'dV_V' (normalized to 1), 'center', 'intervals', 'limits' (in radians).""" nOptSamples = max(ODF['nNonZero'],nSamples) # random subsampling if too little samples requested nInvSamples = 0 @@ -118,7 +118,7 @@ def directInversion (ODF,nSamples): # ----- trial and error algorithms --------- def MonteCarloEulers (ODF,nSamples): - """ODF contains 'dV_V' (normalized to 1), 'center', 'intervals', 'limits' (in radians)""" + """ODF contains 'dV_V' (normalized to 1), 'center', 'intervals', 'limits' (in radians).""" countMC = 0 maxdV_V = max(ODF['dV_V']) orientations = np.zeros((nSamples,3),'f') @@ -141,7 +141,7 @@ def MonteCarloEulers (ODF,nSamples): def MonteCarloBins (ODF,nSamples): - """ODF contains 'dV_V' (normalized to 1), 'center', 'intervals', 'limits' (in radians)""" + """ODF contains 'dV_V' (normalized to 1), 'center', 'intervals', 'limits' (in radians).""" countMC = 0 maxdV_V = max(ODF['dV_V']) orientations = np.zeros((nSamples,3),'f') @@ -163,7 +163,7 @@ def MonteCarloBins (ODF,nSamples): def TothVanHoutteSTAT (ODF,nSamples): - """ODF contains 'dV_V' (normalized to 1), 'center', 'intervals', 'limits' (in radians)""" + """ODF contains 'dV_V' (normalized to 1), 'center', 'intervals', 'limits' (in radians).""" orientations = np.zeros((nSamples,3),'f') reconstructedODF = np.zeros(ODF['nBins'],'f') unitInc = 1.0/nSamples @@ -235,7 +235,7 @@ if filenames == []: filenames = [None] for name in filenames: try: table = damask.ASCIItable(name = name, buffered = False, readonly=True) - except: + except IOError: continue damask.util.report(scriptName,name) diff --git a/processing/pre/patchFromReconstructedBoundaries.py b/processing/pre/patchFromReconstructedBoundaries.py index e9196916e..b710fb2cb 100755 --- a/processing/pre/patchFromReconstructedBoundaries.py +++ b/processing/pre/patchFromReconstructedBoundaries.py @@ -78,13 +78,11 @@ def rcbOrientationParser(content,idcolumn): damask.util.croak('You might not have chosen the correct column for the grain IDs! '+ 'Please check the "--id" option.') raise - except: - raise return grains def rcbParser(content,M,size,tolerance,idcolumn,segmentcolumn): - """Parser for TSL-OIM reconstructed boundary files""" + """Parser for TSL-OIM reconstructed boundary files.""" # find bounding box boxX = [1.*sys.maxint,-1.*sys.maxint] boxY = [1.*sys.maxint,-1.*sys.maxint] @@ -99,8 +97,6 @@ def rcbParser(content,M,size,tolerance,idcolumn,segmentcolumn): damask.util.croak('You might not have chosen the correct column for the segment end points! '+ 'Please check the "--segment" option.') raise - except: - raise (x[0],y[0]) = (M[0]*x[0]+M[1]*y[0],M[2]*x[0]+M[3]*y[0]) # apply transformation to coordinates (x[1],y[1]) = (M[0]*x[1]+M[1]*y[1],M[2]*x[1]+M[3]*y[1]) # to get rcb --> Euler system boxX[0] = min(boxX[0],x[0],x[1]) @@ -728,7 +724,7 @@ def image(name,imgsize,marginX,marginY,rcData): # ------------------------- def inside(x,y,points): - """Tests whether point(x,y) is within polygon described by points""" + """Tests whether point(x,y) is within polygon described by points.""" inside = False npoints=len(points) (x1,y1) = points[npoints-1] # start with last point of points @@ -750,7 +746,7 @@ def inside(x,y,points): # ------------------------- def fftbuild(rcData,height,xframe,yframe,grid,extrusion): - """Build array of grain numbers""" + """Build array of grain numbers.""" maxX = -1.*sys.maxint maxY = -1.*sys.maxint for line in rcData['point']: # find data range @@ -883,7 +879,7 @@ try: boundaryFile = open(args[0]) boundarySegments = boundaryFile.readlines() boundaryFile.close() -except: +except IOError: damask.util.croak('unable to read boundary file "{}".'.format(args[0])) raise From ac35759c2fab4710d1831e72c49f7d27df773bac Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 10 Dec 2019 17:25:51 +0100 Subject: [PATCH 47/78] not a module subroutine --- src/damage_local.f90 | 2 +- src/damage_nonlocal.f90 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/damage_local.f90 b/src/damage_local.f90 index 5ce27c339..a57bb5c65 100644 --- a/src/damage_local.f90 +++ b/src/damage_local.f90 @@ -215,7 +215,7 @@ end subroutine damage_local_getSourceAndItsTangent !-------------------------------------------------------------------------------------------------- !> @brief writes results to HDF5 output file !-------------------------------------------------------------------------------------------------- -module subroutine damage_local_results(homog,group) +subroutine damage_local_results(homog,group) integer, intent(in) :: homog character(len=*), intent(in) :: group diff --git a/src/damage_nonlocal.f90 b/src/damage_nonlocal.f90 index d7e1aa074..a5e211783 100644 --- a/src/damage_nonlocal.f90 +++ b/src/damage_nonlocal.f90 @@ -252,7 +252,7 @@ end subroutine damage_nonlocal_putNonLocalDamage !-------------------------------------------------------------------------------------------------- !> @brief writes results to HDF5 output file !-------------------------------------------------------------------------------------------------- -module subroutine damage_nonlocal_results(homog,group) +subroutine damage_nonlocal_results(homog,group) integer, intent(in) :: homog character(len=*), intent(in) :: group From 74707b1b00be08413175f0573d4075b11da551bd Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 10 Dec 2019 17:36:25 +0100 Subject: [PATCH 48/78] hybridIA test needs update (no crystallite) --- PRIVATE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PRIVATE b/PRIVATE index a535b399a..be7872952 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit a535b399a91ef1b117b88332b77bbba90dac83f2 +Subproject commit be78729525144accdbcda97e9abc625558af89cb From db91803b807ef016c18cf43460adb85b868f3369 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 10 Dec 2019 17:52:37 +0100 Subject: [PATCH 49/78] cleaning --- PRIVATE | 2 +- src/damage_local.f90 | 38 -------------------------------- src/damage_nonlocal.f90 | 40 --------------------------------- src/homogenization.f90 | 49 ++--------------------------------------- 4 files changed, 3 insertions(+), 126 deletions(-) diff --git a/PRIVATE b/PRIVATE index be7872952..952238b95 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit be78729525144accdbcda97e9abc625558af89cb +Subproject commit 952238b951a3d0c1c79df52530681724d3dead2e diff --git a/src/damage_local.f90 b/src/damage_local.f90 index a57bb5c65..aa9292f49 100644 --- a/src/damage_local.f90 +++ b/src/damage_local.f90 @@ -16,8 +16,6 @@ module damage_local implicit none private - integer, dimension(:,:), allocatable, target, public :: & - damage_local_sizePostResult character(len=64), dimension(:,:), allocatable, target, public :: & damage_local_output integer, dimension(:), allocatable, target, public :: & @@ -43,7 +41,6 @@ module damage_local public :: & damage_local_init, & damage_local_updateState, & - damage_local_postResults, & damage_local_Results contains @@ -68,7 +65,6 @@ subroutine damage_local_init maxNinstance = count(damage_type == DAMAGE_local_ID) if (maxNinstance == 0) return - allocate(damage_local_sizePostResult (maxval(homogenization_Noutput),maxNinstance),source=0) allocate(damage_local_output (maxval(homogenization_Noutput),maxNinstance)) damage_local_output = '' allocate(damage_local_outputID (maxval(homogenization_Noutput),maxNinstance),source=undefined_ID) @@ -92,7 +88,6 @@ subroutine damage_local_init case ('damage') damage_local_output(i,damage_typeInstance(h)) = outputs(i) damage_local_Noutput(instance) = damage_local_Noutput(instance) + 1 - damage_local_sizePostResult(i,damage_typeInstance(h)) = 1 prm%outputID = [prm%outputID , damage_ID] end select @@ -108,7 +103,6 @@ subroutine damage_local_init ! allocate state arrays sizeState = 1 damageState(homog)%sizeState = sizeState - damageState(homog)%sizePostResults = sum(damage_local_sizePostResult(:,instance)) allocate(damageState(homog)%state0 (sizeState,NofMyHomog), source=damage_initialPhi(homog)) allocate(damageState(homog)%subState0(sizeState,NofMyHomog), source=damage_initialPhi(homog)) allocate(damageState(homog)%state (sizeState,NofMyHomog), source=damage_initialPhi(homog)) @@ -239,36 +233,4 @@ subroutine damage_local_results(homog,group) end subroutine damage_local_results -!-------------------------------------------------------------------------------------------------- -!> @brief return array of damage results -!-------------------------------------------------------------------------------------------------- -function damage_local_postResults(ip,el) - - integer, intent(in) :: & - ip, & !< integration point - el !< element - real(pReal), dimension(sum(damage_local_sizePostResult(:,damage_typeInstance(material_homogenizationAt(el))))) :: & - damage_local_postResults - - integer :: instance, homog, offset, o, c - - homog = material_homogenizationAt(el) - offset = damageMapping(homog)%p(ip,el) - instance = damage_typeInstance(homog) - associate(prm => param(instance)) - c = 0 - - outputsLoop: do o = 1,size(prm%outputID) - select case(prm%outputID(o)) - - case (damage_ID) - damage_local_postResults(c+1) = damage(homog)%p(offset) - c = c + 1 - end select - enddo outputsLoop - - end associate - -end function damage_local_postResults - end module damage_local diff --git a/src/damage_nonlocal.f90 b/src/damage_nonlocal.f90 index a5e211783..855fa0ea5 100644 --- a/src/damage_nonlocal.f90 +++ b/src/damage_nonlocal.f90 @@ -19,8 +19,6 @@ module damage_nonlocal implicit none private - integer, dimension(:,:), allocatable, target, public :: & - damage_nonlocal_sizePostResult character(len=64), dimension(:,:), allocatable, target, public :: & damage_nonlocal_output integer, dimension(:), allocatable, target, public :: & @@ -46,7 +44,6 @@ module damage_nonlocal damage_nonlocal_getDiffusion33, & damage_nonlocal_getMobility, & damage_nonlocal_putNonLocalDamage, & - damage_nonlocal_postResults, & damage_nonlocal_Results contains @@ -71,7 +68,6 @@ subroutine damage_nonlocal_init maxNinstance = count(damage_type == DAMAGE_nonlocal_ID) if (maxNinstance == 0) return - allocate(damage_nonlocal_sizePostResult (maxval(homogenization_Noutput),maxNinstance),source=0) allocate(damage_nonlocal_output (maxval(homogenization_Noutput),maxNinstance)) damage_nonlocal_output = '' allocate(damage_nonlocal_Noutput (maxNinstance), source=0) @@ -94,7 +90,6 @@ subroutine damage_nonlocal_init case ('damage') damage_nonlocal_output(i,damage_typeInstance(h)) = outputs(i) damage_nonlocal_Noutput(instance) = damage_nonlocal_Noutput(instance) + 1 - damage_nonlocal_sizePostResult(i,damage_typeInstance(h)) = 1 prm%outputID = [prm%outputID , damage_ID] end select @@ -109,7 +104,6 @@ subroutine damage_nonlocal_init ! allocate state arrays sizeState = 1 damageState(homog)%sizeState = sizeState - damageState(homog)%sizePostResults = sum(damage_nonlocal_sizePostResult(:,instance)) allocate(damageState(homog)%state0 (sizeState,NofMyHomog), source=damage_initialPhi(homog)) allocate(damageState(homog)%subState0(sizeState,NofMyHomog), source=damage_initialPhi(homog)) allocate(damageState(homog)%state (sizeState,NofMyHomog), source=damage_initialPhi(homog)) @@ -248,7 +242,6 @@ subroutine damage_nonlocal_putNonLocalDamage(phi,ip,el) end subroutine damage_nonlocal_putNonLocalDamage - !-------------------------------------------------------------------------------------------------- !> @brief writes results to HDF5 output file !-------------------------------------------------------------------------------------------------- @@ -275,37 +268,4 @@ subroutine damage_nonlocal_results(homog,group) end subroutine damage_nonlocal_results - -!-------------------------------------------------------------------------------------------------- -!> @brief return array of damage results -!-------------------------------------------------------------------------------------------------- -function damage_nonlocal_postResults(ip,el) - - integer, intent(in) :: & - ip, & !< integration point - el !< element - real(pReal), dimension(sum(damage_nonlocal_sizePostResult(:,damage_typeInstance(material_homogenizationAt(el))))) :: & - damage_nonlocal_postResults - - integer :: & - instance, homog, offset, o, c - - homog = material_homogenizationAt(el) - offset = damageMapping(homog)%p(ip,el) - instance = damage_typeInstance(homog) - associate(prm => param(instance)) - c = 0 - - outputsLoop: do o = 1,size(prm%outputID) - select case(prm%outputID(o)) - - case (damage_ID) - damage_nonlocal_postResults(c+1) = damage(homog)%p(offset) - c = c + 1 - end select - enddo outputsLoop - - end associate -end function damage_nonlocal_postResults - end module damage_nonlocal diff --git a/src/homogenization.f90 b/src/homogenization.f90 index 842c5f4b6..5fa723eda 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -39,8 +39,7 @@ module homogenization materialpoint_results !< results array of material point integer, public, protected :: & materialpoint_sizeResults, & - thermal_maxSizePostResults, & - damage_maxSizePostResults + thermal_maxSizePostResults real(pReal), dimension(:,:,:,:), allocatable :: & materialpoint_subF0, & !< def grad of IP at beginning of homogenization increment @@ -196,35 +195,6 @@ subroutine homogenization_init endif endif - i = damage_typeInstance(p) ! which instance of this damage type - valid = .true. ! assume valid - select case(damage_type(p)) ! split per damage type - case (DAMAGE_none_ID) - outputName = DAMAGE_none_label - thisNoutput => null() - thisOutput => null() - thisSize => null() - case (DAMAGE_local_ID) - outputName = DAMAGE_local_label - thisNoutput => damage_local_Noutput - thisOutput => damage_local_output - thisSize => damage_local_sizePostResult - case (DAMAGE_nonlocal_ID) - outputName = DAMAGE_nonlocal_label - thisNoutput => damage_nonlocal_Noutput - thisOutput => damage_nonlocal_output - thisSize => damage_nonlocal_sizePostResult - case default - valid = .false. - end select - if (valid) then - write(FILEUNIT,'(a)') '(damage)'//char(9)//trim(outputName) - if (damage_type(p) /= DAMAGE_none_ID) then - do e = 1,thisNoutput(i) - write(FILEUNIT,'(a,i4)') trim(thisOutput(e,i))//char(9),thisSize(e,i) - enddo - endif - endif endif enddo close(FILEUNIT) @@ -252,15 +222,12 @@ subroutine homogenization_init !-------------------------------------------------------------------------------------------------- ! allocate and initialize global state and postresutls variables thermal_maxSizePostResults = 0 - damage_maxSizePostResults = 0 do p = 1,size(config_homogenization) thermal_maxSizePostResults = max(thermal_maxSizePostResults, thermalState(p)%sizePostResults) - damage_maxSizePostResults = max(damage_maxSizePostResults, damageState (p)%sizePostResults) enddo materialpoint_sizeResults = 1 & ! grain count + 1 + thermal_maxSizePostResults & - + damage_maxSizePostResults & + homogenization_maxNgrains * 2 ! obsolete header information allocate(materialpoint_results(materialpoint_sizeResults,discretization_nIP,discretization_nElem)) @@ -742,8 +709,7 @@ function postResults(ip,el) integer, intent(in) :: & ip, & !< integration point el !< element number - real(pReal), dimension( thermalState (material_homogenizationAt(el))%sizePostResults & - + damageState (material_homogenizationAt(el))%sizePostResults) :: & + real(pReal), dimension( thermalState (material_homogenizationAt(el))%sizePostResults) :: & postResults integer :: & startPos, endPos ,& @@ -766,17 +732,6 @@ function postResults(ip,el) end select chosenThermal - startPos = endPos + 1 - endPos = endPos + damageState(material_homogenizationAt(el))%sizePostResults - chosenDamage: select case (damage_type(material_homogenizationAt(el))) - - case (DAMAGE_local_ID) chosenDamage - postResults(startPos:endPos) = damage_local_postResults(ip, el) - case (DAMAGE_nonlocal_ID) chosenDamage - postResults(startPos:endPos) = damage_nonlocal_postResults(ip, el) - - end select chosenDamage - end function postResults From 4c1281b4fc417e3042c501e2e0c36a25ec1fe742 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 10 Dec 2019 20:04:03 +0100 Subject: [PATCH 50/78] rename changed order in shapes dict. This resulted in wrong column names when writing to ASCII file two fixes (one would be enough): 1) keep order (build new directory) 2) write in order of labels in pandas dataframe, not in order in shapes dict --- python/damask/table.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/python/damask/table.py b/python/damask/table.py index 6181fdb1f..56af8b622 100644 --- a/python/damask/table.py +++ b/python/damask/table.py @@ -203,7 +203,7 @@ class Table(): '' if info is None else ': {}'.format(info), )) - self.shapes[label_new] = self.shapes.pop(label_old) + self.shapes = {(label if label is not label_old else label_new):self.shapes[label] for label in self.shapes} def sort_by(self,labels,ascending=True): @@ -234,8 +234,9 @@ class Table(): Filename or file for reading. """ + seen = set() labels = [] - for l in self.shapes: + for l in [x for x in self.data.columns if not (x in seen or seen.add(x))]: if(self.shapes[l] == (1,)): labels.append('{}'.format(l)) elif(len(self.shapes[l]) == 1): From e142d00d02a4229ceee3203e270ecdc16360902f Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 10 Dec 2019 20:05:24 +0100 Subject: [PATCH 51/78] test now sensible to wrong rename --- python/tests/test_Table.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/python/tests/test_Table.py b/python/tests/test_Table.py index a0dc31975..2046d3803 100644 --- a/python/tests/test_Table.py +++ b/python/tests/test_Table.py @@ -65,11 +65,13 @@ class TestTable: default.add('nine',d,'random data') assert np.allclose(d,default.get('nine')) - def test_rename_equivalent(self,default): - v = default.get('v') - default.rename('v','u') - u = default.get('u') - assert np.all(v == u) + def test_rename_equivalent(self): + x = np.random.random((5,13)) + t = Table(x,{'F':(3,3),'v':(3,),'s':(1,)},['random test data']) + s = t.get('s') + t.rename('s','u') + u = t.get('u') + assert np.all(s == u) def test_rename_gone(self,default): default.rename('v','V') From 8fb8e9be6ea2a3fff9c2d037df9a11f831943d86 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 10 Dec 2019 20:25:19 +0100 Subject: [PATCH 52/78] write temperature to DADF5 --- src/homogenization.f90 | 7 +++++++ src/thermal_adiabatic.f90 | 26 ++++++++++++++++++++++++++ src/thermal_conduction.f90 | 27 +++++++++++++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/src/homogenization.f90 b/src/homogenization.f90 index 5fa723eda..b014bebb5 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -779,6 +779,13 @@ subroutine homogenization_results group = trim(group_base)//'/thermal' call results_closeGroup(results_addGroup(group)) + select case(thermal_type(p)) + case(THERMAL_ADIABATIC_ID) + call thermal_adiabatic_results(p,group) + case(THERMAL_CONDUCTION_ID) + call thermal_conduction_results(p,group) + end select + enddo diff --git a/src/thermal_adiabatic.f90 b/src/thermal_adiabatic.f90 index 2aa69bec5..5c30f280b 100644 --- a/src/thermal_adiabatic.f90 +++ b/src/thermal_adiabatic.f90 @@ -7,6 +7,7 @@ module thermal_adiabatic use config use numerics use material + use results use source_thermal_dissipation use source_thermal_externalheat use crystallite @@ -37,6 +38,7 @@ module thermal_adiabatic thermal_adiabatic_getSourceAndItsTangent, & thermal_adiabatic_getSpecificHeat, & thermal_adiabatic_getMassDensity, & + thermal_adiabatic_results, & thermal_adiabatic_postResults contains @@ -251,6 +253,30 @@ function thermal_adiabatic_getMassDensity(ip,el) end function thermal_adiabatic_getMassDensity +!-------------------------------------------------------------------------------------------------- +!> @brief writes results to HDF5 output file +!-------------------------------------------------------------------------------------------------- +subroutine thermal_adiabatic_results(homog,group) + + integer, intent(in) :: homog + character(len=*), intent(in) :: group +#if defined(PETSc) || defined(DAMASK_HDF5) + integer :: o, instance + + instance = thermal_typeInstance(homog) + + outputsLoop: do o = 1,thermal_adiabatic_Noutput(instance) + select case(thermal_adiabatic_outputID(o,instance)) + + case (temperature_ID) + call results_writeDataset(group,temperature(homog)%p,'T',& + 'temperature','K') + end select + enddo outputsLoop +#endif + +end subroutine thermal_adiabatic_results + !-------------------------------------------------------------------------------------------------- !> @brief return array of thermal results !-------------------------------------------------------------------------------------------------- diff --git a/src/thermal_conduction.f90 b/src/thermal_conduction.f90 index e513d709f..5507d8a7d 100644 --- a/src/thermal_conduction.f90 +++ b/src/thermal_conduction.f90 @@ -7,6 +7,7 @@ module thermal_conduction use material use config use lattice + use results use crystallite use source_thermal_dissipation use source_thermal_externalheat @@ -37,6 +38,7 @@ module thermal_conduction thermal_conduction_getSpecificHeat, & thermal_conduction_getMassDensity, & thermal_conduction_putTemperatureAndItsRate, & + thermal_conduction_results, & thermal_conduction_postResults contains @@ -263,6 +265,31 @@ subroutine thermal_conduction_putTemperatureAndItsRate(T,Tdot,ip,el) end subroutine thermal_conduction_putTemperatureAndItsRate + +!-------------------------------------------------------------------------------------------------- +!> @brief writes results to HDF5 output file +!-------------------------------------------------------------------------------------------------- +subroutine thermal_conduction_results(homog,group) + + integer, intent(in) :: homog + character(len=*), intent(in) :: group +#if defined(PETSc) || defined(DAMASK_HDF5) + integer :: o, instance + + instance = thermal_typeInstance(homog) + + outputsLoop: do o = 1,thermal_conduction_Noutput(instance) + select case(thermal_conduction_outputID(o,instance)) + + case (temperature_ID) + call results_writeDataset(group,temperature(homog)%p,'T',& + 'temperature','K') + end select + enddo outputsLoop +#endif + +end subroutine thermal_conduction_results + !-------------------------------------------------------------------------------------------------- !> @brief return array of thermal results From e3b316bcaeee886f644bae31c19d4dc30d89ca64 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 10 Dec 2019 20:33:44 +0100 Subject: [PATCH 53/78] all tests without spectral Out --- PRIVATE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PRIVATE b/PRIVATE index 952238b95..4c20d48ec 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit 952238b951a3d0c1c79df52530681724d3dead2e +Subproject commit 4c20d48ec1df8230dde85afbc3e7b5efca8cd314 From 9b67ead62f4b7795499d6ae6f7b64ddd9e9c56ad Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 11 Dec 2019 00:10:02 +0100 Subject: [PATCH 54/78] removed postResults completely --- src/CPFEM2.f90 | 1 - src/DAMASK_abaqus.f | 5 +- src/constitutive.f90 | 11 --- src/crystallite.f90 | 8 -- src/grid/DAMASK_grid.f90 | 78 +------------------ src/homogenization.f90 | 150 +------------------------------------ src/prec.f90 | 3 +- src/thermal_adiabatic.f90 | 37 +-------- src/thermal_conduction.f90 | 37 +-------- 9 files changed, 8 insertions(+), 322 deletions(-) diff --git a/src/CPFEM2.f90 b/src/CPFEM2.f90 index 7123602f8..ace3e51f4 100644 --- a/src/CPFEM2.f90 +++ b/src/CPFEM2.f90 @@ -65,7 +65,6 @@ subroutine CPFEM_initAll call constitutive_init call crystallite_init call homogenization_init - call materialpoint_postResults call CPFEM_init end subroutine CPFEM_initAll diff --git a/src/DAMASK_abaqus.f b/src/DAMASK_abaqus.f index e2c56a06e..0f663dde3 100644 --- a/src/DAMASK_abaqus.f +++ b/src/DAMASK_abaqus.f @@ -143,9 +143,6 @@ subroutine UMAT(STRESS,STATEV,DDSDDE,SSE,SPD,SCD,& outdatedByNewInc, & outdatedFFN1, & lastStep - use homogenization, only: & - materialpoint_sizeResults, & - materialpoint_results implicit none integer(pInt), intent(in) :: & @@ -332,7 +329,7 @@ subroutine UMAT(STRESS,STATEV,DDSDDE,SSE,SPD,SCD,& ddsdde(6,:) = ddsdde_h(5,:) end if - statev = materialpoint_results(1:min(nstatv,materialpoint_sizeResults),npt,mesh_FEasCP('elem', noel)) + statev = 0 if (terminallyIll) pnewdt = 0.5_pReal ! force cutback directly ? !$ call omp_set_num_threads(defaultNumThreadsInt) ! reset number of threads to stored default value diff --git a/src/constitutive.f90 b/src/constitutive.f90 index 2d0688467..1fd833f29 100644 --- a/src/constitutive.f90 +++ b/src/constitutive.f90 @@ -93,16 +93,6 @@ subroutine constitutive_init write(6,'(/,a)') ' <<<+- constitutive init -+>>>'; flush(6) - mainProcess: if (worldrank == 0) then -!-------------------------------------------------------------------------------------------------- -! write description file for constitutive output - call IO_write_jobFile(204,'outputConstitutive') - PhaseLoop: do ph = 1,material_Nphase - if (any(material_phaseAt == ph)) write(204,'(/,a,/)') '['//trim(config_name_phase(ph))//']' - enddo PhaseLoop - close(204) - endif mainProcess - constitutive_plasticity_maxSizeDotState = 0 constitutive_source_maxSizeDotState = 0 @@ -123,7 +113,6 @@ subroutine constitutive_init maxval(sourceState(ph)%p(:)%sizeDotState)) enddo PhaseLoop2 - end subroutine constitutive_init diff --git a/src/crystallite.f90 b/src/crystallite.f90 index 4ae87b82e..9b7768e4a 100644 --- a/src/crystallite.f90 +++ b/src/crystallite.f90 @@ -118,7 +118,6 @@ contains !-------------------------------------------------------------------------------------------------- subroutine crystallite_init - integer, parameter :: FILEUNIT=434 logical, dimension(:,:), allocatable :: devNull integer :: & c, & !< counter in integration point component loop @@ -232,13 +231,6 @@ subroutine crystallite_init #endif enddo -!-------------------------------------------------------------------------------------------------- -! write description file for crystallite output - if (worldrank == 0) then - call IO_write_jobFile(FILEUNIT,'outputCrystallite') - write(FILEUNIT,'(/,a,/)') '[not supported anymore]' - close(FILEUNIT) - endif call config_deallocate('material.config/phase') !-------------------------------------------------------------------------------------------------- diff --git a/src/grid/DAMASK_grid.f90 b/src/grid/DAMASK_grid.f90 index 51c97456b..d2a86d769 100644 --- a/src/grid/DAMASK_grid.f90 +++ b/src/grid/DAMASK_grid.f90 @@ -15,11 +15,7 @@ program DAMASK_spectral use config use debug use math - use mesh_grid use CPFEM2 - use FEsolving - use numerics - use homogenization use material use spectral_utilities use grid_mech_spectral_basic @@ -80,12 +76,6 @@ program DAMASK_spectral type(tLoadCase), allocatable, dimension(:) :: loadCases !< array of all load cases type(tLoadCase) :: newLoadCase type(tSolutionState), allocatable, dimension(:) :: solres - integer(MPI_OFFSET_KIND) :: fileOffset - integer(MPI_OFFSET_KIND), dimension(:), allocatable :: outputSize - integer, parameter :: maxByteOut = 2147483647-4096 !< limit of one file output write https://trac.mpich.org/projects/mpich/ticket/1742 - integer, parameter :: maxRealOut = maxByteOut/pReal - integer(pLongInt), dimension(2) :: outputIndex - PetscErrorCode :: ierr procedure(grid_mech_spectral_basic_init), pointer :: & mech_init procedure(grid_mech_spectral_basic_forward), pointer :: & @@ -280,10 +270,8 @@ program DAMASK_spectral enddo if (any(newLoadCase%stress%maskLogical .eqv. & newLoadCase%deformation%maskLogical)) errorID = 831 ! exclusive or masking only - if (any(newLoadCase%stress%maskLogical .and. & - transpose(newLoadCase%stress%maskLogical) .and. & - reshape([ .false.,.true.,.true.,.true.,.false.,.true.,.true.,.true.,.false.],[ 3,3]))) & - errorID = 838 ! no rotation is allowed by stress BC + if (any(newLoadCase%stress%maskLogical .and. transpose(newLoadCase%stress%maskLogical) & + .and. (math_I3<1))) errorID = 838 ! no rotation is allowed by stress BC write(6,'(2x,a)') 'stress / GPa:' do i = 1, 3; do j = 1, 3 if(newLoadCase%stress%maskLogical(i,j)) then @@ -335,26 +323,10 @@ program DAMASK_spectral ! write header of output file if (worldrank == 0) then writeHeader: if (interface_restartInc < 1) then - open(newunit=fileUnit,file=trim(getSolverJobName())//& - '.spectralOut',form='UNFORMATTED',status='REPLACE') - write(fileUnit) 'load:', trim(loadCaseFile) ! ... and write header - write(fileUnit) 'workingdir:', 'n/a' - write(fileUnit) 'geometry:', trim(geometryFile) - write(fileUnit) 'grid:', grid - write(fileUnit) 'size:', geomSize - write(fileUnit) 'materialpoint_sizeResults:', materialpoint_sizeResults - write(fileUnit) 'loadcases:', size(loadCases) - write(fileUnit) 'frequencies:', loadCases%outputfrequency ! one entry per LoadCase - write(fileUnit) 'times:', loadCases%time ! one entry per LoadCase - write(fileUnit) 'logscales:', loadCases%logscale - write(fileUnit) 'increments:', loadCases%incs ! one entry per LoadCase - write(fileUnit) 'startingIncrement:', interface_restartInc ! start with writing out the previous inc - write(fileUnit) 'eoh' - close(fileUnit) ! end of header open(newunit=statUnit,file=trim(getSolverJobName())//'.sta',form='FORMATTED',status='REPLACE') write(statUnit,'(a)') 'Increment Time CutbackLevel Converged IterationsNeeded' ! statistics file if (iand(debug_level(debug_spectral),debug_levelBasic) /= 0) & - write(6,'(/,a)') ' header of result and statistics file written out' + write(6,'(/,a)') ' header of statistics file written out' flush(6) else writeHeader open(newunit=statUnit,file=trim(getSolverJobName())//& @@ -362,40 +334,11 @@ program DAMASK_spectral endif writeHeader endif -!-------------------------------------------------------------------------------------------------- -! prepare MPI parallel out (including opening of file) - allocate(outputSize(worldsize), source = 0_MPI_OFFSET_KIND) - outputSize(worldrank+1) = size(materialpoint_results,kind=MPI_OFFSET_KIND)*int(pReal,MPI_OFFSET_KIND) - call MPI_allreduce(MPI_IN_PLACE,outputSize,worldsize,MPI_LONG,MPI_SUM,PETSC_COMM_WORLD,ierr) ! get total output size over each process - if (ierr /= 0) call IO_error(error_ID=894, ext_msg='MPI_allreduce') - call MPI_file_open(PETSC_COMM_WORLD, trim(getSolverJobName())//'.spectralOut', & - MPI_MODE_WRONLY + MPI_MODE_APPEND, & - MPI_INFO_NULL, & - fileUnit, & - ierr) - if (ierr /= 0) call IO_error(error_ID=894, ext_msg='MPI_file_open') - call MPI_file_get_position(fileUnit,fileOffset,ierr) ! get offset from header - if (ierr /= 0) call IO_error(error_ID=894, ext_msg='MPI_file_get_position') - fileOffset = fileOffset + sum(outputSize(1:worldrank)) ! offset of my process in file (header + processes before me) - call MPI_file_seek (fileUnit,fileOffset,MPI_SEEK_SET,ierr) - if (ierr /= 0) call IO_error(error_ID=894, ext_msg='MPI_file_seek') - writeUndeformed: if (interface_restartInc < 1) then write(6,'(1/,a)') ' ... writing initial configuration to file ........................' call CPFEM_results(0,0.0_pReal) - do i = 1, size(materialpoint_results,3)/(maxByteOut/(materialpoint_sizeResults*pReal))+1 ! slice the output of my process in chunks not exceeding the limit for one output - outputIndex = int([(i-1)*((maxRealOut)/materialpoint_sizeResults)+1, & - min(i*((maxRealOut)/materialpoint_sizeResults),size(materialpoint_results,3))],pLongInt) - call MPI_file_write(fileUnit,reshape(materialpoint_results(:,:,outputIndex(1):outputIndex(2)), & - [(outputIndex(2)-outputIndex(1)+1)*int(materialpoint_sizeResults,pLongInt)]), & - int((outputIndex(2)-outputIndex(1)+1)*int(materialpoint_sizeResults,pLongInt)), & - MPI_DOUBLE, MPI_STATUS_IGNORE, ierr) - if (ierr /= 0) call IO_error(error_ID=894, ext_msg='MPI_file_write') - enddo - fileOffset = fileOffset + sum(outputSize) ! forward to current file position endif writeUndeformed - loadCaseLooping: do currentLoadCase = 1, size(loadCases) time0 = time ! load case start time guess = loadCases(currentLoadCase)%followFormerTrajectory ! change of load case? homogeneous guess for the first inc @@ -526,7 +469,6 @@ program DAMASK_spectral write(6,'(/,a)') ' cutting back ' else ! no more options to continue call IO_warning(850) - call MPI_File_close(fileUnit,ierr) close(statUnit) call quit(0) ! quit endif @@ -546,19 +488,6 @@ program DAMASK_spectral if (mod(inc,loadCases(currentLoadCase)%outputFrequency) == 0) then ! at output frequency write(6,'(1/,a)') ' ... writing results to file ......................................' flush(6) - call materialpoint_postResults() - call MPI_File_seek (fileUnit,fileOffset,MPI_SEEK_SET,ierr) - if (ierr /= 0) call IO_error(894, ext_msg='MPI_file_seek') - do i=1, size(materialpoint_results,3)/(maxByteOut/(materialpoint_sizeResults*pReal))+1 ! slice the output of my process in chunks not exceeding the limit for one output - outputIndex=int([(i-1)*((maxRealOut)/materialpoint_sizeResults)+1, & - min(i*((maxRealOut)/materialpoint_sizeResults),size(materialpoint_results,3))],pLongInt) - call MPI_file_write(fileUnit,reshape(materialpoint_results(:,:,outputIndex(1):outputIndex(2)),& - [(outputIndex(2)-outputIndex(1)+1)*int(materialpoint_sizeResults,pLongInt)]), & - int((outputIndex(2)-outputIndex(1)+1)*int(materialpoint_sizeResults,pLongInt)),& - MPI_DOUBLE, MPI_STATUS_IGNORE, ierr) - if(ierr /=0) call IO_error(894, ext_msg='MPI_file_write') - enddo - fileOffset = fileOffset + sum(outputSize) ! forward to current file position call CPFEM_results(totalIncsCounter,time) endif if (mod(inc,loadCases(currentLoadCase)%restartFrequency) == 0) then @@ -575,7 +504,6 @@ program DAMASK_spectral !-------------------------------------------------------------------------------------------------- ! report summary of whole calculation write(6,'(/,a)') ' ###########################################################################' - call MPI_file_close(fileUnit,ierr) close(statUnit) call quit(0) ! no complains ;) diff --git a/src/homogenization.f90 b/src/homogenization.f90 index b014bebb5..a3a9be2f0 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -35,11 +35,6 @@ module homogenization materialpoint_P !< first P--K stress of IP real(pReal), dimension(:,:,:,:,:,:), allocatable, public :: & materialpoint_dPdF !< tangent of first P--K stress at IP - real(pReal), dimension(:,:,:), allocatable, public :: & - materialpoint_results !< results array of material point - integer, public, protected :: & - materialpoint_sizeResults, & - thermal_maxSizePostResults real(pReal), dimension(:,:,:,:), allocatable :: & materialpoint_subF0, & !< def grad of IP at beginning of homogenization increment @@ -124,7 +119,6 @@ module homogenization public :: & homogenization_init, & materialpoint_stressAndItsTangent, & - materialpoint_postResults, & homogenization_results contains @@ -135,14 +129,6 @@ contains !-------------------------------------------------------------------------------------------------- subroutine homogenization_init - integer, parameter :: FILEUNIT = 200 - integer :: e,i,p - integer, dimension(:,:), pointer :: thisSize - integer, dimension(:) , pointer :: thisNoutput - character(len=64), dimension(:,:), pointer :: thisOutput - character(len=32) :: outputName !< name of output, intermediate fix until HDF5 output is ready - logical :: valid - if (any(homogenization_type == HOMOGENIZATION_NONE_ID)) call mech_none_init if (any(homogenization_type == HOMOGENIZATION_ISOSTRAIN_ID)) call mech_isostrain_init if (any(homogenization_type == HOMOGENIZATION_RGC_ID)) call mech_RGC_init @@ -155,51 +141,6 @@ subroutine homogenization_init if (any(damage_type == DAMAGE_local_ID)) call damage_local_init if (any(damage_type == DAMAGE_nonlocal_ID)) call damage_nonlocal_init -!-------------------------------------------------------------------------------------------------- -! write description file for homogenization output - mainProcess: if (worldrank == 0) then - call IO_write_jobFile(FILEUNIT,'outputHomogenization') - do p = 1,size(config_homogenization) - if (any(material_homogenizationAt == p)) then - write(FILEUNIT,'(/,a,/)') '['//trim(config_name_homogenization(p))//']' - write(FILEUNIT,'(a)') '(type) n/a' - write(FILEUNIT,'(a,i4)') '(ngrains)'//char(9),homogenization_Ngrains(p) - - i = thermal_typeInstance(p) ! which instance of this thermal type - valid = .true. ! assume valid - select case(thermal_type(p)) ! split per thermal type - case (THERMAL_isothermal_ID) - outputName = THERMAL_isothermal_label - thisNoutput => null() - thisOutput => null() - thisSize => null() - case (THERMAL_adiabatic_ID) - outputName = THERMAL_adiabatic_label - thisNoutput => thermal_adiabatic_Noutput - thisOutput => thermal_adiabatic_output - thisSize => thermal_adiabatic_sizePostResult - case (THERMAL_conduction_ID) - outputName = THERMAL_conduction_label - thisNoutput => thermal_conduction_Noutput - thisOutput => thermal_conduction_output - thisSize => thermal_conduction_sizePostResult - case default - valid = .false. - end select - if (valid) then - write(FILEUNIT,'(a)') '(thermal)'//char(9)//trim(outputName) - if (thermal_type(p) /= THERMAL_isothermal_ID) then - do e = 1,thisNoutput(i) - write(FILEUNIT,'(a,i4)') trim(thisOutput(e,i))//char(9),thisSize(e,i) - enddo - endif - endif - - endif - enddo - close(FILEUNIT) - endif mainProcess - call config_deallocate('material.config/homogenization') !-------------------------------------------------------------------------------------------------- @@ -219,19 +160,7 @@ subroutine homogenization_init allocate(materialpoint_converged(discretization_nIP,discretization_nElem), source=.true.) allocate(materialpoint_doneAndHappy(2,discretization_nIP,discretization_nElem), source=.true.) -!-------------------------------------------------------------------------------------------------- -! allocate and initialize global state and postresutls variables - thermal_maxSizePostResults = 0 - do p = 1,size(config_homogenization) - thermal_maxSizePostResults = max(thermal_maxSizePostResults, thermalState(p)%sizePostResults) - enddo - - materialpoint_sizeResults = 1 & ! grain count - + 1 + thermal_maxSizePostResults & - + homogenization_maxNgrains * 2 ! obsolete header information - allocate(materialpoint_results(materialpoint_sizeResults,discretization_nIP,discretization_nElem)) - - write(6,'(/,a)') ' <<<+- homogenization init -+>>>' + write(6,'(/,a)') ' <<<+- homogenization init -+>>>'; flush(6) if (iand(debug_level(debug_homogenization), debug_levelBasic) /= 0) then write(6,'(a32,1x,7(i8,1x))') 'materialpoint_dPdF: ', shape(materialpoint_dPdF) @@ -547,48 +476,6 @@ subroutine materialpoint_stressAndItsTangent(updateJaco,dt) end subroutine materialpoint_stressAndItsTangent -!-------------------------------------------------------------------------------------------------- -!> @brief calculation of result array at material points -!-------------------------------------------------------------------------------------------------- -subroutine materialpoint_postResults - - integer :: & - thePos, & - theSize, & - myNgrains, & - g, & !< grain number - i, & !< integration point number - e !< element number - - elementLooping: do e = FEsolving_execElem(1),FEsolving_execElem(2) - myNgrains = homogenization_Ngrains(material_homogenizationAt(e)) - IpLooping: do i = FEsolving_execIP(1,e),FEsolving_execIP(2,e) - thePos = 0 - - theSize = thermalState (material_homogenizationAt(e))%sizePostResults & - + damageState (material_homogenizationAt(e))%sizePostResults - materialpoint_results(thePos+1,i,e) = real(theSize,pReal) ! tell size of homogenization results - thePos = thePos + 1 - - if (theSize > 0) then ! any homogenization results to mention? - materialpoint_results(thePos+1:thePos+theSize,i,e) = postResults(i,e) - thePos = thePos + theSize - endif - - materialpoint_results(thePos+1,i,e) = real(myNgrains,pReal) ! tell number of grains at materialpoint - thePos = thePos + 1 - - grainLooping :do g = 1,myNgrains - theSize = 2 - materialpoint_results(thePos+1:thePos+theSize,i,e) = 0.0_pReal - thePos = thePos + theSize - enddo grainLooping - enddo IpLooping - enddo elementLooping - -end subroutine materialpoint_postResults - - !-------------------------------------------------------------------------------------------------- !> @brief partition material point def grad onto constituents !-------------------------------------------------------------------------------------------------- @@ -700,41 +587,6 @@ subroutine averageStressAndItsTangent(ip,el) end subroutine averageStressAndItsTangent -!-------------------------------------------------------------------------------------------------- -!> @brief return array of homogenization results for post file inclusion. call only, -!> if homogenization_sizePostResults(i,e) > 0 !! -!-------------------------------------------------------------------------------------------------- -function postResults(ip,el) - - integer, intent(in) :: & - ip, & !< integration point - el !< element number - real(pReal), dimension( thermalState (material_homogenizationAt(el))%sizePostResults) :: & - postResults - integer :: & - startPos, endPos ,& - homog - - - postResults = 0.0_pReal - startPos = 1 - endPos = thermalState(material_homogenizationAt(el))%sizePostResults - chosenThermal: select case (thermal_type(material_homogenizationAt(el))) - - case (THERMAL_adiabatic_ID) chosenThermal - homog = material_homogenizationAt(el) - postResults(startPos:endPos) = & - thermal_adiabatic_postResults(homog,thermal_typeInstance(homog),thermalMapping(homog)%p(ip,el)) - case (THERMAL_conduction_ID) chosenThermal - homog = material_homogenizationAt(el) - postResults(startPos:endPos) = & - thermal_conduction_postResults(homog,thermal_typeInstance(homog),thermalMapping(homog)%p(ip,el)) - - end select chosenThermal - -end function postResults - - !-------------------------------------------------------------------------------------------------- !> @brief writes homogenization results to HDF5 output file !-------------------------------------------------------------------------------------------------- diff --git a/src/prec.f90 b/src/prec.f90 index b6d5d4fdf..8fd2495ce 100644 --- a/src/prec.f90 +++ b/src/prec.f90 @@ -42,8 +42,7 @@ module prec sizeState = 0, & !< size of state sizeDotState = 0, & !< size of dot state, i.e. state(1:sizeDot) follows time evolution by dotState rates offsetDeltaState = 0, & !< index offset of delta state - sizeDeltaState = 0, & !< size of delta state, i.e. state(offset+1:offset+sizeDelta) follows time evolution by deltaState increments - sizePostResults = 0 !< size of output data + sizeDeltaState = 0 !< size of delta state, i.e. state(offset+1:offset+sizeDelta) follows time evolution by deltaState increments real(pReal), pointer, dimension(:), contiguous :: & atolState real(pReal), pointer, dimension(:,:), contiguous :: & ! a pointer is needed here because we might point to state/doState. However, they will never point to something, but are rather allocated and, hence, contiguous diff --git a/src/thermal_adiabatic.f90 b/src/thermal_adiabatic.f90 index 5c30f280b..36dd2316b 100644 --- a/src/thermal_adiabatic.f90 +++ b/src/thermal_adiabatic.f90 @@ -16,8 +16,6 @@ module thermal_adiabatic implicit none private - integer, dimension(:,:), allocatable, target, public :: & - thermal_adiabatic_sizePostResult !< size of each post result output character(len=64), dimension(:,:), allocatable, target, public :: & thermal_adiabatic_output !< name of each post result output @@ -38,8 +36,7 @@ module thermal_adiabatic thermal_adiabatic_getSourceAndItsTangent, & thermal_adiabatic_getSpecificHeat, & thermal_adiabatic_getMassDensity, & - thermal_adiabatic_results, & - thermal_adiabatic_postResults + thermal_adiabatic_results contains @@ -59,7 +56,6 @@ subroutine thermal_adiabatic_init maxNinstance = count(thermal_type == THERMAL_adiabatic_ID) if (maxNinstance == 0) return - allocate(thermal_adiabatic_sizePostResult (maxval(homogenization_Noutput),maxNinstance),source=0) allocate(thermal_adiabatic_output (maxval(homogenization_Noutput),maxNinstance)) thermal_adiabatic_output = '' allocate(thermal_adiabatic_outputID (maxval(homogenization_Noutput),maxNinstance),source=undefined_ID) @@ -77,14 +73,12 @@ subroutine thermal_adiabatic_init thermal_adiabatic_Noutput(instance) = thermal_adiabatic_Noutput(instance) + 1 thermal_adiabatic_outputID(thermal_adiabatic_Noutput(instance),instance) = temperature_ID thermal_adiabatic_output(thermal_adiabatic_Noutput(instance),instance) = outputs(i) - thermal_adiabatic_sizePostResult(thermal_adiabatic_Noutput(instance),instance) = 1 end select enddo ! allocate state arrays sizeState = 1 thermalState(section)%sizeState = sizeState - thermalState(section)%sizePostResults = sum(thermal_adiabatic_sizePostResult(:,instance)) allocate(thermalState(section)%state0 (sizeState,NofMyHomog), source=thermal_initialT(section)) allocate(thermalState(section)%subState0(sizeState,NofMyHomog), source=thermal_initialT(section)) allocate(thermalState(section)%state (sizeState,NofMyHomog), source=thermal_initialT(section)) @@ -277,33 +271,4 @@ subroutine thermal_adiabatic_results(homog,group) end subroutine thermal_adiabatic_results -!-------------------------------------------------------------------------------------------------- -!> @brief return array of thermal results -!-------------------------------------------------------------------------------------------------- -function thermal_adiabatic_postResults(homog,instance,of) result(postResults) - - integer, intent(in) :: & - homog, & - instance, & - of - - real(pReal), dimension(sum(thermal_adiabatic_sizePostResult(:,instance))) :: & - postResults - - integer :: & - o, c - - c = 0 - - do o = 1,thermal_adiabatic_Noutput(instance) - select case(thermal_adiabatic_outputID(o,instance)) - - case (temperature_ID) - postResults(c+1) = temperature(homog)%p(of) - c = c + 1 - end select - enddo - -end function thermal_adiabatic_postResults - end module thermal_adiabatic diff --git a/src/thermal_conduction.f90 b/src/thermal_conduction.f90 index 5507d8a7d..ed25fccde 100644 --- a/src/thermal_conduction.f90 +++ b/src/thermal_conduction.f90 @@ -15,8 +15,6 @@ module thermal_conduction implicit none private - integer, dimension(:,:), allocatable, target, public :: & - thermal_conduction_sizePostResult !< size of each post result output character(len=64), dimension(:,:), allocatable, target, public :: & thermal_conduction_output !< name of each post result output @@ -38,8 +36,7 @@ module thermal_conduction thermal_conduction_getSpecificHeat, & thermal_conduction_getMassDensity, & thermal_conduction_putTemperatureAndItsRate, & - thermal_conduction_results, & - thermal_conduction_postResults + thermal_conduction_results contains @@ -62,7 +59,6 @@ subroutine thermal_conduction_init maxNinstance = count(thermal_type == THERMAL_conduction_ID) if (maxNinstance == 0) return - allocate(thermal_conduction_sizePostResult (maxval(homogenization_Noutput),maxNinstance),source=0) allocate(thermal_conduction_output (maxval(homogenization_Noutput),maxNinstance)) thermal_conduction_output = '' allocate(thermal_conduction_outputID (maxval(homogenization_Noutput),maxNinstance),source=undefined_ID) @@ -80,7 +76,6 @@ subroutine thermal_conduction_init thermal_conduction_Noutput(instance) = thermal_conduction_Noutput(instance) + 1 thermal_conduction_outputID(thermal_conduction_Noutput(instance),instance) = temperature_ID thermal_conduction_output(thermal_conduction_Noutput(instance),instance) = outputs(i) - thermal_conduction_sizePostResult(thermal_conduction_Noutput(instance),instance) = 1 end select enddo @@ -88,7 +83,6 @@ subroutine thermal_conduction_init ! allocate state arrays sizeState = 0 thermalState(section)%sizeState = sizeState - thermalState(section)%sizePostResults = sum(thermal_conduction_sizePostResult(:,instance)) allocate(thermalState(section)%state0 (sizeState,NofMyHomog)) allocate(thermalState(section)%subState0(sizeState,NofMyHomog)) allocate(thermalState(section)%state (sizeState,NofMyHomog)) @@ -290,33 +284,4 @@ subroutine thermal_conduction_results(homog,group) end subroutine thermal_conduction_results - -!-------------------------------------------------------------------------------------------------- -!> @brief return array of thermal results -!-------------------------------------------------------------------------------------------------- -function thermal_conduction_postResults(homog,instance,of) result(postResults) - - integer, intent(in) :: & - homog, & - instance, & - of - - real(pReal), dimension(sum(thermal_conduction_sizePostResult(:,instance))) :: & - postResults - - integer :: & - o, c - - c = 0 - do o = 1,thermal_conduction_Noutput(instance) - select case(thermal_conduction_outputID(o,instance)) - - case (temperature_ID) - postResults(c+1) = temperature(homog)%p(of) - c = c + 1 - end select - enddo - -end function thermal_conduction_postResults - end module thermal_conduction From b3639387f0b89a87159d2d09de6db326c350e6e6 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 11 Dec 2019 08:10:45 +0100 Subject: [PATCH 55/78] including fixed tests for restart --- PRIVATE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PRIVATE b/PRIVATE index 4c20d48ec..84eb17697 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit 4c20d48ec1df8230dde85afbc3e7b5efca8cd314 +Subproject commit 84eb176974a97026f518fc3f2f4d63a1336280b3 From 0b04843c91efb68d59196f8fcee36b4c512236f8 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 11 Dec 2019 08:11:00 +0100 Subject: [PATCH 56/78] pandas is needed for Table class --- python/setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/python/setup.py b/python/setup.py index 515401c59..def343ec1 100644 --- a/python/setup.py +++ b/python/setup.py @@ -15,6 +15,7 @@ setuptools.setup( packages=setuptools.find_packages(), include_package_data=True, install_requires = [ + "pandas", "scipy", "h5py", "vtk" From 5e4e53b9f9cfce4d0b4775d51588891079de0d5d Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 11 Dec 2019 08:17:23 +0100 Subject: [PATCH 57/78] including one more test that works without spectralOut --- PRIVATE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PRIVATE b/PRIVATE index 84eb17697..283c7567f 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit 84eb176974a97026f518fc3f2f4d63a1336280b3 +Subproject commit 283c7567f1e4f6f1893cb5b5efdbbda1682f7533 From 562d216fa934f185a8205f7791e546b52d1303bb Mon Sep 17 00:00:00 2001 From: "f.basile" Date: Wed, 11 Dec 2019 09:23:12 +0100 Subject: [PATCH 58/78] bcc is passive rotation and fcc is active rotation --- .../tests/reference/Rotation/PoleFigures_OR.m | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/python/tests/reference/Rotation/PoleFigures_OR.m b/python/tests/reference/Rotation/PoleFigures_OR.m index fb2baa6a1..7a6d750ad 100644 --- a/python/tests/reference/Rotation/PoleFigures_OR.m +++ b/python/tests/reference/Rotation/PoleFigures_OR.m @@ -1,7 +1,7 @@ %% Import Script for EBSD Data -% -% Use MTEX -clear ; clear all +% +% Start MTEX first in Matlab +clear ; clear all ; close; %% Specify Crystal and Specimen Symmetries @@ -19,7 +19,7 @@ setMTEXpref('xAxisDirection','north'); setMTEXpref('zAxisDirection','outOfPlane'); %% path to files -pname = 'L:\f.gallardo\DAMASK\python\tests\reference\Rotation'; % has to be changed +pname = 'L:\f.gallardo\DAMASK\python\tests\reference\Rotation'; % has to be changed to hwere you have DAMASK % which files to be imported fname1 = [pname '\bcc_Bain.txt']; fname2 = [pname '\bcc_GT.txt']; fname3 = [pname '\bcc_GT_prime.txt']; @@ -45,17 +45,17 @@ ebsd6 = loadEBSD(fname6,CS_bcc,'interface','generic',... 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', 'Passive Rotation'); ebsd7 = loadEBSD(fname7,CS_fcc,'interface','generic',... - 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', 'Passive Rotation'); + 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', 'Active Rotation'); ebsd8 = loadEBSD(fname8,CS_fcc,'interface','generic',... - 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', 'Passive Rotation'); + 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', 'Active Rotation'); ebsd9 = loadEBSD(fname9,CS_fcc,'interface','generic',... - 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', 'Passive Rotation'); + 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', 'Active Rotation'); ebsd10 = loadEBSD(fname10,CS_fcc,'interface','generic',... - 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', 'Passive Rotation'); + 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', 'Active Rotation'); ebsd11 = loadEBSD(fname11,CS_fcc,'interface','generic',... - 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', 'Passive Rotation'); + 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', 'Active Rotation'); ebsd12 = loadEBSD(fname12,CS_fcc,'interface','generic',... - 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', 'Passive Rotation'); + 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', 'Active Rotation'); %% Plot Data 1stpart_bcc h1 = [Miller(1,0,0,ebsd1.CS),Miller(1,1,0,ebsd1.CS),Miller(1,1,1,ebsd1.CS)]; % 3 pole figures From 37e52fd81f16861b45b96d50349d3aa1f1d29a3d Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 22 Oct 2019 23:31:27 +0200 Subject: [PATCH 59/78] polishing --- python/damask/orientation.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/python/damask/orientation.py b/python/damask/orientation.py index 1b08d2937..a63444155 100644 --- a/python/damask/orientation.py +++ b/python/damask/orientation.py @@ -1126,10 +1126,9 @@ class Orientation: return (Orientation(r,self.lattice), i,j, k == 1) if symmetries else r # disorientation ... # ... own sym, other sym, # self-->other: True, self<--other: False - - def inFZ(self): return self.lattice.symmetry.inFZ(self.rotation.asRodrigues(vector=True)) + def equivalentOrientations(self,members=[]): """List of orientations which are symmetrically equivalent.""" @@ -1145,6 +1144,7 @@ class Orientation: """List of orientations related by the given orientation relationship.""" r = self.lattice.relationOperations(model) return [self.__class__(o*self.rotation,r['lattice']) for o in r['rotations']] + def reduced(self): """Transform orientation to fall into fundamental zone according to symmetry.""" @@ -1152,7 +1152,8 @@ class Orientation: if self.lattice.symmetry.inFZ(me.rotation.asRodrigues(vector=True)): break return self.__class__(me.rotation,self.lattice) - + + def inversePole(self, axis, proper = False, From bd12ef83b92a6cc8722099d366945da7f6ce6f1e Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 11 Dec 2019 17:38:31 +0100 Subject: [PATCH 60/78] parametrizing --- .../tests/reference/Rotation/PoleFigures_OR.m | 116 +++++------------- 1 file changed, 29 insertions(+), 87 deletions(-) diff --git a/python/tests/reference/Rotation/PoleFigures_OR.m b/python/tests/reference/Rotation/PoleFigures_OR.m index 7a6d750ad..a17bdd831 100644 --- a/python/tests/reference/Rotation/PoleFigures_OR.m +++ b/python/tests/reference/Rotation/PoleFigures_OR.m @@ -1,99 +1,41 @@ -%% Import Script for EBSD Data -% % Start MTEX first in Matlab -clear ; clear all ; close; -%% Specify Crystal and Specimen Symmetries +tmp = matlab.desktop.editor.getActive; +cd(fileparts(tmp.Filename)); -% crystal symmetry -CS_bcc = {... - crystalSymmetry('m-3m', [2.8665 2.8665 2.8665], 'mineral', 'Iron-alpha', 'color', 'light blue'),... - crystalSymmetry('m-3m', [1 1 1], 'color', 'light blue')}; -CS_fcc = {... - crystalSymmetry('m-3m', [3.662 3.662 3.662], 'mineral', 'Iron', 'color', 'light blue'),... - crystalSymmetry('m-3m', [1 1 1], 'color', 'light blue')}; +%% Specify Crystal +symmetry = {crystalSymmetry('m-3m', [1 1 1], 'mineral', 'Iron', 'color', 'light blue')} % plotting convention setMTEXpref('xAxisDirection','north'); setMTEXpref('zAxisDirection','outOfPlane'); -%% path to files -pname = 'L:\f.gallardo\DAMASK\python\tests\reference\Rotation'; % has to be changed to hwere you have DAMASK -% which files to be imported -fname1 = [pname '\bcc_Bain.txt']; fname2 = [pname '\bcc_GT.txt']; fname3 = [pname '\bcc_GT_prime.txt']; -fname4 = [pname '\bcc_KS.txt']; fname5 = [pname '\bcc_NW.txt']; fname6 = [pname '\bcc_Pitsch.txt']; -fname7 = [pname '\fcc_Bain.txt']; fname8 = [pname '\fcc_GT.txt']; fname9 = [pname '\fcc_GT_prime.txt']; -fname10 = [pname '\fcc_KS.txt']; fname11 = [pname '\fcc_NW.txt']; fname12 = [pname '\fcc_Pitsch.txt']; +lattice_types = {'BCC','FCC'}; +models = {'Bain','GT','GT_prime','KS','NW','Pitsch'}; +rotation = containers.Map; +rotation('BCC') = 'Passive Rotation'; +rotation('FCC') = 'Active Rotation'; -%% Import the Data - -% create an EBSD variable containing the data -ebsd1 = loadEBSD(fname1,CS_bcc,'interface','generic',... - 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', 'Passive Rotation'); -ebsd2 = loadEBSD(fname2,CS_bcc,'interface','generic',... - 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', 'Passive Rotation'); -ebsd3 = loadEBSD(fname3,CS_bcc,'interface','generic',... - 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', 'Passive Rotation'); -ebsd4 = loadEBSD(fname4,CS_bcc,'interface','generic',... - 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', 'Passive Rotation'); -ebsd5 = loadEBSD(fname5,CS_bcc,'interface','generic',... - 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', 'Passive Rotation'); -ebsd6 = loadEBSD(fname6,CS_bcc,'interface','generic',... - 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', 'Passive Rotation'); - -ebsd7 = loadEBSD(fname7,CS_fcc,'interface','generic',... - 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', 'Active Rotation'); -ebsd8 = loadEBSD(fname8,CS_fcc,'interface','generic',... - 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', 'Active Rotation'); -ebsd9 = loadEBSD(fname9,CS_fcc,'interface','generic',... - 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', 'Active Rotation'); -ebsd10 = loadEBSD(fname10,CS_fcc,'interface','generic',... - 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', 'Active Rotation'); -ebsd11 = loadEBSD(fname11,CS_fcc,'interface','generic',... - 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', 'Active Rotation'); -ebsd12 = loadEBSD(fname12,CS_fcc,'interface','generic',... - 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', 'Active Rotation'); - -%% Plot Data 1stpart_bcc -h1 = [Miller(1,0,0,ebsd1.CS),Miller(1,1,0,ebsd1.CS),Miller(1,1,1,ebsd1.CS)]; % 3 pole figures -plotPDF(ebsd1.orientations,h1,'MarkerSize',5,'MarkerColor','r','MarkerEdgeColor','r','DisplayName','BCC-Bain') -hold on -plotPDF(ebsd2.orientations,h1,'MarkerSize',5,'MarkerColor','w','MarkerEdgeColor','b','DisplayName','BCC-GT') -plotPDF(ebsd3.orientations,h1,'MarkerSize',5,'MarkerColor','w','MarkerEdgeColor','g','DisplayName','BCC-GT_Prime') -legend('show','location','southoutside') -cd 'L:\f.gallardo\DAMASK\python\tests\reference\Rotation'; % has to be changed -orient('landscape') -print('-bestfit','1_BCC.pdf','-dpdf') - -%% Plot Data 2nd part_bcc -close -plotPDF(ebsd4.orientations,h1,'MarkerSize',5,'MarkerColor','r','MarkerEdgeColor','w','DisplayName','BCC-KS') -hold on -plotPDF(ebsd5.orientations,h1,'MarkerSize',5,'MarkerColor','w','MarkerEdgeColor','m','DisplayName','BCC-NW') -plotPDF(ebsd6.orientations,h1,'MarkerSize',5,'MarkerColor','y','MarkerEdgeColor','w','DisplayName','BCC-Pitsch') -legend('show','location','southoutside') -print('-bestfit','2_BCC.pdf','-dpdf') - -%% Plot Data 1stpart_fcc -close -h2 = [Miller(1,0,0,ebsd7.CS),Miller(1,1,0,ebsd7.CS),Miller(1,1,1,ebsd7.CS)]; % 3 pole figures -plotPDF(ebsd7.orientations,h2,'MarkerSize',5,'MarkerColor','r','MarkerEdgeColor','r','DisplayName','FCC-Bain') -hold on -plotPDF(ebsd8.orientations,h2,'MarkerSize',5,'MarkerColor','w','MarkerEdgeColor','b','DisplayName','FCC-GT') -plotPDF(ebsd9.orientations,h2,'MarkerSize',5,'MarkerColor','w','MarkerEdgeColor','g','DisplayName','FCC-GT_Prime') -legend('show','location','southoutside') -print('-bestfit','1_FCC.pdf','-dpdf') - -%% Plot Data 2nd part_bcc -close -plotPDF(ebsd10.orientations,h2,'MarkerSize',5,'MarkerColor','r','MarkerEdgeColor','w','DisplayName','FCC-KS') -hold on -plotPDF(ebsd11.orientations,h2,'MarkerSize',5,'MarkerColor','w','MarkerEdgeColor','m','DisplayName','FCC-NW') -plotPDF(ebsd12.orientations,h2,'MarkerSize',5,'MarkerColor','y','MarkerEdgeColor','w','DisplayName','FCC-Pitsch') -legend('show','location','southoutside') -print('-bestfit','2_FCC.pdf','-dpdf') -close - +for lattice = lattice_types + for p = 0:length(models)/3-1 + p + EBSD_data = {loadEBSD(strcat(lattice,'_',models{p*3+1},'.txt'),symmetry,'interface','generic',... + 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', rotation(char(lattice))), + loadEBSD(strcat(lattice,'_',models{p*3+2},'.txt'),symmetry,'interface','generic',... + 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', rotation(char(lattice))), + loadEBSD(strcat(lattice,'_',models{p*3+3},'.txt'),symmetry,'interface','generic',... + 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', rotation(char(lattice)))} + h = [Miller(1,0,0,symmetry{1}),Miller(1,1,0,symmetry{1}),Miller(1,1,1,symmetry{1})]; % 3 pole figures + plotPDF(EBSD_data{1}.orientations,h,'MarkerSize',5,'MarkerColor','r','DisplayName',models{p*3+1}) + hold on + plotPDF(EBSD_data{2}.orientations,h,'MarkerSize',5,'MarkerColor','b','DisplayName',models{p*3+2}) + plotPDF(EBSD_data{3}.orientations,h,'MarkerSize',5,'MarkerColor','g','DisplayName',models{p*3+3}) + legend('show','location','southoutside') + orient('landscape') + print('-bestfit',strcat(int2str(p+1),'_',char(lattice),'.pdf'),'-dpdf') + close + end +end \ No newline at end of file From fcbe4ee5a2950cbafd7e851db81d833b6647b82f Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 11 Dec 2019 18:08:51 +0100 Subject: [PATCH 61/78] [skip ci] polishing --- python/tests/reference/Rotation/PoleFigures_OR.m | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/python/tests/reference/Rotation/PoleFigures_OR.m b/python/tests/reference/Rotation/PoleFigures_OR.m index a17bdd831..74e1365b7 100644 --- a/python/tests/reference/Rotation/PoleFigures_OR.m +++ b/python/tests/reference/Rotation/PoleFigures_OR.m @@ -3,8 +3,6 @@ tmp = matlab.desktop.editor.getActive; cd(fileparts(tmp.Filename)); - -%% Specify Crystal symmetry = {crystalSymmetry('m-3m', [1 1 1], 'mineral', 'Iron', 'color', 'light blue')} % plotting convention @@ -21,14 +19,13 @@ rotation('FCC') = 'Active Rotation'; for lattice = lattice_types for p = 0:length(models)/3-1 - p EBSD_data = {loadEBSD(strcat(lattice,'_',models{p*3+1},'.txt'),symmetry,'interface','generic',... 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', rotation(char(lattice))), loadEBSD(strcat(lattice,'_',models{p*3+2},'.txt'),symmetry,'interface','generic',... 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', rotation(char(lattice))), loadEBSD(strcat(lattice,'_',models{p*3+3},'.txt'),symmetry,'interface','generic',... 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', rotation(char(lattice)))} - h = [Miller(1,0,0,symmetry{1}),Miller(1,1,0,symmetry{1}),Miller(1,1,1,symmetry{1})]; % 3 pole figures + h = [Miller(1,0,0,symmetry{1}),Miller(1,1,0,symmetry{1}),Miller(1,1,1,symmetry{1})]; % 3 pole figures plotPDF(EBSD_data{1}.orientations,h,'MarkerSize',5,'MarkerColor','r','DisplayName',models{p*3+1}) hold on plotPDF(EBSD_data{2}.orientations,h,'MarkerSize',5,'MarkerColor','b','DisplayName',models{p*3+2}) @@ -38,4 +35,4 @@ for lattice = lattice_types print('-bestfit',strcat(int2str(p+1),'_',char(lattice),'.pdf'),'-dpdf') close end -end \ No newline at end of file +end From a0a99c526b285965e2647047bcd29f413802fdf2 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 11 Dec 2019 19:24:29 +0100 Subject: [PATCH 62/78] some remaining IntOut format strings --- PRIVATE | 2 +- src/IO.f90 | 23 +------------------- src/grid/grid_mech_FEM.f90 | 3 +-- src/grid/grid_mech_spectral_basic.f90 | 3 +-- src/grid/grid_mech_spectral_polarisation.f90 | 3 +-- 5 files changed, 5 insertions(+), 29 deletions(-) diff --git a/PRIVATE b/PRIVATE index 283c7567f..f60209558 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit 283c7567f1e4f6f1893cb5b5efdbbda1682f7533 +Subproject commit f602095584e1d8c4f96e5746d6a199bd3bc029c3 diff --git a/src/IO.f90 b/src/IO.f90 index 8973860c2..c121cc65e 100644 --- a/src/IO.f90 +++ b/src/IO.f90 @@ -32,8 +32,7 @@ module IO IO_intValue, & IO_lc, & IO_error, & - IO_warning, & - IO_intOut + IO_warning #if defined(Marc4DAMASK) || defined(Abaqus) public :: & IO_open_inputFile, & @@ -542,26 +541,6 @@ pure function IO_lc(string) end function IO_lc -!-------------------------------------------------------------------------------------------------- -!> @brief returns format string for integer values without leading zeros -!> @details deprecated, use '(i0)' format specifier -!-------------------------------------------------------------------------------------------------- -pure function IO_intOut(intToPrint) - - integer, intent(in) :: intToPrint - character(len=41) :: IO_intOut - integer :: N_digits - character(len=19) :: width ! maximum digits for 64 bit integer - character(len=20) :: min_width ! longer for negative values - - N_digits = 1 + int(log10(real(max(abs(intToPrint),1)))) - write(width, '(I19.19)') N_digits - write(min_width, '(I20.20)') N_digits + merge(1,0,intToPrint < 0) - IO_intOut = 'I'//trim(min_width)//'.'//trim(width) - -end function IO_intOut - - !-------------------------------------------------------------------------------------------------- !> @brief write error statements to standard out and terminate the Marc/spectral run with exit #9xxx !> in ABAQUS either time step is reduced or execution terminated diff --git a/src/grid/grid_mech_FEM.f90 b/src/grid/grid_mech_FEM.f90 index f6074fee9..a34d880f7 100644 --- a/src/grid/grid_mech_FEM.f90 +++ b/src/grid/grid_mech_FEM.f90 @@ -476,8 +476,7 @@ subroutine formResidual(da_local,x_local, & ! begin of new iteration newIteration: if (totalIter <= PETScIter) then totalIter = totalIter + 1 - write(6,'(1x,a,3(a,'//IO_intOut(itmax)//'))') & - trim(incInfo), ' @ Iteration ', itmin, '≤',totalIter+1, '≤', itmax + write(6,'(1x,a,3(a,i0))') trim(incInfo), ' @ Iteration ', itmin, '≤',totalIter+1, '≤', itmax if (iand(debug_level(debug_spectral),debug_spectralRotation) /= 0) & write(6,'(/,a,/,3(3(f12.7,1x)/))',advance='no') & ' deformation gradient aim (lab) =', transpose(params%rotation_BC%rotTensor2(F_aim,active=.true.)) diff --git a/src/grid/grid_mech_spectral_basic.f90 b/src/grid/grid_mech_spectral_basic.f90 index fb69427e3..f05f9bc93 100644 --- a/src/grid/grid_mech_spectral_basic.f90 +++ b/src/grid/grid_mech_spectral_basic.f90 @@ -440,8 +440,7 @@ subroutine formResidual(in, F, & ! begin of new iteration newIteration: if (totalIter <= PETScIter) then totalIter = totalIter + 1 - write(6,'(1x,a,3(a,'//IO_intOut(itmax)//'))') & - trim(incInfo), ' @ Iteration ', itmin, '≤',totalIter, '≤', itmax + write(6,'(1x,a,3(a,i0))') trim(incInfo), ' @ Iteration ', itmin, '≤',totalIter, '≤', itmax if (iand(debug_level(debug_spectral),debug_spectralRotation) /= 0) & write(6,'(/,a,/,3(3(f12.7,1x)/))',advance='no') & ' deformation gradient aim (lab) =', transpose(params%rotation_BC%rotTensor2(F_aim,active=.true.)) diff --git a/src/grid/grid_mech_spectral_polarisation.f90 b/src/grid/grid_mech_spectral_polarisation.f90 index ed2e0e1a9..33c3e4e72 100644 --- a/src/grid/grid_mech_spectral_polarisation.f90 +++ b/src/grid/grid_mech_spectral_polarisation.f90 @@ -509,8 +509,7 @@ subroutine formResidual(in, FandF_tau, & ! begin of new iteration newIteration: if (totalIter <= PETScIter) then totalIter = totalIter + 1 - write(6,'(1x,a,3(a,'//IO_intOut(itmax)//'))') & - trim(incInfo), ' @ Iteration ', itmin, '≤',totalIter, '≤', itmax + write(6,'(1x,a,3(a,i0))') trim(incInfo), ' @ Iteration ', itmin, '≤',totalIter, '≤', itmax if (iand(debug_level(debug_spectral),debug_spectralRotation) /= 0) & write(6,'(/,a,/,3(3(f12.7,1x)/))',advance='no') & ' deformation gradient aim (lab) =', transpose(params%rotation_BC%rotTensor2(F_aim,active=.true.)) From 1d7010778e446d2d95aa441560da31a0e48eedc9 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 11 Dec 2019 19:43:23 +0100 Subject: [PATCH 63/78] [skip ci] silence annoying warnings --- python/damask/dadf5.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/damask/dadf5.py b/python/damask/dadf5.py index beced188d..278a4d89d 100644 --- a/python/damask/dadf5.py +++ b/python/damask/dadf5.py @@ -360,7 +360,7 @@ class DADF5(): f[k] path.append(k) except KeyError as e: - print('unable to locate geometry dataset: {}'.format(str(e))) + pass for o,p in zip(['constituents','materialpoints'],['con_physics','mat_physics']): for oo in self.iter_visible(o): for pp in self.iter_visible(p): @@ -369,7 +369,7 @@ class DADF5(): f[k] path.append(k) except KeyError as e: - print('unable to locate {} dataset: {}'.format(o,str(e))) + pass return path From 674d800ceafff78f10d361034128d9e0c9524967 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 11 Dec 2019 20:52:45 +0100 Subject: [PATCH 64/78] fix for test needed --- PRIVATE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PRIVATE b/PRIVATE index f60209558..a4a216604 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit f602095584e1d8c4f96e5746d6a199bd3bc029c3 +Subproject commit a4a216604ca07f6391c209fa75b593c8e8a887e5 From 186605610d69e13fd735f3646fde5764cb7a79bd Mon Sep 17 00:00:00 2001 From: Vitesh Shah Date: Fri, 13 Dec 2019 09:53:47 +0100 Subject: [PATCH 65/78] No phase name for generic datasets --- processing/post/DADF5_vtk_cells.py | 5 ++++- processing/post/DADF5_vtk_points.py | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/processing/post/DADF5_vtk_cells.py b/processing/post/DADF5_vtk_cells.py index b8875f4e9..9e8585773 100755 --- a/processing/post/DADF5_vtk_cells.py +++ b/processing/post/DADF5_vtk_cells.py @@ -2,6 +2,7 @@ import os import argparse +import re import h5py import numpy as np @@ -89,10 +90,12 @@ for filename in options.filenames: x = results.get_dataset_location(label) if len(x) == 0: continue + ph_name = re.compile(r'(\/[1-9])_([A-Z][a-z]*)_(([a-z]*)|([A-Z]*))') #looking for phase name in dataset name array = results.read_dataset(x,0) shape = [array.shape[0],np.product(array.shape[1:])] vtk_data.append(numpy_support.numpy_to_vtk(num_array=array.reshape(shape),deep=True,array_type= vtk.VTK_DOUBLE)) - vtk_data[-1].SetName('1_'+x[0].split('/',1)[1]) + dset_name = '1_' + re.sub(ph_name,r'',x[0].split('/',1)[1]) #removing phase name from generic dataset + vtk_data[-1].SetName(dset_name) grid.GetCellData().AddArray(vtk_data[-1]) results.set_visible('constituents', False) diff --git a/processing/post/DADF5_vtk_points.py b/processing/post/DADF5_vtk_points.py index 9265cc3a0..908474336 100755 --- a/processing/post/DADF5_vtk_points.py +++ b/processing/post/DADF5_vtk_points.py @@ -2,6 +2,7 @@ import os import argparse +import re import numpy as np import vtk @@ -76,10 +77,12 @@ for filename in options.filenames: x = results.get_dataset_location(label) if len(x) == 0: continue + ph_name = re.compile(r'(\/[1-9])_([A-Z][a-z]*)_(([a-z]*)|([A-Z]*))') #looking for phase name in dataset name array = results.read_dataset(x,0) shape = [array.shape[0],np.product(array.shape[1:])] vtk_data.append(numpy_support.numpy_to_vtk(num_array=array.reshape(shape),deep=True,array_type= vtk.VTK_DOUBLE)) - vtk_data[-1].SetName('1_'+x[0].split('/',1)[1]) + dset_name = '1_' + re.sub(ph_name,r'',x[0].split('/',1)[1]) #removing phase name from generic dataset + vtk_data[-1].SetName(dset_name) Polydata.GetCellData().AddArray(vtk_data[-1]) results.set_visible('constituents', False) From b14c15fd9ee6720d79677ed30d4558e3928269a5 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 13 Dec 2019 12:15:45 +0100 Subject: [PATCH 66/78] directly output DADF5 to vtk from python --- python/damask/dadf5.py | 120 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) diff --git a/python/damask/dadf5.py b/python/damask/dadf5.py index beced188d..1142d02b4 100644 --- a/python/damask/dadf5.py +++ b/python/damask/dadf5.py @@ -1,7 +1,10 @@ from queue import Queue import re import glob +import os +import vtk +from vtk.util import numpy_support import h5py import numpy as np @@ -841,3 +844,120 @@ class DADF5(): N_added +=1 pool.wait_completion() + + + def to_vtk(self,labels): + """ + Export to vtk cell data. + + Parameters + ---------- + labels : list of str + Labels of the datasets to be exported. + + """ + if self.structured: + + coordArray = [vtk.vtkDoubleArray(),vtk.vtkDoubleArray(),vtk.vtkDoubleArray()] + for dim in [0,1,2]: + for c in np.linspace(0,self.size[dim],1+self.grid[dim]): + coordArray[dim].InsertNextValue(c) + + grid = vtk.vtkRectilinearGrid() + grid.SetDimensions(*(self.grid+1)) + grid.SetXCoordinates(coordArray[0]) + grid.SetYCoordinates(coordArray[1]) + grid.SetZCoordinates(coordArray[2]) + + else: + + nodes = vtk.vtkPoints() + with h5py.File(self.fname) as f: + nodes.SetData(numpy_support.numpy_to_vtk(f['/geometry/x_n'][()],deep=True)) + + grid = vtk.vtkUnstructuredGrid() + grid.SetPoints(nodes) + grid.Allocate(f['/geometry/T_c'].shape[0]) + for i in f['/geometry/T_c']: + grid.InsertNextCell(vtk.VTK_HEXAHEDRON,8,i-1) # not for all elements! + + N_digits = int(np.floor(np.log10(int(self.increments[-1][3:]))))+1 + + for i,inc in enumerate(self.iter_visible('increments')): + vtk_data = [] + + materialpoints_backup = self.visible['materialpoints'].copy() + self.set_visible('materialpoints',False) + for label in labels: + for p in self.iter_visible('con_physics'): + if p != 'generic': + for c in self.iter_visible('constituents'): + x = self.get_dataset_location(label) + if len(x) == 0: + continue + array = self.read_dataset(x,0) + shape = [array.shape[0],np.product(array.shape[1:])] + vtk_data.append(numpy_support.numpy_to_vtk(num_array=array.reshape(shape), + deep=True,array_type= vtk.VTK_DOUBLE)) + vtk_data[-1].SetName('1_'+x[0].split('/',1)[1]) #ToDo: hard coded 1! + grid.GetCellData().AddArray(vtk_data[-1]) + else: + x = self.get_dataset_location(label) + if len(x) == 0: + continue + array = self.read_dataset(x,0) + shape = [array.shape[0],np.product(array.shape[1:])] + vtk_data.append(numpy_support.numpy_to_vtk(num_array=array.reshape(shape), + deep=True,array_type= vtk.VTK_DOUBLE)) + ph_name = re.compile(r'(\/[1-9])_([A-Z][a-z]*)_(([a-z]*)|([A-Z]*))') #looking for phase name in dataset name + dset_name = '1_' + re.sub(ph_name,r'',x[0].split('/',1)[1]) #removing phase name from generic dataset + vtk_data[-1].SetName(dset_name) + grid.GetCellData().AddArray(vtk_data[-1]) + self.set_visible('materialpoints',materialpoints_backup) + + constituents_backup = self.visible['constituents'].copy() + self.set_visible('constituents',False) + for label in labels: + for p in self.iter_visible('mat_physics'): + if p != 'generic': + for m in self.iter_visible('materialpoints'): + x = self.get_dataset_location(label) + if len(x) == 0: + continue + array = self.read_dataset(x,0) + shape = [array.shape[0],np.product(array.shape[1:])] + vtk_data.append(numpy_support.numpy_to_vtk(num_array=array.reshape(shape), + deep=True,array_type= vtk.VTK_DOUBLE)) + vtk_data[-1].SetName('1_'+x[0].split('/',1)[1]) #ToDo: why 1_? + grid.GetCellData().AddArray(vtk_data[-1]) + else: + x = self.get_dataset_location(label) + if len(x) == 0: + continue + array = self.read_dataset(x,0) + shape = [array.shape[0],np.product(array.shape[1:])] + vtk_data.append(numpy_support.numpy_to_vtk(num_array=array.reshape(shape), + deep=True,array_type= vtk.VTK_DOUBLE)) + vtk_data[-1].SetName('1_'+x[0].split('/',1)[1]) + grid.GetCellData().AddArray(vtk_data[-1]) + self.set_visible('constituents',constituents_backup) + + writer = vtk.vtkXMLRectilinearGridWriter() if self.structured else \ + vtk.vtkXMLUnstructuredGridWriter() + + x = self.get_dataset_location('u_n') + vtk_data.append(numpy_support.numpy_to_vtk(num_array=self.read_dataset(x,0), + deep=True,array_type=vtk.VTK_DOUBLE)) + vtk_data[-1].SetName('u') + grid.GetPointData().AddArray(vtk_data[-1]) + + file_out = '{}_inc{}.{}'.format(os.path.splitext(os.path.basename(self.fname))[0], + inc[3:].zfill(N_digits), + writer.GetDefaultFileExtension()) + + writer.SetCompressorTypeToZLib() + writer.SetDataModeToBinary() + writer.SetFileName(file_out) + writer.SetInputData(grid) + + writer.Write() From 0c30f6b1dfc52cc399a08bf479e239f29abf36ff Mon Sep 17 00:00:00 2001 From: "f.basile" Date: Fri, 13 Dec 2019 12:52:33 +0100 Subject: [PATCH 67/78] Polishing Mtex script for plotting pole figures. --- python/tests/reference/Rotation/1_BCC.pdf | Bin 44551 -> 43263 bytes python/tests/reference/Rotation/1_FCC.pdf | Bin 44391 -> 43263 bytes python/tests/reference/Rotation/2_BCC.pdf | Bin 43118 -> 43017 bytes python/tests/reference/Rotation/2_FCC.pdf | Bin 43107 -> 43017 bytes .../tests/reference/Rotation/PoleFigures_OR.m | 10 +++++----- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/python/tests/reference/Rotation/1_BCC.pdf b/python/tests/reference/Rotation/1_BCC.pdf index fe22f6a2e36d180c423a1902b1a7409f866ff324..599b892105907e96d19f52b7d927dafda0500d7c 100644 GIT binary patch literal 43263 zcmaI7WmFzZ6Dn8eD?~g1fuBySqzpcL+{!O>lSTa&pdl*Z1SD@7Ju= zJzcfCYFG8ln%NXeViF9@jBKzJ6_r)hu*}3jVmo6iSUx^jCM5?uQ)d%12V!brdn1#t zX2cSTO2isw4vv;~--uZl*%*NgstUqNs#1z-Jj9=7#OzF*ZOy(pNjezWf3-AmWD%o* zWfFBTGjjS|AZFxbMocZn!vbXHW@ce#WoBVxWnrZQGE)J8R5Y*x0QVo~ko*p_x{?71j+dj9UkeZi};`S9ZS#vQqNVuRR+KWalqM=i_;p1j}@sScmA5CH*r{e}HuYyoW z6dMu6#{lPcI%H`3TqX_m=r;Uo;w6$Vbk`75zu_6MSE+&VOq%5da@L+j!WLAHauIOg zL`gdkRh;zU?XsLft9RD;m@R%37lD8={8e#T??S{ESX!CLsUlISGfm4Zn^YF^wFpY#Kc*11ApkU z+yDAkY#&TX&*8u4fTMQ``JzbCQ1g?loQdVF#ObtG|rVHB3uhV2GKA^m`N`R=o(SOY zlmHQQ%p?~>L^JO21rvhMk!&sOBcj9sKeUcg8~A406++vsO#ho-b^X%o6-KaAIu;hK zp5kH)o3cMW&`vqWalhjjNtblw#_1W<_YK5%+HQtdF8V4C6m%wM52*@mZIg{plSK`k zEBjk3<703Tx8WfelvY&BOqm9L(YGu<&Qby_LkgrJ;>vm^oynRW>3~S{^*0S$pt`=A zVNb_d?-Z#BeNxp~qz(^Iq> zi=M2Sys@ytss&32HOK7B!;|jFp8d^_&ObMp^=4TDvA-_(2=upx9Y+nZk*MrPZPGyY z;SQ)wzbtqieJk;%fQNrRfqK=cJ0~9Hdvxbn;y$MfBH0y?xm%AFs46IucU#+ZdIupR z?5Pd>F6J_G0v0I{%#4U@5p}S5R{wL96nDZDDUs_s>7?@j6Qgj5CS%)c#5ZDdY zxRf*}MM^IhXIASgN+OLEx$QWGw!liFlV9gz%OB!L*2~_SCuzy;I@fD>H9emH3>E%0 z0JVS;!9lZ!W&5`#-9`6Sr~y**c~2R=Ekao@G_30`}!8B21+MxwJbfOgUK75dkeX8$D%KM-gvv<$>THUv_P6w1?UWAO^F zXcaua{xmcd&iiOZgQTm3k%`J+Th@M;;jtO|`c)X@9`Qm#TSvB+NMQY|75CJ8L*LS_ zdtK=cP87qu!V!=!uz9G-7!~3osqIgMi!I5|`y~@$GW|LZ+Q7&$5%F^t9F2wA6k;sS z(DUwwA4-T?WAe&~kYR^XFUR;($vZ(VcB*Tfjm7=boIOu$VcU)_#S9;PJ{5hmf!684 zPyHe$tM7D?3M;;606+hIx?2Azd2>za!o|C=E2PD|CbE1@q#m!CQa40t{0JYV-i*AY z7D|K&{kO1&uDu_Wd%Ozb+FRex$6sSk=Ry>|yRpT{kQZ{Rt1M8a1u*$&>K*e6$wZ&S zvpm;EZO@UR1rt3mBPEvae)w|qlC853R1`r7WNy*ck64^k=FoA|juSs$VL_I?8biE; zPE2Gek2BP`nDmRQR3Rdfw+Pb672K|e@iwN;-;gkID0>JC%`ro3I#IN=AC2hxn9nuKj>6W6f(-^6FrX*?)GB+l~6p@EImq=aSr6FR_ka0+c zfESTX6qSC15-o+M-FXdna-&H2cE1#;$Ww1C&d=OPbYSzNXeKed4zUbiIrBg@-cqBa z#;q>mlw^lcG_`XhL3UwLrTCCJOkaqc0+f8^dS*p~wNV+Oh8&9FtU#uKXonPlc22|M z{&7a2lI)FOc%_YQCRvuIqrxmp4}dDn4%frJoWa)S0@zo`3l%jdQ9BP#X->-EO> z!^q&{YM|>~@CR${$6n|Z$jL+>ZW5}YJ*~4G-l3}902XR`; z%aiw|2ZAz1g9~C~G9zE76GDk~f2jGb%3_R$kqeKN25>@;Wsh;B4lO~J!IEe%>23q} z#Z;u~TyBYlV4c8d*DYja`q}C_P5VJpi2Nb=f@DyWLCDD)Vbl9Sob13S;UKY5;MuxE zN0T5WrC=drs7Xd2!F2D!hW7YqfX=|3`nLqC&F#~@K;ph!rZIFn@(eUUT9TZ~P&>U} zcw7|uwQd-;huLB)I#bxyBVE5ZH3$v$D~+5ibrux3jxjlfi5up7R-9iDd`Vz1lN}e8 zC{t`w7&O!>Xk`q#9f`$7a6Mrk5f)z(xb#d6VgZVT+c26vGqPJE_^b!91a-=oeHx2T zxVyd>8Oa1OkTML-Pdd2>oqQjyD$#-h&mMuCnuZH3fsLG|aWxJ<30qoV0L(-g8YTkP zxPSZ4m#}tZ1w5RNKt4k!?Q^+lxRx-N7x>;MB{iXK!@iVw0M9H()^bio=LU z51Agd7pf;{CN<`W(V)FhYiHBwJ?DE_D2HqRmokDq8_3oaN%3{GrnfPRp&GdlgwY1m&K zuyKIH^PXl;>&?nDp2M!lrrms(_+&Pg^B5t2toVA#5?CUY9<$=0Sws5(%^+kpl#lcm ztTXubu|n5HAQRgPf$8x_P{h@peztP7VCVf`0@aah&-=uA4tNVOeXgq(A^#D!` z#Bz<77fNQ}^nYmP!_zwRb@w-<`kyskvpUIh1MA?dCWPKZ*e@+$)mi1VZP4AoKzX#O zFWpGH72t(nLc)|}hT#K;#rTcK9wTgs{3-o6DIkWYZ+d2yPZch zTB_iL;K?6TU@q-(NqLR=Jk5Sv;1{WaRgw4%&&$|z!$HL8!Ru=Jqf^G1e31@jRNQyC zsvTWbAA(!98g7izB55=QcL7&OoWe!HP8!NMVg;M`qoV&R<>Zp! z6>KRk<@ZxPz}tb4Ng+${4Im1&-h*ls`J|(~72eMGBo|Myq%AW9#qB*BChrLG=?%Km1Mp6={54EGiF zr4z`xT%c(_FYTW~3Fy_4fvDi_YT*5VMe8Y$Ux(|DtL4OigSlP=s$M~W-sgf-H1BX# zQH^#Yp(RnPN@ruED^4uVK=7m!Sf9xie43zAK&5Ab`EZp;GTB5o3y` zRw=bFMDosF-aw_;OTuDqfD$8*hgYL2O!_A%@}(>r!HV#pM6qwhBgpV6Bk|8_0;uzu z(7&d1`vlGW(kMU301V}x)UP^b2kic2*WGAq5w0Jp2+cTc2brEKr?TR@3sq|W=FfA^ zb8vvPoLdu{*WZx?R_ufUS-r)M2mQ3*QHQRF2U~0{laX2@A}piVF-PfK4JX6L&cdLr zxhQgMg@68Dz9kG>dR}VDX9I?(r06KDx^@OFb>76>G`;Z%U5-bY_td0Cykb6;CQ;IN zVXh#x0X`>x*n&b%=8`zEBi>qww~#A%xZSr*nm|03tDz;uHVdioEG}5G_APGQa{1`Z zDUyl&JJdFjf0CjgXpt8Wic?d&E2s*O9#Xr-1{KQOPVG$Ti4Qz=JvTRF{BMN|NvU1j zS(4(HWpBzj5yvv(11#^K=aw+iP4LD`scsb=p7)73e&_A%4=xW!L1LlPvkaJ}kC))S zEK3*PNcAkAV=2OFOcVk^LAxkWB=-O~7&s<>df*?Do1<2Ldy>*=Oecg5FsQ{Miww z0&mcT3W{rA_VfD~;z*sVd~%TS0cpOYJif-F#Q<>6bk(eM&2-mEEy59?LJF%|KrR&A zv$T>E7^?GXUnk?n_`B&VD*QQo_&B35eB-%g4yYuCzAf!!>hyLX5y?x^XebW7~N8eKiH%eLHh#BmL&b+0qvpr%$^Qsx?Mk;u%TTn zbgpKw9?2pRe_4S+M!+(j=B$?K;v;zEIkf6qlS_v8D^J%SrKm=7|0D&`mdvzl&OzB`B{p<3KKOVr zV#3LyMu&B%Gza_42O?##^K$XAN5o<+GP@3c%%1oQtZZlaC%QN!&Ci)y5KQ6U%*|7x+1NE)Q1&ok`g1P)wX^*UswcTUF_buu%9Hz7YE z_XR)OBcEaq=@BY-)4GhhH*6o7WK^YKK}W6T8C(HIXz|6ENr1UVO=X)7Za<3coMO)m zfEw-=G|L>5`Mk@Vzf? z?fYbAzY*A|sh6n0=ni>nFk@i*U!hBp!K*FG*5kesL zEAtQp9N3H5S&iRtCpJAgE9N@M;1+J8W!($V0^5c)%LMYL`ZpA?F}RuGDuUt33T`fH zm?75LgLKr;F+dK*JSRC6{|0v1Le^`RGI+=#d|I41MUlQ>;IIVGO+}74L|MTG0={EC(Ee7Cxh#c>5cP+l;3={m zqk`4slZOV!*M-QcIA&!z)GVnq^qs9Vz5BV!6l|4FCyCX@To^(Xd$3;S@H6d4D3>&Q z_oK;Hi&~5Yf44;*Jq1()&5E)G=8^Msu0EZRREDDm5~hnbB1oPdkNCy3$%j+5pcqCC z`dckfVwiiJ2*qn?lf~Y7VUw+h_@W~%tIOM(ZA-QIQLP+eh#C-GfHIb-^gv@NWv>#h z^l6kC^2I2tRNkM`k=5{n7;(#A-vrswbvtbYf&_C1dk8Ao^zjLQXsD<0rnpE2P@o^2 z6`u$zh2kx-P%hKnm|%>}D+W=pmT=#iT!lA*{X|~_JFGVk7J{*coDF@_Jtjr)$;mgk z%b+#gY?i?_-Kh9(Vib)-mPY1gc=j;tfM2-|L}5HtZ>^6QiD))k-qvCMPXEqrIUgOx ztnWC5>=RWuzWKzWftwx@Kq)f?e)wEuaSgH~2M4RBp7{RF)S}Yb4nH!#3a633XG|eg zX$TY+wYh75yt1@L2K);hLM+6W=|2!7gUyiO>icHXWGQ+Wy$VA{!*%foIz@`?*t=^Jh8b+SRf%2KFjzW8&L-xWkYEg#>8@iS+;yfX6so1Y{E5DodbDg&-}k9YUtHTmS5(~Q zdb?~Elgy+U!_vx)n{rWC3`;+}IBgvr{|&8cWZbV0CTXCj<+X|imlo&N?<8E<{7>vi zz!BCLc18LF);D%ma0Q8J->Ik|rdc$@Mvy}}e4ILM`=M;^I_+(WEa^HN>dVzw`sFC5 zM>Ku}j)8_GRwRyr^tTa7QX759D%kV%I`=y@*OLByam}}MxJ)cM{2($Mj@qjX4-T6p zc=p_*I_>-!QLbyFMA86M9#-Q-FcXKmgF(t6C|d{0AV99KuX^LXlopK@J=lN;uCD z8v47s(hKmP0x0d-9dvP(ZWgM$^QP-Yg@m#1MW(jwiYVc0N?I z#N7G05YH014#@8lat<$uYAyrnrerqo)8zM#Io?dw$Nsvxf7#azF?JuPv@^ zV6)TAP46dRrqz0f*i4LDX;UxJOPHreUvVUq_77vihjWB714PVmJz;GlDAKJ?xtnOf z&1&kYW=lqs$A)vnGr{!D@jOXwBNBJIv(uYsI?ZVtO6Q!EetMZG7R%@JvBvPHbC`jo zIh?MrWpf&i*IUe&*aVvJm@1aabHnbFc?#H$+W<*c(5zHNf^f!ilr!h3<)rVER+GHr ztA59;W+rgR$=(;OCY>1RH&`r|prhE#rEAW+Q|!}w8rzObFk7#%TC1W)T2AEXWI7m3 zez{*?O=21LaVpny@a5#^&9k)ze!a7QVp>m07=KnJd;Seg5Hg_&&rAeXMk^_A~`&H&DaY_A` z8qRjb5v?69wSBX*I`=P5<2=#A$rB7B7MCn&EkH;QV?QOSIs{2bej>25lL ztBAFICRuzhfhz0Rza4aH%r*}@pPi3dsP@(YX(v;HQ{Y6k@;`YOML^$ZF1srBAYi9= z4lN3}S05{`*N8peRg3&~{H7M^Y=xt4t;?A~JC)a=nkP8hvQf@+Z?bUi>PRvf&^en9%GgRnGiGFAuLeJ*oL!%rM^*CekVxM9alCSF z<7FHt)8joEiPIKCse7wwK`6!h zXO~LdFHOv1Pp`T6iSYIPod{-8%=;U3CN?Z~9ylf$?zNNHaPqu1!^l>fsjOo9H{WuY z4Kq1Gqy0BKoxj2(mm)}-=yIQ_;10}MTFhe)DXirWZ);xUt1vfix)qDqc4=C}&)mH; zVl17=8`0wBxh6z&gLgg2nGxQ`uqW3lb*!tUh+aggj-fPXDio{TBJw4N&#v98fk|H6 zsk#$&2`d#xE|l~$j}$$SR7@sqc9fy&c=QyG2Oh~M(0Z4+YE)EZZpM@+I9tJ$%3K}U z=F+m3Jw#Ll6>J(-%*9!$R>e9(T3T=2mjvR+K5fCV7@VG@`hj8DaU~C*XsXR(I9~f)<@?Bu)*bcDNhx&h@EzJYDf(L__H>W(6!!BB{^CHs!m4sM(X&%dy@4suoP`Z* zIwBZuhHA-tU`R~L(O`Z(k~vSwSDV~)L{8j{ZzX8)!y4H~*v0h&7Cc^-Ht-oSHn^+d zC5}16ltoAOW%aI>JStW;?iq*$xV*(BdzHhGl}9t5UnZ@2XsvAyG7y(>J9k@f)u(RFxC(fWH7eHI&8(+sCi*qb5Qe8RBY5Tk*&{d}uADQDmKJ34kH8}J1202R zcde*zUvKav@2FgQGgYpevF@CTX$dL)wFHaQPQ6`39`^BsY*O1aP;E>Y5GBvf-P4hZG8o zRhzxEc59n%?I`V9ZE;XjVU@?Gx>qdNoAj49zBUXP=g{#;KJ^t&W?^x4yV`Z;q zhJ0tU!Y*Ury|Fvu5JBt*k;nmguC$)Ax=5G0cNs(pu0KodJXW?qf=W+hgD|C?F@n3~=HDVK1Up^KPn4`;WAbr@4CsBnb(pEtZT;dZ5rX}@Y;$Vg zq-?AR0N`txIT!q?C%*#jkSd>S?rWC{&Y8cUZSOU7r8UOw{r+W)S4#7vZ${zLLC}JT zk2BC-p}R4OpwavO49MR0!uoVy*R|40F=p*8dx8w_(8H~GwdyA8k$`v^eaAv4>D++T zS$9XIxcBZ{1;rHm{!HSX_ZuyhjeJ319I->sW#IYXXXk=Xh2YDHq%RLO#vx;y*c%p7 za!Gxs%gQO);q)10=SW(@^g49U*l1gR?8X3<$PXhjvpqN3z7$u5peDsjuiw)sxk&D_ z?8Zh<$0Y0=l(--8PlIQw9Ldl#xW+X_ zS$VA6zd3l`bJQYQuQCs|C;rvcQ_R?WP-mGdwnSL=((VoN=p~$g)4bs`MxB&yIJ-^%Si> zXWqG1&}vY-qiu}DLJp;^DQl}a+T_w{|1!}JN4*wFV^PTo_Y6pEF-L(~y=KW)!O%XF z{sSfM^&PW^gISjj$76hbGx*luGwJqt57SgD&ezg~$|eL$nrl;U^&GK=Ls$|wZWZz+ zYZ(Q(@|2mUvGIucMB`oNKQcISVojM|`d)U*1<`#TDySFg)~p4wf#+6LJ|8}ZAfp`!51IV8 z$D?8^qqovlZ{?`5>%!NrvB}G*4+vf^b#=oo5KM(|eU~8-Tyo?k=S5=PVi7-w!6QO zvsWG8;zQnltsd7ZsU$P$PlHZd7;SK!afNIAe-l=Jq!h_UPOeGOH-l98V~Y%gyr)&) z7>KYG?6%pi@;XP!+}*)tjZYLAC_OvupY?g}9=vq9y8Klq$b48kefNGpTRdu{Bn#&V z^~62rNObjnBH`7N=gaNUu!g;$yzP7p4pqN-j|yIFt^4nM8dr@@H1c)rHArrSELJ)_ zF82^rboT#ybXmEf`byQe@S3}0NZ9j1d%OQH33i5yIGY~kRS2ix4yWMb=^e&<$CW-v zm8t(E4^Y{T=Y|2&9lI!-rK{BysNOYU{71d#4D>Z67OvFQzM_3ev-}wH-v~l#IMZFq zXnNySXkxd;c>v1WG2D_XyQ3HWW-L&x8SU$0X;vs zuKL-wOyB6Y$T32Zf+xL3^YNNe*WlmytDp6r)J0r~-ogGo-<*%3^bgcO9sLK=ig$*m z=J@4*XXGM(-wAl$=iR8EB(pPAKWow&sqn%p$9nu>?*S-Py?ExSI9`+bYnxYV@vZm7 zH2K2hf4I&XwWuoBdyoG;f{zzEx??n67}aY3rB*eaGabpAj@urV@zRt>qKWhbz>O1N z|4)!P>yE8f9AMQM?_e+MvMT$qdy z5Rz6W*CP}cmlO0aKhPdDQ?fL3$2(yE+r;8y(-W>+CB601@HYW0lS)0DMb7%aB;l;f zkXg3b&Cb!Tsoudj;DEr>c>3V~U)WdG0EG)$DwnpgX272Oox3}-b zM)LIR!2D7z_NdKW3)}0d^jr4!^NmqV9Qkul!*<|CpOKTcmKuS>Nhjo*qREf z7yTZmfdg$hef2Y;3e)BHom)tS>KpUO#f8(aO){G{!1CQ5xU!4#1-O4(gPS@Yf$u?- z^_suRJxY-?P-JO0KKU%EX?BNdM~;y zHeS858VK8ZP}~3P@RLK%fLgi5)_4#9Pu_FdS9tnsRv*9ok3#C6{u~GIe;{?<;R&*o$f69?S^M5#?Dk}yYvca4H|2AzvrAOirkItXZ z0{r)}Gy7hv3Q*aN@IPGo4cmF}B2o@N6V_PlzBHL%)Hgl8`Y#R(#iVF%7L6P5eg2vp zq#Z3eFo1OD{)D~)^tpMZDpxS~5Wo>U_5q~QB|Z`8zS~khO%N7paV9#@Dy?2d@GpVi zy0-iYN9|xqACZmX&+kr20K>8zdo;geG|CrHGS;NLaSKNY>-z;QuHsf`vEdNLK3Mp2 zs{GG_Qd#<^rsQMe(eUbO_HPtP_=WY;Xv@iMe0usEB+ZmXHYA^t?f!&19{jY_*-6hN7%YlU z04D?KNI$fwOLXX@n?5oB2cr4&(Squ8Nh1_?z6IN+`Asi`izSO$UhGG7r}vze7Hx>*oHrgLSZd#)-bKUZm^@ZQTf*38F93 zmD~MBi0sqUC)k_U36QX0i<*+K?fC_zQ#1;fzk85I?28PJH9Lb-NL~YxPMtu5a4}+3 zOig9wHql5=-c6My>Bnm6_IT-48~Gc)_S1*U-lsWJLMCQC9bY%{f346i2=J|Z{|9nf z%?tlpeGf}&>4Y`y3qS8aqo3Zbg55k?_QwBNrY_;(aq4CE_ugtjKFki_-+QYCd4GNX z>$>8Fzcc-ITsMcYw*1o@;tSnB=~1H^9KbuRo&0ljJ!jTa>S}F}J~>ZOLU%I#?Y-+? zck==rUGM)wyYqB=xJVx3(>JcDd%r#3`fI|e_VlCS@7M(t4K??#o!o`bMy4<<__Jv=BM+2K(yBc3 zdKu;SuTUEaK`C{OzdRZt(HWxHEa~QA^ZrGKDZ0YKSDs+&?v8hA-arEcN76O^YiLDe zh{)K~98V+f2Lpy(7Q3RZ(O)X#SaVJz$-*-3H;8{>CFGk`?EHtvQJR-Yy1Eg3&(s=( z!*=w9d_bq}e|8&5>Cp&cw8Ie2$kn)bYAeSmsA!n_PetJ9e@DPB>7_i-na8YX9$KYx zQP4}DyrD=r-PhuhajJngOizfU;d6-o9G$1wj{+bk9-_1qcl@9rYJ|J@&)F>=O=g>wq$xT2cYs={&^46$OS)#7!tgbGN;LZaFxZR%-!K%pQ7aIM zYOh5_#d%l&xbc?`*f!T1x-=^k!%X$Nkwc|a&*4}l*G`sWFcV8Fr+|gd8z88S-95XY zlKx-t?juEO^=D+*9pXZB8aF~{e|@Iayz;MA|D}{H)_YFQ$q$zF16doJ5I2vSPfF!5 zGOIs%x@~)zee(8~nvSmrzKhX6oTFV7;9LBUl&}1}=pFyWO*VBYmoWTu?|T#_vdysy zpTU{f`%^sbqj<60{nsviwO|+E@gKYOKX?_t>>?H?05 zB!ru$zJDoBOU~bA@$wgsp02M8+~wbTQT_h5B7gt6Ij3-Uy3+hM*n^608$X;d8gIl|q_;i2-roW?Lz)5dzbBxW2|vXh0OZhGTR0?^*Gs(JLTtS{ zk8=9@Rw6yOU*+I#g)svpn)OW_f<;%+ssaYk<30&!Nlha0fa5^k67!B9? z8({R=OK?_3{^}94pl#0^@GBUs_LjA{%MN=;=w;>Wa0$WgJf7$=>pt~!RTy2*UP2PG z_lmo)4iu$j$-=PkM4|t-J3%3^JcY7S5na=U!TS_2_3d}iOpppI)CJxU#C*{x^Rk0O z*RH#-LGa5jciHa;|34xRim!|Rh&-Hjj+*k-+=*^g7|cglHERD*^Kf`ycYy6Y`RUyU zDc;Ty2go177}P1aLV$su-waiJehxr%M?Q(G#&`-acTi{}S#=;as8JD5U%Ho?Kn~@m z9D)cy8ovZv!b=g`D8>^xduB(3`_h~6(C2T8cveu{tsLqNfl)kUK1Wh?PZyulg9U~@ z17yj}nx$U{5 zrnvI2$|G=AY`g_&-vF)LCMgk^s_M600p;i;YIPm%y-zsz`I{tfbZF{%KN4B6B;-X! zW+C<_r_%c~^Xzia_RlTY)A?(}NUeFUh^)G**LMbMXc}b)L>Efpg)N$zQ_A~VB3pU4 z`5p{%Ycd(c$OW8$9?K7hfM^$zP!76hBxfxsCDJRmEvXk8wjT%>9yJUN^WcGCLj;cN zG)hX%_&q}d){}ja-+*g&*=!7qn*ikpoR5qIc0XVL^xTJ?Lmag*I+nukMRH+*=C(3B z7u2litzezSflj2e(LpF-MqcT|`J|TEA|qhI6e}?K1)jz>H?zb+-z^!}so+I6aP6L5 z6`=dIga!LTc%p@L*r1ZcIX^`f{;sCGa!)W3j-9RrV$uBAG_O=oZ|;(WIRm7vTQfiK zXk>u)V3sbsTc~XNKA=%AaRbM}bUko<*#jTHVrgNE!oLxNNQM_EfW1rA%->r)9#1Ln zWI3Fl!*@r_aMcgP6Lp%q<*-=;Z{nt6a6CN-kK49z#qO~XlIp%2?mCledCJ5B3QE1e zDcxDS+k|)34UxY?shBIr)FfIfl^h74n#E++I#0F150c~z0GB8!P?&WwI$rvEOXKs2 zWJWlrV{s>uv(5TbjUT|JL&KN71CDuph|3IM1}1KMd!a}6l4Bt@55W5C!nmF`rio9C zsfy-L1}72@-?Ik|$=R0zw|VJl&<@SwYbdFitx)^%TVGgTlYd*;8v7%qZglsfCWWDi z!SrQy7gB5wF+sTM;2gle zG;ti{#w{Qd^pE5K+@}6n97U&%rXa)H9Wfq@y8QA+zeJLZMxW>@OV4sbFc(e-fg=`f zgN1Nx#wA+$fOFe-HL!k<2{_0v&KxtQI^1zNtnF7nc1mlR#+I{}`~rsagWN7+gKbe> zqSY6Wu>3Sm+=HZn@`^2KiP}33dd?JCXo+t7V5#debBjRcO>4qevyUj^>^W1tEFPJD zYJ`muS`Kwgm_-{81PW@zB~LBG>B)L;ovgWcfu^e)9;9Q0+0DAO=wRXLdhi406DUExLY_gJVX~R))$CJtQA9L zg64H^O_sURQdXS&KE%yLK2~J9+)$Ayo!|?0pvuVeQG}B3MtOCMl5ymPDQ(eIWT2Th zFeQA*%^qHg1bQfj{{s^{_SRyb}3Yx2K)uyf+W{O&{1vhv6e3XVa5r z%T)95{CGa41l|vv%uxtUqYzdUyqZ%!+I#!@xyNkxcSM5g%BB8HE%g&bx^$qBr6Q%I z$f8MK;PrKbz`c=0Cm-D>jV6??De76k9~MNsh9yZr!Q7zG4KPu`Wc{>^o5$@_5PsHp zSNaWaS|lJNKy0#D(n|YV%D(=HyPQvNupH>EtBa8#6K=9cM?-q2DmT>Y|MjU}fd9X$ zgk~fAH;H4)Ck^vegilezC8!;$A1Z1VH})lI5g4>*%lB>Xe?$qJJ{9O?U26VOQm9E@ zw3s)<;a`KD&Ag5qmRCX4Ns2~K$?%7>q+rAMk#2}#mN*9xq{Q{pfJjwL>CBnF_}nv6 z3t-6ca+O*VfJ?U@C&;1=D6>K)ULl%Bd73P~l}+|tkT@hK`zRAoDND@rIEI6TuWBh} zIM?vk0{WZdCCns7<)AFkXROi~bd4a?BCwM){qK@FP~)&tGy-tJD<)B(*HpoR!R{~+ zIQQCSL=hLWDVRjqJl_CYU$Me3PyAsKnoJfi{NIMO~e$hopaK- zJR*W1vMebZ?*Za%{&?^m4?_uRlnc?pFHaO4`J{v-bkf(@L}HWKK;mLzWdn3nHH~~2 z4mY9&bX`zmb*Yr}*57%f*b@Ooqt`;wRmBNGKj6GrS?;0Tdu0}Egi&KKy8X~c z2c!dKh=W0O?rhOfJaX{_fOrXpnRNP8y0M_$q&Bo_R}*B<#dhs*TpsqeBh?nv$N4ka zK+d_*FYTp-z@gTi4a0b7if>APW>Lv<>l+6(mr=qDWF0{4YQcu>BKD=)tDYOQ3-P z3F)wK^#}pPjzCqVJi?sHz+b9sCx&G^gho0!=)^165fllJ!W^JDW$Iq=wXq-_K+Ias znSCKg?|MCG^T-knsc<;73_vb8&DE-I6_BK_kwFMf_fXT15R3}tjsw*kgCKG#xG132 z1qt1G+My#UiuS?Me&wDL=sFS zmPOTs`H2$eh- zOsrU}?HL}U=q)4+8>@{HzuJ&yhk-Xyc?g$#hoj)!0+d0AAgi`Fq`8EDfzm-nu=b#m zL>vC(7(zq}_$7%Ibjw7o3_yr5qibY|W9rS#Gm#E}TE4$dFx8eSi>D=3X6n0el>eA% z^J4|IT){$j2{9^m0KhPMC_%d;`m9kWgN4$iy4&u=u^+M5Nc5F z2Cig(P>x*%ilZY}ksHKil7^5Z{Te{)RSdqdkY-__j@zXhajYZm)7()*tpyvCE`c^s zS_ZfHlO~A3w_-fxFmFjdk9vCyrw^LGLVkKQG!xuMY|s_~ez*chlXFe8pM)p9lSJ!< zCc|6m6&DsPwuDZFJtlu<0+9v1s}D9%R_i?mbD9?|1OqmL@0eL@YgkOAWjq3;kpNL3 zxY=a`@v>Ka9Qm^9pxR22TN#`*mx7uIEFMKI{NbWv;8&ajmsm7u1}EdKUQWh*Z)+ga zuw(-HUV%m+)In3Ud<#(LKoRKz#nP4%Zi3~5_M*#LEs1~Rx##M#LMMQj*8ZK@^%eN_ z_7W_J;?L0o46m~1q(&!*SHlZ@NG&j0-%PTuP{Y zF&h*v+r|#{MVs@z#hwaLRRsLhfJ?Ai9;&vNodH zSK%sqXArW})-;QDSCJdzP85tAPyH&M7ay05<<|seD9Z68__Pv@Jia0IvgC`XUD2d< zdw5)a_$6|oiK#n#`EX&PJ@@|}63kUAU%GyE0e zn>f~vIZ?lrv$@nC6_+iuke5;2okAXs)4X2vEpsw1AyRS~@zLd0Eo(OHegg1~U0G=T^2X3YjR78&3dDcNQEPci=0KTGKv%dF*ELt)z&*bDm z2?s8L8wH=>aAAmC8rCaOE^WX1SVzw9eN{bk!;H?1bJ0BJMdUwG&xi0LIkk(NnGn>W zG-{D{sBNOzh`5G$flB$1Fz)tLCz(4B=_us*B zvoU#iK$%4L{Tx*=R&%#cEswNiVL?3xHF7m&LxrqvvM6L0&BudCi=Ri?bmWQjBNuj> zEqubU^AFCBajmsSWX|xj$YYLxe7W~Hh_J=8zH3{~+x%=W0FMXj3f5Z}^vDzD=j^w3 z4kk|qhE!LE#w5Jy&|ON2NezCRVX$Hjf3(s4Sx1lR+}pgFGa(6H&x54L!vqFb#{NUn zA!#pb(}Y=^JJn=M`gn$Do_Ga)z z!jRT8eQoJWl~^=a>W8VHn-t+fmFGc76IbxYJQW<*1mMjgR|<8yZmD@WR>VD46gT%tu6rDx|#u!KJDD;nK~ zW(Q-Jdxc#vtBzRj^icN{%eqt2z2trS(HBrFg0j8P{Y#|gWMY=GZ+h{b+5hAj37 zq?K}b^)#;7H1!Lf)m$k~j`|t2*7lP`ZpX+M>fml7e2mznsi0Jopb}Zz!wivif*4Q+* zoXM}Q5OdxnU7WJ6T}_*bNQ!5rqpY6*q@$r`nVUdI^|iRnR+xB@pd>#UyGTF#DT=~H#4qpSm|?1sG;_2~`8vS-X=j0E z>1uOdnd=Vp45Slyv0>;}jw}i2L?cs5L`TAGNQ|q&+wM>`WN6|g796k7o`n981@`=A zD|3$1T3;oPHZG9(i?=RCmC>9-JTJnSX=mGHU!Bf=5U_HD`pwt#J+4=h z;CcKIvGOJIauGuU{Y9T{Z<N zvNPF$kYOmj)gkz~FxA2uHVB`U_KdA&ZI3@t9x>i&MlTF7ZXVi-zxNFpfIZk-bp=N*M2>bxxA?)P&KG(dUS9KRvrmD|@kywLJG^ z^%Z@k+3E8X_^(gI$M~8qLCyupt_M63h|5)d2h8Un75=H1DGBVC%-S0%xShg`aX(Zf z5c{V;OdPtDMiil_nz5y%UuCn{t9H@w$1qg@?nIhej(DF zNVUf@6j?WYHHOYV%Qzd(d#!;hgPLL_jSEY>36jFlV5n*yDjNRGQoW8OduM-KjUg~N zj~QW?Ci-P5a#Ajn&*97|=ljCy#H6XnB!UH@VK5$g8X9xKp`M=}L>b@oOv*+;tYL7F z2l(P2gfJmhoRLnlKkTj}l+8mYpgH%!?aXjtxiw!vj;)$HNn8$6w?tbHw586XspaH| zV2ZI1Ula?_=f8*R3p3CwbCap*bLTMJC@L4U(wW~GFFqwH5>7T{!C))qLvH|#{q(o? zAN79noQx2NU@`RoTKbDv#(42DLVG4OWId&oMDQz(OP%T$5EiVNAii-SGYaFyZ|0xd z9JVHV_iHsL+qCuM>;jC}`81m)bMY2f9z+&bYwkfOjK1#!j34>%#&S4Y$FsjdXnbks|dx)KRZSIQ@?hB|kwFHtf;QR`7 zq03MM#g(q!wf@_u#%UQr!?0j7DmL(!I^hxdg>x%r{|z>ZT2(|y5;K*v=)R#^eMBd+ z@lk0<+N~E4k^8~nKC&KE>W1b;`MOO)Tk!^rg#rUCbKrAG;$H>0se4+i9*TJE{gY{h zJg@;~(zGEF7+jOzo@y{~`-KTN0dzl=T1^do_a7^q@QRTv zA=Muytd4`TtQCGt7K~LN^fbnDPnx*n^7~E zY)BmHe*l<$E$xh%jmsTgwF3XNE{|vBREPh7sPlnME3XK*#WWDIKj&ODao4Svm1F9} zSWWqN;oNv+b{#$B%!iI?;`th$kY*oWNGIp(TBS@Ip0l{$pzRv>UjVdc)n^kW0?qxP zY_4&oZ5a>Db@5yBID~*q*Ng^#*YZv`3&PeE|uBl`^BD{q1{g5iT ztWgkFM9Gwc!^?AxkA*IzAG#*hmJ+t+n?-S_SvK!fOo@21#4k%BTU53P@qUPJjj2)< z&LRS?RACUJ_~0e+h9{CfX#^^|p=bBoFiftWn!uM`hakx43Fooj7z8N)Ntw`VDTyp| zvohl%ML5ElM}IA<`#C7$O4*VOKAXkWD5pDMig-GOl*kHwYwmkJ(m9G&qp%ITOvl4Y zX3qori}YouXJA04P7KioRWRQHwDFTgp~TnNo9C~3lzw81U%T02v+YoKr2Uip)7LSK zkGPh@+ov&EN0!=l8`b|6=Vu6H zA5?PjdqWKQymhuFw)h}9ilD>~q&sDB$tQ(46~4w(d^?Wd27W?;XOKZc+ft9DA*m!$ zb3W+{n2!wPHj%kSs!x5s$c$2Y&d)(9lzTd%=JHAepU1a7k4k;jII znnE(z@#U}vw5y#Ad~acb9jAOC;ZLkzI=s&I2C>x;rc}kTQN$$AM@&za3g$)DSN7DM zfgWPH5rer-qp?o=!FJ;$UP>Uu7xScP7NK$qu7x((&a9EX5;ZV_zlvP4t#q{_&Ry~dHmEBG0>pj^k#p(HWXfHbO%a`r#4p8SfU$mcQ?MS3?Pk6O1 z87sXh`3mlhzlTNxiRkV*T$_!Z<@7hnUsa5AEgLY8lrC)jqXr40My@(SN}_0mT7FL? z$N7M>cOQF;JwPv>b0w^s0#g5}{pFX+FvH=qof4JJ8{?B61RL4sRzPK zQJ6C`Hw)L9R2+b(=Aa6A06+B5i?uIo<*UsR4M+*Xy))|&z1^r{&W8KsgjoIafTDw3 zx;tP6Ei`oGoHKo~hCQj;C40qew6&Ck(c6#ng`1@2r9efkq41&|ATeerV?@GHHR^aN z0YY-JuG)01VEaq;u5|lBhT^98Z_-EhAH}GAseeBkQEz7n7aFJmNv?syb-`RcTtA>F z4@Z8<6gBpcN}qiuoZu}yL&bvf7LIsLc#v8qwu85p#G$Y$D2I9v)q-O`hjSAZAB_|YUaEfQ2=MKB5Vd3!$e2$0ku<>nXQz;_3#+Ai{9-t zv|<6_6!-N&!iF4w#)D}we9Y|itkM^8>C5RP$81`ZFrC?4%0k%B7x&W@iaVrXd5uRq zMFw&E&jb&i#kC#t&a6xrX5!zk#XkjqKjaR}75`~qwC64ldsC~TNDv17$BC9>CR;qu zX*(CmVFlI~wPfhdx!fi8vt`5|pW^r*$n}^qc8t;G73A*UQ|PA83Y+oGS1eNw-I$a% ztwpH|_qmD9SEN!8L&74FLtI#A2+$m~LR8siXeEwTrM6zn8wzt&MU`<-5V?lTY`2GXrsCnB3lS*X=RW zqz)?p5mb{992Dc`1t{D-X$WZHUlNl*$NJl#7#=rz47!4ySvHRT@vdl--3~MrfQ^0E;vLHo!j3H2`o!Q^x^- zpmpK`pwa?(0K~M{yZ{E;I(`5ztpgK4l9rVPphkPi3NWFq0RS9n9XJ5~w5(i!7}`s2 zKo)HcFQAmxfgjLJ%b{lxqk7ssttQ}3peXRmUZsHFduLnv`E`gZ?FJ!&A#v3z2fxZZ z+W%s$pbcT@Px_50m5<$`RPNJ=Ia2V2TwxpDP(|jACzX%uBJKC5ee>wBi}u1c>LJ_g zn_4O#pGCO5%|LUc$Zw1VZ5%WVsW-8`@-~UvK8Xj(O^tnLK1^dLE7G%G?9caa zHGhqVMZB)3#!x&QRiQzj(X3U1DB*A}>QJ?XRy?m>6)otpYP**HwCCQP277qT(7=q5 z)6f@r58jq7YfNxO!JAkj&vUC3EMj}B7=}_OCjUe6s;`R~CeMYmcsg>m`zH&(`(B8Zn>MI-BM9?V@LFG;9KlsY`>}_jGKMtlTloOYycr=w|<^O~z z7m2ootB@1V%xWgqPd_>-*DL z)lE4}9`987S@_SSsxeYqgRZjFv>!-u&v!W#`9vJA8(*6JeKa^F0`Y8zoFTCXM+jx7 zNmH7i28sM(LNkq5_Xx#o1#({U7yvJoK$@NdGzz6>*=(uYA@2t^IA!{2Q@#C`Fq41iy2Ka}KqTwE2_^{eGsEa0`oKSRe73t(@ng^B*Fx{c}rA%Xue99LHz9E*H%Akf|UwGxU92k301IEe0qG#_{TiKdkxPFI;qk@0Bt=F_njuqYx?hFkf8dC7$gBxWPZT ztWqkB<5!jfa30h&D(NQhcS_YM9yqisVI}d?O9N~VSo@U5llfDn>%NWdr6LfRTvD4| z=9&xmxcTLy#a{M#>@qBDLEqB$FCv=NT--k!5Ht3huzn&>-h=n?9;k!uKn^JSmj`WM zGnSnFc-L!r-2!|Z{__7#gnqt0NmS*$PuC2?40%13BTIXbG=oTEN&+%TH ze)WGNREpU;g%5B4%Pby>8?1NvMt6IKsKjUoOkIXjS=j4Ni*%XX9M*6j;YA^(uX`u} z|N56%@j)yh7h?}OXJcyrn~JUL@OHYYiG^{&i%e|l4%Bu}y4ca={~<1tRK410W5LS+Q zl)@shUMHxB+3(`rBK)Zc+K+&rF%5F)!5egpSitBczF~D?5YTAM`L_l8{d2$5U;c5iDI5v^NQq-8_{ft0JHK zMQo5NczsA)U1zJeaCp1K=QRnR{Qdp|Uc`D%1rSgBtiYOv^Uz0LRvBQLhO9C1b?tan z>}9iGRW12%R0-@-n!dvvzEZD`j8^a!|_rgHM)qzFFq?<8&kuMFZK1c0idq1 z4nP?;@XuL%C4n2D!p2Mn!J0&60XKdL2U*rXPs3DI~cDKI&M{OOFu;1WWwR`Ep zHTkbeQFi{)`=_RtJA6#}FKz{d7$0XUky(rO;gWgst4uz1r94IIKWKJSV;u|1T;?EhH3R;LMNNW+`9bqw(0r76Zc9 zwa7QS#RE8LIcT#HTdBgVBX`w6-Ss)CfCP3IXC(*+i zy>E3!AX<5O3J@F2u!yH@S$KA24=FLAi1|94SAP$itD*w=C@0IEYweiHqx%wH>($X?)AjrBmu;zZ7jEX( zICCPrKeP8%7jNLpAkP&LeBu6O;+oM~V|T|aBm6w3>t~v*5qGZ97Kl%6=dC94+JzjuPkAeJt~MaS72V zklVfgv7pY$YhS^f^fSB_?)w4ZWwqGVa5vvQ(GyufEs%bp-RM8hncetDzpVX_ev$hB zL%;M6tciApclxADjbshg%BNnKxpN6Mosq*8*?zpfea}U=ZNuNiMiw9b@dKkcZBJw` zXu2Wh4G?jO8PW`KYcfT!kN<2<*=*`61Xuh==q-QWRzDHi;UNuw9N^S@Hl}@d`E>zH zWv%D%9~HyYItk8PBSrS##(N|4+Vta~JGLb+}mctQHd*ESE`mIZS4z^geAO9ldK865KCSAJ<-3K!{#zkb*B<~n#_JaY5!tK zt?d9@>mBbXr|Tf{KO6#k>K4CVMRzt!Gs;`$7!BWdb4m*b&fEN73cGTDxFIbg;`XOs zt@Wx8nG1VOIS)xHZ5?mu<8{#7@d-3!dq&xEWvtXUn;nqV>Gv#p=#r@9m;wv5KWI*^ z5tFW}iq~(l1Ovh%e~1CfI!;H{rL7m}7QX4wA8iYC8P9vZ+i9Q z-c{CvwI01QDFme#5Y9S}$FAeewB*(^A~<)=l@Ao}IsS+$C4jHh5&d&#^yx>zO!Z`^ zggRG>R#GfD^lnV?bhKVV+vKp6Du-?|q&{I=@Tv@IipWJU5`@BENUSNdzO z;vb!15*?j}ni+OuTtXgVSq)$yT9^5ctZ~=8P>IVxg|J>P39?~g=58NSv3&q}qYt1< zV#VUru}iQohPyf!zrkb`TGE#SmFb-)P*#mwu-GXgPDByfV6Nrr(Nc}PmLXdIOK#cf zIqiVHr08h7`2zRsR!hAaLWU&jyJ2ivF|9sjSXb3D9X%k&Ly-U3wtkucb1c*dZk+Fi zy1BY_h9mbMhccv*e%vfwshQhTi3sf}0QXM}&8;&6K{GpLFH>qe=flfwCY>fX zP>G|L?t#E1VEAtdB5%_#Vb)-Fb~+Erl8&D*RMtcf|J(x+ALzovyPX+*C-9+-{CUyb3A_aB9eJ8k->`%}`d^5_O@LN!U$WNskESi= zo^f^pU;Q5+~GCTiy=+4{KuZak?*gb;bwoNga!w5C3B`4wtNF zPya$k?}(BUcc9y~nit+Xbp>5Atoy8}ru}j#5HWLry<11Q{x4Pn(n^I(6>Td2M}+XR zdYguTf9YwCY#!)U)QgE z?>tpABbi1BHv5mwt;u3ri~o3%1Fc7`Elh1uqe_j^wVC2}(|0thAqd?pSYG=ZGZ4os zQvS!hTqD4*CO0c%9nyfbmMQ<^@CsQ^z~>1(%el%b54FqwMUTZ}HFb5tqg=X*FeU8| zD^@e_Ztc*qz$Wt3GoDTA&m{bzzxTpRWN-GF5D6<}-b?`~C3IUCi&kjB2*nu!7E zxC&MOjlHl$IOjvX()_TEs@Zjc&Ohc)TisUxVkQytt}wRP7B&o%?GMfIyzpUq(aahv zkTOJ6xL$$lou}VZ(o*NXmdSrpcp$je;-7r|TA%0c2MpX@V$vF?K0+E=iI;hdLZ`Pf zAF<`Q7#735;X2BH6jq86N-HWUsUAoBV<JG}XL@K^y-PhdgSdB-XuKYq1{m#k9P( z)H_P5I@j8!*YCI$2I35+Wl`M_AIYk99X2~$1;6h2hqv!iR<&O+06taaC0KS}#oGN|M_cMX^`iUNJ0avhpdXpklmYO1 z%KB9H{jChO8dTd#{?lmfQo9;zQ>-{+COtQHHJDij(`%W!f4&RW1EYT5${8|P%DGZA zu!?yX*yaBeCrALJUQZfSmsP7ghGQ5^9}%wP&*99!MUNi0qN_k3UcqFaqkq&GYVLjT z^7*%{Ge!-msEUy3xp>lx#Zt9~mICYl092saiv^TwmbOQ~n`VGA-cXWd1fkH;aF@R| z*PYqZV*LfhfAs4P+aqc*{g^Nor>dJ&BeR<^=qfObd$$%ZX}9o#2aSN8`yBo5yspn1 zf8RFn54WRv3Av@;Lh2St{vM9^(tCnAtm&orzQG^>AK@HEAIxB=KX-?raxqqzxe+HWfUpSJP;whi?kfv7rj z7<~^?VsVXRsJw<-eWUSzQ0^4<$k&Q`jR+TtvUISue*qL+$stAX;gE`fEEfs4+Fy42 zzrB!pgaqiFKu9rXbxJt2ecvL3fSG*R2F5-s{`qbFVPI%80;csh0;Df3*6up0Uk6U< zE%*&ka>7EJ_FbXr_A^si8%hVVgl~8AnX>f=>n?*c<%fqYb~FEW><6PqeERW*@Y%b> zGIzB1jT@ng=D3?ZX9NPLcS>Gr#Aj|7T@7hVRqC0`PY+#AUjKo?j>TT~ZYBI8A_*9( zZT|(}%3c+b4Xgft{Y=$E0rc0uy8uVbVYQ#4vT#mC5EW)KalW32tOuLk`8{}Xq#u46 zfTY^`?rAOr%>+P*fFv-zx1(s(eK&fUozIx;l+iSUjQx+nE8{KeP;7HQIHf6b!9@ua%?JJypE-P}l^z7v9h)fjjNQFmER z`op<*dQk!KMC6rl4sO3%GlDk7NoJ07?=~nPEWC8H8@tN?HU-z0KB{7C?U>cF|M6uA zs=k?D&ftw_YRcG5lCENA!ou2AS=Uf^sNLd~cxUC@@J^CsipD%Ry9ZsL$W0#IE}B`A z`-f@Ms#DYaL%`wXyX5=fGj&(MNvqz`%Q54cRZJqw9K(za)0rVnxGc)|17O5WiD@;U z{0l|V>ox9%aUMB6K9>6|BlsRLFIJ%8}Em3uO;Jf zsLlw+Xh-z71DC6b^d6=TP;~V0*Cxo_9mDSbT5_oBp?AKeQ4P*!z_KMw$!TW$3*Aww zTl2RV;Ky^11ta7}I2G|Tt-W!K*nft?&Wh>6Q7V6XOBJ~H3vXY(6Od|>Hncde2$+b> z_$8xrN|IqnSEr1BN9wTJMZzA|plB4xL~V6v%2v5C9zPF6>~su%Jd7q`<5!^3G7DdN z+-Yq1nH&#k5i(XBMrg@w>zC+8J)+0oE-PI2U;r6QAXq6!=tJ@qhF5WMVZYu8W#a15 zJ&WwGlv;c6k5Jfgw!nX3#;5QO5cQl@w}exK8nedv#q{Ey)lojObAB;2_%$lgYnQP;L_cbRW>%n*bZ_!6U}syh zpjAgvn1DR8U3;HFYITE_xA)e8S%%bRQ69y)3S~o+kz#GX?3kFu@f!oD+G@%Lb6UCF z8y3TwhHpuYWHr?ESGFUsuP0u^7${-_~1*L(m)BE6rFnkPm{i$QsXGIuiI9RC%&r zZ>C24fYV@}!RK)6?U*nyNlwZ7&UCvlKLDJx>KqfV6T-~fR}NAAQwzWM%M$HQOP}9{ zV{?}EXk_))g{5)E^Oc((^OTfy1KhYa@HQ^xfV?10jyh36y*F~7)4?U6^t26{J3VfeK77Vx zZRu(D-e@XJLZmlw4?CD`Y%=9SqBn64b3*8jmy>#Rr=J>@x@Ji$vL(g-+sPy;Iz{#t zP(BOf1$Y;f*){_2{bi5+>rc8teU#tL!w4uU>4t4N{{Lqb{J>EF<+Bne@VI^QCaRTn zzFRMdw*lDzYkOt(%*w1dNQ{W=*)qG|b&qrhS=Aqxg_X-T_6K9Kw)NOoX?FQAsOU87 z(fN-hL}p%CSs4L^R61Y1U{-b+jA$pLSw4%!nx}&QS4wzIg5J1ck#xYxl%;3y#mzNK zxblaoH{kSS9uGo)4p=bo&CRk4i7YjCb}RD;G>uOQK&wlIz)mtUhg>&nk`G9=lN@_n z#s=RXD}?~J6wp#^+RRCbCkyhL;h`q%9AOJU6u6|qfTq(Rt|2A*+~0MaZ~o!I5?1zT zRv3>RpAXqtP(jXX1pxilt|74FoAGxUm~nKm;w4~S_4IXDBCe_LafW?E{;tDp=6H?7 z2xuIBH*W4zs{fW*E%G-RRtg^A)PV<|3xEed?KPlE4qogkR1R2JowM#1z8@fWsI`YuWp2aQB`ZD z7;cueWXp5q<10aTgiZgOfkyM&%wUz$D6y+Al=Y!IWZ4P7$zgtA<-F#D)n9|KTp{93 zZkZ*W?`R2D90p4)F|&9qf%*%yt;J0WfnlK59HVM-@XJwFIr*F!q2e`j zdt-(n{B7(Y_-T-q_f6W(pZl6j6M`>TEo^8(cU=BRjYM^WAk$KA7Qn|1O{gT9ZV_ylE0 zBO>9!O7$rWZpc5&s1em$^#-X4%ea25=W~aSkLvZB{}v4qo>CX5q{Vj3*4I9|8&Lzf zy13PCn>+i4EmzW$Kzrgi96pXaBsx2A`ETIp_EDAqlobidjPM9vDRSqJw^@nUw5z76 z0&7V$WIqfqCO08udD&zSYF-V_Z?RIR?&A~X2o8`0ZsO+Z=__ZI+VC&YKzOH8X8%`^ zE(BPR&W9}=QuL>>^SLv6CBmbwYmLuZ{4R&th2EGPpAWTQLJ_m3Ko+FOx?|C*ErXEwUVDD1Z|mNN=;_9a+{a2c9FS?$xl}iAl@-brGXI}iL^j~WE0s`+u7|~k!is;aoNHDAis5iCQ z!U0S2q;2N8nH1RQRHrFhvVQ)>J9qTEFF3 zw!UuGIDV#5UZE?WSh1ErQ9uQ2b=QgB(Lw-82}yi`C7LN;V+GNscLoNCv6mrl6+{?f zsC>8vxq<=QKp0Y6lM~GDgW~JX`i)xSWVy@|OhtVLG7=z96=@pXdn+Za6v5&c@{KU(U`iS0WB)?ybK!R`Zh9EoPNwM3<_DnT}bgcM3L**p+?QvSy}$cNVmM46JI3 zL8E-Nw@b))FY$P%E3h1!O~-ra*4VLo6vLUh$=KSr#gp2U5Ts;2ApO1VYC;HE#sHQ_ zuZemF{x%rBv61>Wh&l;ZC5pSaxZipuuQsYe^{-8-z-&^r%^!xrMeT44um z)p&n#K*pgGcbBHe^x%rDNQgiQMiK=x(va;#|C|{JBY9fc=c+H|3--hRh^_2aDyR#& zEK_Y%Om!@8IndQJL9jG4Y>4dH`Hh7%Y(wj~21n zhS30}D<&_koec2B0J(4}b01+S5N&BU$AyrD2!BAywk3oi3o3dD1|WDP9RdrP73#Gc zt3#!Ckf)d@v30fQNADGbtTLUGaY-kAl$Yq%EWJ3U=;Xx6X%!p*!CL07x+JrEf>?G< z=h7f@X2fjtI%xnChiV_84D{?khcgA<`jA5BtUnJ7#13tS+yuqlf_g68`K>7B!lvIv z?&QO5w#Fo=?LrHvi0eURQTbnz&ETI|27esH81Yp^N8>p}b`pg0P2;qyi;-K#-uDf7FzoVryH_2xQE+6e*#xj1_m0=IHFWA@B4#~`VMVcuyRf=JRkWYA<8e`Td&<6*vtlBN4 zz301t8q>aZoWc)JUedmh3?hU621+?djo-s5bs#0EIjMU7&ae)I^Cf;{o9H}R-qcn2 zS&3{#ykMJ5Cd9%q{acP8{6sk5s0oDl*%RJ0EaJ{z#mVw5h$Spz zUrC#_2emB^!P#ez)RV1(YNy?TWz2;;iaD^}+F*fZtvuud2#S&JWUvP#U znGl-b1yJxeTi%4Xp%WepWLXVy=(G*d=G9g16H}LOan0j3CgPYh+leM%Cn-7UJ%NleQF0Gd?wvNwvoJr{2yRt>p_35 zZY3+q5HoWJ%678CQZuzlu0%j@GeiIK+=Ij%JZC2yCJB4(t04jwel_kPzx%jWDG(T6 z(O(~m#1t<8*HNEceIb9PNhne50)HeFXkQe}En`jo=4`@0HZ-DB|K^kT!t{ z*&oc&H=&(Z`75b?X@A}X!&v~0 ztSKnd0?p3d5I$b;oDe@6h#58@6V7FaTggR zXxelF&6+sJeGmodDI_)@u5UUaUu41h%~JgGtf=lp-r2XHq*CQ^yI zG^{U|Dpz{>JDd6S)b#5?uIhQPReiTozkw&=_93{Ta=uF zF7$N<5DeFSBw(uLU6;(5ZH$%GM0gEg&mhRm$7VkJ>OwRFXwh}yN-b-G3pEw|-T>08 z=#1(G({b~qtr0u4BnYLPp8%Ot)=`?cw=q7yjd1*W9ou48%lQXlVd9vq_&UVn84~5s z*nN`D)(~i|mMMpi)Zv<+ww`=N#9iRTX?ViM)avKw>%IYNO4z!@SsPM6cXvJJ+lKUG zDWLWvJwR2_c&WGsjx|Oqy)JL~GcqF}JZeiWW?)&H*zz$j# zDuNiV?7VnTULzms-73Jp*E<|Cu1lB%`Yl)492ULSD>;BZ!V(^>apw--5SEu+U@xl^ z%G_p2M2;e*t%qviWPFp%AM{cP7Ii^TxW6C!wj-b-=Mzk5j^UPU9*Q3TVi|xaJdwjL}1-hTRMV>W2M~NA&nMFJ< z@$2)f#3GxqNnpvt>cDgDjVxt~ZVXCGnh{VCA*y2Jx6MMxf$j8XK+@SPnt!$6OeUl~ z6H*|U(Ct?wL^w#Q8jmG5CmYOS^7I{wsr|MVS(uSHznk1K`;Ay?6-$*&)$o9CAQOsT z??)XWTY)Q>u^5l@wl{7hJT->?cZ4`Oh_xpne}1VaCp^(Ldv;S^v*36dRDoSGK8#zz z(iwzfdB09mmEk>CUJ3`D5fc`-`rbJtJs&-vLT%us!_gKq?9mY^9^@xECe>S z88G!;#5>)2w3vNLs|eIKgC*R@E^khMN8Hk-1y>Bs{99P+)apEKf!zB3jPZ#^9p-%pief_tkc&;~R#0=#SMK z>&O9F>p^WcN{ww17RY!H-aeNG2t5rglPxqsJqkU*cS_|3W(`5C(%15^<8h5}}av)u_ljb=Tud^_kJR*J@C})%56@(MA#% zud3_s14okpqov7kdS4E_6p^KX%@P>DVOT>Lht}8SnTrl{gsbpsfzpL3gHFq!obRGr zZ9f8*hD3STh25)S)DfXHihnhfjtF9JIrr=0812%h9ELyUX(4doD?!kGU0$+LMg-wi zYJ}-q+Et+G&t+mVzOaGrnc47-$5pd|u{_%>L^lb@HJcQ2Z|1mC%K1@nBgcD1kpCIT-IJu4+NR5GMXUZ@A&!cDZX+06GzV< zz?a}JtMHP_`6v)YZV-fWkPx|iwlGB&(?}GW9i?sm>^(LS>WB2>-f7Mkh0zw>yjYCR zEjTrbklr!_x`ILcg+u^p5IB*b^=s5A6ZP*EZv^a+F#_w*r~C zzSp8Ho4CpfRGF*^h7Il!-f<)@wW*U@zCM>Lr=}XL8mC2rSmSe`7}`V$8UofwD&6}+2})_h)k8AQx50yO8vSSq_(#0fqCfbum>$BuW% zM8OH^zFZxr|59_UPw{2C2|q5yT3~rt3T)tuSDG`K@Fc)``{zdoqg{dHTGpj)SCE-F zg^R>FG7R(nf|nvi%_wNzSaRJ_6)iLad2G7cp9Y2AhrDU=hFE676QW;b+GAC)akuL~ zm80S^9jtVi{`Th}f zeaJ^cek5UW;dSjO;(K?`O|VSJLBjg}){N$uBvOG>)+0qZfDm>mf zi(x~iaTMZ-Y|Y@Zcjxxz?j)>Z9T}D&H+Muf3>dn0MPtXL^%XK>-oKVlAS1NZSev|> zt5KTNJ3mOM(`~`;|YR$@9*7MlEcn|0r=U z^kFMswGrB5<%6@JH(x)^Z}QS6wO2nNGKwVHQgq>v z1^vnV)>Zs+4lxxjy(6nCb`as+!4qn&uQ`h){V7FL3%BE%6zVV}nv3;F4QS&VRgChJ z1Y=e=l7$ibzt7JOoGZL`4&~Rj6l%|WSc*-ZvbhE{&j-3UUU)YCR*Hlj2G2<=gV548 zhvQ>cH>cfeQt9bXIalCRys#ueu*Q#fYpRz_vwTJ{Tb-<g5k} zGwa|fxJjAACCMu8gqz<&)YgDVQ!<_JlTnUM;AFo?kD0_!Aae3Y!&{J)_x0iv zSHs_p1yF7Hc!ZH>v>m*S4P(GDOKF0!ZbHal8af1vu<%CCQtgg<5e%h>rlv6d=%W@J zEo;QgcEa^VQ#W*YczLLOK38#3{gj6jd??*?o$hOTDmGNM#>+%2-Siv%mlbykwCHOr znuZQLZO8)&x@GQJmGDC%nnO>ObT*|ZtRsmIxjI-S4^)5JMhmdDnU zo>}y!aAR&b?}ik0k{-;a)9*r!yQ^8B?9ZsE^(st-$ByXO+XyX>j5V@wsIgwIGqR@^ zbsj>zG8SYMb#__udU@G_rr;VO$T}$39s%KNXSo`T#T}3j&&3 z9PD5n0{ZaFzu8B^7FrO4#K+`16uDOHq&gmHF$ZSGIl_$~SRf&ad+aXPu0ekhP_)Tx zQTvwh|10dg!H>_ul(FZ~jSk_Uzd?GjnE7p67ga-n;&c80+G7)l!6a zMjJ0@She@0natrBYx1I_$BRbB*f^Ip>g@TiXuL{eu}JfsW5F*2J*NFR`7_Z7J$u>S z?&|fVB9q+QrKhJKTFKL0>S*5jq?omWw=^aXmb~?(B(Bn=ivK;eRH_}WnCgjI@!J>P zO5YVVy|eB5im7VE1=3Z;e*SWicaH&n?CTnJLlRstu0mm(XWrKQP7h zK11!>&lr8aHVs}j{&2zd3uo_;as0E}-qBTBYx>VZ4LzbA5iT`rFRJ>C`*&Xn*>i2w z>v?dvl);4d3hOV4u58WdztilEgzMDYd&ep;@8JVGdmeVVW_w&K-apuu3%nc#a@+haK`gQv?jA83Yo=Cs={=mwltxN_nIS-br!NlDbV z!AjS#7|q?5$eUM`YRao+^HEY&`O6*e4uhjau2^09_RF-$4ZLO9SU)Awr&(XBHR0gR z`Mtj4PJGM3Gbh77<-qJ-i8u$c03Aag+~aMLQL-EM8)5!&!-M1Qe3JQ4tNW48NxfD?;?D#El zHP+J>C@Yo8EjCTybre{Ni-z%y0@!rp6gG!Fd8_oR;esP|*xgIgev2VUf1%2S*qaThtyQtQu z;&)OJSq@;a^=wt}Q3}2Hrd#r;FC_qDnKn?oX#72IC`+9T!h$%LW!ngr?zj5R5v4X< z*Y_Yqfl0-|b)iWuOx5gVL2OZ>_~w~!t(m@4^KTz~nDBUCFqU7Z0$p}78$l&L1xI2# z6p(!m9NFrwRcn1Y^~MVe@#e+6h=MZQ`??mxMO(9!B19e79#?%ADaS+qmM6bzrZ;S0 z*lOXav-5&S7P>mN?yf0|zL{YOO*vR)Al#Ix+>zog(?`e8_n5jJBjlNWILazw7aX^g zkXw#u6*T!HFEs@HEq;wH(5<=qUf^4qT3dH+89eY(y+xe1WUR7F)qBO)s8;@s;6;?2}5P3^|h;qv|QG{9NPdlws@}+8gA<4WxkHD<1mFyL0M`$CKkum9cRtO ziVD|Hj?R?4xUA=hkxct`uz}Z*_nI)*lJi(>kd*B`IK=lWYMs-LfcRE_+}^}DztCjM-z2IS?h@o?2fPJE7YG}`aHe3*bLnq zho}t?9%y{FomGJvCqzXZE4#2@f^t&pS<=Dk`}QHZ`})>D={X}axIK%{E-J;DEqdZZcJ-Tdq6n@@JmhxCN`m z@AS}ZMlPDWF}38a03hrDer0$4^XAIp2>3`pQ(N|MCspRC?Uz?jzxuErW=>&M$@ zrkPu`&G)R%pSaT!8)&(?XLvwP-0PZ{8vsGTKsmxE75zqqY{ zTQ8Tn*B#(!WEjBja)kgM0cA^0gu)X+I=i2DU~RJpqJ3f5$3-s)d!es}LqDH}pBuu} zJUuY^s~9A_>15m2_{uu}U=~9*!Y*RAqPC_C&W!8o#fNKT05Wm`*yViKTn01L4)}_4;FnZwq-Zx}u=b0w8;7Y{I`@>>W?jateDmwt&7SNh)I#qpB1#ohHRY z!=&FBgS|%FFpXk8dc2BpzgC{(a&IFb>WJzL*kBge3A?g;gh_2K2sK4THzz+T7#70@4$Eof$%iW(b2{9-j-1Bc^~6^EG7N>4ZKsT7VL8ld?Y2$`KKhopUBr4K1=h)|=fIXhGuS9oIOPpU_XQ0Oi|W ze6%!YZoK@+rchSdQ>hd|if+-ndQvKuKK zzNR~9_@ky3$6kLVPI1%mTK9%f>ugzc?~Y zxWL)cWHW^3>GG73FAWT-RNWY-^`kFV+mENLvC)6@XlY7iIj?)*aQ|_G?*nexpfd4E zBtQ3k>mhTCKV0JGNJdc~TnqU67o&`{bm4JK(DhIULD-Fiv}%m|_3VHrJ;?p_$V~o8 zU8g7UFWGgP3qPH3ZNVQ_YT8%H=eHeeI0 z{Lhzmt-5+L@0bV5;3)EF4JTgbTlVByHgKn#-BHJ1v%s*II}e}#u>n-RD|7Py$>Y6u z`nzIN4>D0iR*nuF{wwLFwm=!+i zv=_yu?iMz9xZ`>fw35q8Ijvo4z$q7jVU}}fJAiVqYkE9y^fQX&d(X3n?P=m1*~CZz zSgUa06zrN{dV`vtOv2oyv*0^UGpn+t(NuFt52Z@ckUVtH&Km4pfkDr~*-nr7G57Cv zT9E8L(|dur9D#ZM7xNnQS1>=;tZ9Z?T+~NAUiu8)I1ICoKUz(o{tga$ZhlTyvvQ2^ zCIk9`Muo6vjA*;Ec18B3uVwtSK{dKW`!ERmpk+wph4pbO1WsZH~=0bExN!6bJ>iUa8SuU)+Y`5eg@gkZcH}*>uK#e?CRu-^s z<9YL>nNyg{#xW#dE4x5fj;Owz`4)J?TI?siIQ^i!* z;zhcZOjH7>3QiHR+kWk79jEW%(oNp&97_$a5{&}}4qp;Fq}7+uX6gGwuM@x{ZN&n@GDe^5=H|AA9#VT8xqOMh zvm%0tFu@g_Q1C6MboD=<3LC^2dq&a>^fq12SOgQpOBuAE1_rLQY6&%R)7q~Jcr zh5_ou#3vrD{)DzOhFjpbK2OBQ;N_gGVT8qINyRRNL{Tw)wsjqYx0x7Gvy_-3Fk6B5 zHl^(l$K9rmiCJGLHr8~4J&9eNRrCj zK}SC=eg!IO5j_J`qndA$tk@ORQzjLb3xKbpN_I;~c4W&&MN$>k0oAyU&H6BvZ(s<| zmQPD?IHNum6NaeX4ag7dB2vWI?~J%1{8rZSBN=;tsqo_J9_e9EQ}ieO)1uSnh%bV) z`ansB0A10LRtx~#=@E;l28!a{Ao?9!5*2_w8OTydoE0HZEGx#=@aIS3$l(@MS8K~` z4TDA~m`MaQ{?9mKsso)RNhqiVQ~?ua!o~22y&>9y#Sojm&|%34^Wd(-z~_eClR+$`+4%%I3a@o}zb&I5L5OOq zLf_e@y4FcxgrpgYdQG*+7zM0uNNSy_(MyeN_x`SFd{I0tx%HvU$JE1P-&K9o--%Ce zZ)@(P^y!qy#V=ktx9aJ%2_ZRF_>9W4(@t449iHlAr&+$P832GfX*mXIn-}HOS3~UO zh`M5QGyq2De$cVz4rZec;W~HE?v)Mg@act&V~gl<$ML{oNHe%&@{DtvlJ?Hra`zEcLuAJpLB+fO1ZO1uYH76XxFn`~iICKD=PpC5aE%SKeA}_L(#k2_T46ITID40o3 zIip*B#eYWo{G(F}r(dL8D@{rC`a4TvmdY!^2AZXhId*9Dd28#`$N->;kX%+kiNc>y z>+iQI!LOLn%ogY$sFU7ztRV!Ouo%uHw|3p|M0~1^IAw=swsy5g7=2(fq9G+!Yi_c= z#x|Sli@a*Xm@RM}!fG?nbJLNu9&J7p8-K(-?K;bAn;CCnV1!9GJxC!kQ4Yl;a)OK+ zv}ttlXl?0IS~EoOiZ3Y%hCuCp%s!74RraTRusB<^*@lEtt(F)cC;0GJ=j(kb_&cw& zf5FU(GU)0W$6-_Bu*cytix*8`ZQ$Z;ISHQDLuv*XLxk z@K<2$6Dp;$46k=QH^s_^y-G`sKK}dzJ;z z!)4#613&O^Ys51W=w`=PREq^z@8c{0AusjQ|0fF!cNrUQ75V=(|2wfu#vzUe|D?=1 z9`7#WqvI?9WKf|mDOHC7MYMz$2GQ#Gfd3%4zR{!|TbicbPrvLn=!VnpVMfaaQpS#=N!x8vqNWU|eS~Jrs@F z&mk8HT$iF;e^MpL=^O}`P1Cfv;rQD8A^U}>c5lD@jdP1h4k*!Sfp;Iz5O(07_{>*- z{`n=qYC;iMd0w=j|>H4miFxdnm|& zX6T;ed9sxejv+@@MEuIsvLNo2zm^ldm22fZ?J;~wlzl5FmP^AK00cZE--lYrhZ>z# z>ZV^c5h>}9UG~37RFSGSyK9EInEFYYBwDaMX=sKaoyMdn_*zoCrpoEmrJ)#MPC5#l zP$Ncec>Dx~*4zLiy%^jqAFEmOiAXAx-)C|XwesS z5Q=O)F;{Rh6vEYQWjAU879A1DY9T7A{~}N{@}9L57RoCe7BM9eA3}zFj<07 zYY9Ik2LjDg#BZG;c>_YgeX6;YxDt@u)*1VHFblr*PRAL#BSuFS)W;0zpzTcp;srL& zkO~qfQbJKyT(au`wzPC{(UCW=TM6JPd?O2PE=&*Q6LBD@w~UV{39aHOPupV!5Ga6q z%BkX#r2u>Yz)pyy3a_-6M2rWuR6C7D8fi*HV8m95LRvBqK!pmRT3oB(l%x0pkK(PD<17EyIzHtA~zp$zYp|`XCpbZBVjGboRlU7(Mv&|sqS|<;55lv zRsf7*ZZ+i8KJ5_mW7W_SWqDR7+3h8XJxW<>pN7c~m-9;q@;Ov&ng|ZrvDixKUMApM zR0aKApU-o%PI#u)kaN^ZO)wJUE~>q?EBpLgbYBgP*PxLC1kq+eB%PdQ{Eyfj_h1|W zuBlyZiB|Y#xe@q#x$pIti*ckuE(*MEdAkXd{}TUhrUIH2ERi{QN-C4&Xq;)p(9PL5 zyJSE)MZLx-3Fm@Wj}kHk8Uefv@Tr5+T)aW_WinetZvVyPi}@@YGK@}k(I1ou0d&65 zDZJG$_`0$|S^imCgXF#yW&-LG)jR%y!MCw2tYd(WIdv5uZMpu1XzQg_z}Ea9sF|wq z*3_$S4E0{2AHCTxeEnXI7)!k6=`!T`k*2&RRa1;|BCT2yD~<$`>+9u432&{j(63X2 z)LUqMgWM&~D}?)0aKdHszNAD%6lXZ(Tr&6`oiRbUPjZFl)Q{)d;%=dlF4q3DPkx48 zWFZnb5-sgFt2Om)6AXE^4}@-a%5Bzv;pEPY-xOA|JVnS5b*}I=)=7fN3=O)a5VVg; z;Uuh;Ay1-!5*q+Oh`%aLQl1#`xt*`=db9z521XXUCpNYYw{gFplQFnVB!<4T(=f<4J4pV`w7vo|5(FxPMVyVOJ%xw<0nZz8<0lxL>XzkyY``bxw)Sr7l%O3o0 z?ogH~@(0TtZZG~eKkSk{*a|xQdGzPE`PHEPysJltFU_IRXTEUT(ogU=1U}xwv3cLK zx%hFgOE3s}bxu}BrTHj!6gePM0#Di+rlcZuIXKai`>$ha-Rv1u6N}?QPsaCIoZpfXqPuQc>ccD+%`^sVHyhVd(_7 zBM1nFb^q5$H7o%=Zh7+|TpV5CUM{!)O$CBS{;EJ6g_IPCUr7)|uz?P6L!d7=xHa&8 zOppn`wt^CfU)34tTkiN<9=JEm+vDFg^LB&TQVM_s1tY$C&sa=i!B@k=yQCe05Xx17Zg?!Q;>it$qC6T2ni?&i3vlL zM3n@UM1z*~WfdGV5fhQEu_YWI9~`5SgRO}((A0s5O4!Z_ zXl_a*p{PWpVd~&$VQWLg!obGBM6aqKtfVTXsK!I|X-3Qz=xl9j<0R=|WM^&xbYu~u zhGP_UFg0@e93W=oWJ*LO#>2wI%+1Wg%*4#f#>~o1%fw8{#6(FACm;Z4YGd+uW|sf; zfQV7f)W*!ooQU=Fk_r){goTyUr#FleR-d-SOo6s0rbM6P9GyO=u!eKXJnI~fK5wfh zU!1N<6^sSjieY3j?1`e`TxVL>X|AxVQvh}5efN$*Nu+{uq(A3YW%Zxi-ss_{#ZX1X zz>DMz{J7~CKzM)I{~-HK(EWaA#PK^{kN+ch{NsjnRB-N_9Nm=ZLoG31C8K-A%1=wV z*tP2nUvDiS-1~L=TfbyXd!+r4ryi>T<5kJW+uq0HBOzeMw}0#7haRtu&+F00&7-g2 z`}iEt?TGbHe`qA*AAyl>pYd)y=*+c`*N2#H{-xr`Zl-`p=4GYRWQXP<^);@A%`1y> z4ZSe(`P)aQjGIN?OR%rc7QZo7Ys*??RP2A5#0zAtWZE~Y{U*%ufo~c*4!{t(ClAKE zs;&JAaA3jCxxGF)J9KEI_{K+PY|>O55f>M0?ev-vWZaP8DUh{x#mo*zY;;Tg)G9b( z-P^i;F{*nDOW3xR5Fb8e4`K>05Tv9>iteSA6t^&GrW@Q7it+`Nk90JBGQ(pXLWcci zhE9Np2UnGj719bkJBah;Mj?HRF7^Af{!vEXH+jp6#r_6E#j8R5Y20quMx8Tv&24me zMe9|#3+cSoEZ4>6@LKo&kL)e@kcXB2TgvYREp_t2Kgwc%Ax-(%VHWUHG%KRM*Y25I zDG~-^rKVPS=!$I5qYCwc*E^(akWe((ixf;*gJ^$jGB&EH@?DHI3EFPADRodAP@lW^ zQ$ej>O0aUABj;oTR6dNO^L;Vw4_x))QS%vj8Kr*rkWD78a>2l9{5&x*RiU@8?o!gL zYr3sNVr!2>6G4-i#Ots{$CAqskM2!Q_>Hmja&sEujQVn;H^FNxB;A}yrPW6_Bp~q0 zY*=O^c5}@)1J-(hn|%6BkuDA87k~~~rJQft*c-iJ54&Q?0UbX>;7Q*Pr}N!! z#B?T`O$-1ev4hQv;X8ZW*pNHw;U6?6`-MR64lTX#z(4&`phKq& zZQKz%?%)SY!(#n3f|wXv7#uL)FKfftqY6e~$Hy*RwMC`EV;yH$dy@ip$EuBey&Ktg z_p2bRf>sKCZH`oLHE&|Dsh2LmyiYbjk`S1@6A zp=2;p9r>jz0%0E`^j5y!QOae$pj|lL(wqhK>obV&G_N^+@sQgDDCkV}9#SRRS~i=W zrei4;6VFDq{#8hjZO;tkml=R{o^mDEM4P?CMy7|JUlJcgVC7Jk`L*+#^sXM;!9|N@ zVA-Esu(u6o=#Z4F@9tBEB7Rj`ECf2)QjGRkI?+(y*;#z(K<2WLqOm`MCS}38YQtIs zq-2Ki5a3T3X=8ApV)M{t102G}>)WyFX;>E<;?%>RUv)D1h%}3PGfqx6)&%(rcMBLU1voUq5=|N0QbD>S1Z!DgxeeuYcHgwrwn7Ym1qto#mlQW;>yeXG54w1j}&kKbobia zVjoPT>A4ij2_f#9w%B%mT9RD1F8bF*t6p%EimQw{Fw!FYL4*^zu9^kfvnSm=HjX6A zwAXclwG}M1xj31B*2rk+YyQzzhQi2TN>dZdM~6oIQS)#I5~5P;t`;8XgTWlpBxfGBmkMi3m!%(6?N|y zO>*UrtXwBLW$#T^Ds5!*kMkhmam#>o33;4bx~=#x`ph&s$bOyuZOZA3s8^wgoaH(` z-+Y&IzuWUKt6n3FB^#AEQDqCS?KT*rf?g)J9YnZT6Hh%a0)_hxYB^|vf5Zfbtsj|a zDf{XM=&j?my(A0;+x5uU1UM)OiAk<%9+g%j2%5KWH2JXV(!6>%WGDv12$*TE{vo_A z!KqYfO;%17G&lEZ{z#BGTK`yq0s)`Qsf1$TNYf{a(pl;s78DDNj}H3EfA&W>dza_i zF7j<4$RY%JBfACi?J2p;L-byH;^iZ?%uDoE_59@sL)9^QsN_Luv58uVC1w-c;Q&_m z4+dwXSd{|atjPCd6g>|UlB+#|!yRDx@`nM&6^!d-Esc?X&1p--<+b`t`EN@C4Aa!- zYeaCh_j<6cTz70%nV(M!HVCa!VGBC}kN1?p!ifa9_GY&ZZ2|*>6f%l1Qe1~&;oHx7 zN#r`oR(w9bAzGOzw=I;t{RmLimYe~~38)fHlHAzhc%-x^FftBWW?>L5 z!%ksR*mc|_WJLJN6mKUkN=^~EU{eNCq3R?%-)#9G3&Gbk2GB@f?4v_uVffPkdcTOB z!rLVC3y(|NC4zR-#86`V5~Ft$oQA?~_ux!gxncMdh?EC_U{24VdZDoUs<^m?1H@I> zXp95m);j?`5O9KtMouXr9L`9gD_zgr_~Aiqk|24H!Q5_?WJB*vm4{O}6rQ=K`kq>N zfh$A{Qx;SQXRfqi7Dekj5OJQzit;naYK6p2gDpKOY%CV&R*`c{9QCuImEEYosa~vJ z3GO+6ImH!AN9ReQ(xR1|0dey2~luPhmT`Q%r zh8Ez~OkzTx9r0DOA1(&{vWQ+K-CZ&0UV+J;j`0TXwuB!? zAHg{vTaQN{&qjnF*E<9sgcE7QANNMAJ<@RZgwcB`@#ru(xwr= z5r_>`9LU^T4HtXf$YFhVv5~#BrFu~Y>d#OSB;b*a%|&Q(jjrKgi$&~WYrck{q*nHh z2L~~lQBgD*iS_R*TabaX2TKnO!ENaQc~b{9W>hC4jfWu4fy*W$bA?*d!_>zm zq6sodbM)^`MUy5LUi%dQLOlah%9KM-4V&YCKu(C4`?RCgBT`DH3}YCwUm;S=3bKL= zdJ_OD!37?5Nz78%ixMB;-!BWp(gmW*Z+y+A2&aax=4NI4X8(6$X+BGPtJC3^sVnAC{guKAxEm-cvzJ zNCaxGw=b0Ql|qy@CJ_b+dKR=I8r_z8dJ`VVpDD=T1_K*UgpXe=0oXZF>>2RelSeIH z1ZNhhLkJN~x~3R%--!yM3+zc{$^wxqCo3Wn$T7^~qh0a)P9!YViyWIvESaV@IyojSuK?U;p;`f5~S%F7Ugy=8*1U4;9?t>wuY)+ZrBz(*y}n z?Fv-kY22j`=u)HM{vf0cQk={)rGp+rjoj}>YeBVk#LRVjK|z#;2Q5Y5_qSPUae?#6C^elN(qi}c(!5#YPRBXzP!zz8|9)axOSXGu_c%!-9! z4ebSQ0wHyxc%++Vjm2Y%5&BaIGQO=4m=-sUB&6dGvi4XC(+Y2ksKHG4p(jFexB)>j%uw10nPQm%bQ7W3P>E3 zZ;0=V3H9x~e+bM!NdBPr7qbQHUG;Us87Wck*~8C$g=(7~`);1@U}%UnknH~$Y`*;+ zPMlRu+X`I^43tHis@9Ffh7yVhLNth$92g=3%q8eD@e)gp5sDYOhzC13dLkrqDdZ_- zgN6wKQ!}g7s2qU~qQ3!4g+lfE0pSKfjKg5gZesa^6S_hTx{6$LJ&&q4CE{;{1-_(C z6zspZtf7)On($Nam6XL*{TgIZmw6Ua7|l&`-MlkoA0|r=;9hJRNv!Iw(ii?dDjk4Q z8_HBa(eup?1d}?>g@=yom4OAy8Rj%nb8*BE!UhE%{4j1ACXJf3mh_5MyAs7;Si3Tf zgOmx;O(ZZx3`jXjk3ee-Wv)klOnG#@J#bm#ZD{WIB1vL(-KjC)nop-F;5deQLsw*+ z`kE?+1OipE4xS9Uf_x*U8vja#jzPh%eBV>+NMaNp)CP7w1YH>%8I16Y7`=Kxi5uq? zW(;AoxH3a*2F%}%i6C5pG>fht;j%CXjFd`%33I|e#91=?S3Xs01IXRTHBg5MTf~A| zV8rQVB(idk^Q%yT)={u+AcKbqW)`}X1q(>!L8TB|iKNR>x3JN+W?{IeA#dGKq>(S|Z$822di$gjqME@W`*Dl!h0EgfJKTR@Icl z!gWVh$jifY{>D?-1IEX!w21=02eZr{-~7qf;{wE8L12O$j4OiB9CP>4V#r-m17Z~* zfRnB!fvAe}q6)VQATr1Bknu$|gv7T^>Zd;sg|3f0D)045a$6k{HC?N%mCou;i7DFY zdYm1{!f_Oyh!YufiK5#lp58#;<_=KA+)`9?6B+u5?%GYjiE~tt((`3S^PHrm?`FlR zq{?J9PYW5Gg~Ln4iYb2Q>qzNG_OA;b@Jj6@zNtlpDj0&EmNArCwiAGkX7PkP|D+`( zb{>Ra%fW#sTWiGbA5nYMpM))|5K4#D=L|3rvvuI+Gk0+cetrprB1oj?gN=VJ3l0{; zu+A+aYy`GlK$T@iWGyN#J&K?@g50A>JvE{Ujg_DXi&p4j5f#nd=DIIhqY~ra!&$f4 z4Ev#G#O4G7uyNI*Ji?cp zY_%>p8rJ&FX8XMuN%1$94{R#DScJOO05AzmJPcRs8mSGVvB*d#RD$Qs>X~HY{hdA! zALpp;U>Y>=F3=k@hU6E>pWkdcngDV zNa9K5Uu_1@I^zu-DHaNY31qtYypq`qj zh~)i77Xt)Pj-SxEgGyp(SkpwN zOm7F`gNzRf*$udy?ln9Fv%}9ttd55ci1% zw1(z0d)l4rbxyGn!g!eJT*qQPlKwzgG6sW-0An~yUZv8*!|=$pYxycmHjEvdmkmsy zFF|*FjQ}yhHyTpC?VAzcTucm1;T(#NPi2 zOlm8MTN;?kg}~c83Kw5IFBW$0;W4oU^RrO#RN`{Wn~xE`T$7gP#sTOd_fCu<{y;*- zN81R{43uz+To48TG{*`h@a1Syq3FIyCH!$l2muZ6iiqJVx1y7-6aWO4txEp_7r~_s zbe)er1SR_=v7(p$#)pFu?N1sxGNePPIv{M;A0Y$C%|QSR3&ohFb&jJlTBKKsbLID!=XG2U=ReiI#-IiK)IRH5xIHqX~k6a3IA< zjgFb?$iqUAmEC6t36e*H%p6KPF`jkS5-HFw;2<$i9H@ghuViu*3nX}OC^`j>2dIZ% zWF0kS3nULwRXbi4_aC+gxkqcoH%I|YlCfAQf+B*BaU zrpNW*dplC1FardXxp;YQnLq%o=0)*5FxvpD9#jU@L40uN=w7ItD(Z>+C*n$P4a3|0SfS5y4IK^?|VSh{=Gx?V&+B33}B_2351wZ zw?P3Lg`XKJ#UGleXTIVoLxh+kq{fPqMH)#- z`NDuMZ+JG^hUv$vbr!`ZyZy$#yhSkU5i*^6$^#b8C^jlG4N36qm1j#shUIS{-~sED z>>34`OED=4z*-FjZ;|C0eC7c+cN11hWmww8z}!?aK%5eFUpI5xS&;_)uOheOutqa} zG`hlV2tOe58tXOE8PoQknK;{N9ojJPx^m~%OfrFLHIy=74)3XYGi{m>NGiL#&3ky=@NYQS~)lK>nIBM7> z)_&XePOT|pm^D1YUR95w7CqD-FEpyw<*<>fWHyFyhJdf^w3QoX9!JF3>C1M;ZE%~= z(rrVmCPy3I&q-j}kRse;K0+`W=88DWVgwe)8Bs~)&#U=ODSAL5ZBMb42$`~5TuNv( zx7`mgV~=GrkKe4VpP-imgoHbqhcn&p64k>EznASW8~y&-VVK&g;g>txQRzNVUjepE z%`HdBp%TrWE<^44%m>f_MvRH|yEv>ft~o^W_{)!HdbWQz@5j5@L}>IEY?m&XJCGx6 z2r@)O1ysKajm1P3G^UD%gDgDR%Mb`0{D zGbiG^JtK4Xnn#_diPnKxh#9W{S%Bf-7FxHd&4&e1NhnHALiVQ0z#mkIkQjwVJALNJ z!zOh7SGx@eHN4+BrFOf>O8*?TAz=^}?)=U*NeA*^M!5MX)G=S4oaA)`kxk3T{Um=J z&PSi6ij?~?QlW!6%OW39AG#HS3YhJIG*4{~3F*U*uiZW|Z(0j+z*VHhVzoZMctTR= zDeUzg6tw<<{AG~8(0w(#I{0WPooKeT34gX7g9x!mOe9eK3;pbFhA1Se1(W>mY%ld- z*}`7C$y#3=>rz)#oT570Bo<&=;!JKy#l~Kls56FzA8xF+j+Xy|mIDf^c?%E#dX`ti z$oa^6&)y9KC4uBK2|jTh=`%@~e1rX-jtxdyFx>r3qA&RvwALNWTn-PV)_pgE7if4B zlwt?f`z^P}QZV0;waZZPmT4JbTxE)D8NqCkkkG%@9h-@^RkH7JL3INgE(1&d&Wz6L zYb6tMwBd5c(D&0{wc0H6ULpP8{6*k*!b0T(U__21!{ostdwU7cG9U;GN3qc}ASn6+ z`RO=db)aB8^{h~5ruJExIAC2uU_8yORA3NL@0XVgr81k$?5tFTBGK-TmkV1n0kxiP zRw{0Gpwo}bg;dydXDId3y)1gmq9zH(E(mM*%=OZFtcJ^hCJFdGu|_fR^7r7t5Pmt1 z6?_Dod#)9e8maj!m_&IO1$f+xI2LOH>1Df^M0p8}y%2sijum4BJc7FV(V%{%X~Pwh zXJ&`xe$#}}kr|_y6!~HbU?{&KM_OsL7C*_i1dH)wBcwEW3g-S${%;&FzNCX zT)-dvmK}kr_KJE-vUqzo&Xu_6?W@Mn<%aL$gQejUwX+sL6b? zI*W^vHUNnVY?9mg$!f#NXdJ*RrD1@p?c`~Vm}zt zc>a8jU}Zr38F3T!Gl}vjX)y<+H6Zy+xQTkPzttqBT%MTZxRABFcuyu$`@UxtJ<52# zUUIRR2(v$#zma3G3(#^_*Fww`?^$s*Yqn5t_odHgAKfefpcAU-vuE(ywFAob@-ONC9#20j35|-6~HI$R@uHZ2P#V7WhNy}XK zJ%GE{c(+XGup?5sWH)V&JMnvHUwVVk1Os7&jRJxHBF28EV?fw>gtLNrng`83BQ}F0 z%^${aW=|XtM}f)JIlI(ZyLpCM&zH=?8%&1&2 z9H{vV>$r-S^dZ)DAz``DJmfBH>Ti`viP1gxn`T?ec07s>zo?1BNpA=*nbJ-AE^j=S zJqG(oB07lJjpHNkujG%Hm4~ksS3?3)}gz8k5*bx>mzR@9bi}Yfjx(bl7|Eq z-o>t}nNc*7qPxx)$#a(SG@poHC)Y=T~5|cd1nsgcMcBs@Y}3(Jrv0o-!|-{!-7h{3YL%V_By_USJvZTSS!{+sU~c zl}c5<0#!_vx)Rk;6|xG|OLe0PHC45#8nsb1t_F2R)uI;lOjW#21xA&)UWH8csa{1$ zb)i8;PqnU5#Z5J;NhML$qFJR@RlG%ILKVMN+|g7>Zt!&MD%Em5sh1^b zh*s3Byp-^~pzMo*wtAa~0X9%|vb%n#xC(6SKEnk-m0`b{nrk&_!5dhwT%wOW)||zm zNR{EX>X>JBVo?!N-&=xDFy@lO5ki&mG42!JtC`x87b!5*;c0p+e<;sbpvZcegzcSY z5juG+GWp^FHT`{al9k8mh9dXZuZ)&2QD1f&cg$~TOY~(5czMpPa5|SQc;}B_Px;lx z%ocHL5-X}6ETg`(ZEh8n zQ1{pF%Lc zo#l$53dj`~1Uxl-%@Ds<%oilZDC^W8;;0|^@9EN14uJ&;)N=w(lE0qZ7gWSc?$k*! z^$~MdTaHP<7H-9t2ud}W+f0nk7z^O>)l_lx3G;MTj_V`pKB8!bX5<~!5JOKJ3upwL zT(j%GnpmE&Ca1|o`GxEzmU+%7{bF&(!})Dk%pneZnwVcVr)o>%A&DyDQN=B)>oc?L zV#9=zr_Ts+$S<3o(+Xl^55@VOQk<*;9G#mFv#d-^U)79))KHzPsAKqUnZ%y#D391Y zL{nQvzof;-!G44DeX1DK(10i8?fr4w>TR?^cg3ZK9p8(}K@8XeAF{n}=U< z!9RYd4A~rB6Xu>rZD0a}>wJYN@b05_+Gub^0=Z;kwHN4uxCM2>&6+%h8QjdTP~B&K=(38$2#BldvKpSE)_y8EIr7+ao}lvo>yc7U zyRu3yW-D|{t-w&Z*+Zkawz=#}Eq<>`=fJ?L*vRH$bjNQ0j6jK{VQa`<4>4?Vxcw*K z6tPsGepd4O+vvT$jbdy=5g4xS;)vrp%QQiAHpUIWSGdbJ;ZtNAp!8PJ!>;k4h+d3JPkd=SYY5^0w#EU59?OhHFIJxwK%# z9=s%~j2=ANvo+vBtlLGgWrI3!h_o;{S(4~tNxK_Y^={aCxp@67;ebd2SIZphQNt$4 zxQeZ&WM6+$;Ock~_#1MX`5u$6r>dLFX>mpz^D$nfm*a`MMH4@UakB~3n}T|IOj-Z! zj#=+WIF~rcJJpIC|8?PRhr9bHSmuG@;e$^05l!R~k?cx$1f}K69(S3>O59Cs|FQgq zm+T@BZgl_e0~IO(Y@=nnxU~Qizc;p*q5E{J5Bejt56UG+C%Wrh(1&5gz4!2Lx5B+C zl!t?0Y$gV`FSGH~*o)a)r#jP z1H!jcA~mA+edN1tJ+=6uKg*^KF}VgU8CL{A839MqR|?Xj5CILO9GIPusKh9sW&r(V zCXB^L&rQ6bq}SJd;iaqKgGJz?R;oD&m$5Tpm8!~lti|J`|DEE6N+Mx^U{RQ>Kl)9U9Uxvcm!Q{<_Bk)LyD)()<)!Q&G+GI4p{g zKgW=ggD=fMZ55diS-rk$G(16@{y8PC3*9B#Y!(02l(p`@<&SW%U+5`gBwa@FwpbW> zX<=GAYvS&fUF^mBV+o^_7c);I??Nx50JW(^26ttmY6YT!{l(-AYyBs~8u_ohfV{B)_QYK7UNP zJM_`6kgVNBlDTOuS1(>m&&^S%_;D5!=O~(03hBHs&QT(|g}CHs_qKE%vDX~(Hb$7V zVbN*l`6$5Ay!!bG`c=b~AiSCv0-S-cuk%}KI!AVj3FAxe%TBo z0kUG7LNQZ1cRJg&f}RbA3pWWfy z2Q+=(4LF%&>iqV3;Oz@HrLDI64r1aSekO?<|95FzPQCGz4c{7$VmJGN$O1As(vyrIe6Ag*<-RFa`vU3?K-Ru znPsiv=g6GR^3B*jxl9gLQ3{_PQ758`%WGXyIKiPX-%sn*25pU#IY6h$PQbA@_ZWj7 zl+M_Qa+JjLXuW5OJ$#`e{OorMhSbeaYF?{n9Ae1Ty3Dh*q-9iR?4s%Z+w^~K;J_=w zgjv}Rew*Y&%jNm1^=Xi*^Kb|3#5y(vrznWRl-oliI!T6@Zs`Ov_UnzE|1F{mwWlM_ zNy0dqyj!94-5Gs1({rP`M{ghGuQg{D!7V`1Gwcz#`9e|vBVUju+tcljrr~Ps(fIoa@Ow=Doo-f5{jxgs9akn-Q|W^;v1=8+ZntPl z`3Z|o54jUbS>3P;RnfL|)*!9qp3ep`0`V!O$%$5fyUt}t z9~GVe*6H{Q?H-U3nG<6Jk< zYi24f53I3_XmD9b@9>+Y{W}ws#jVzZf9N8AhkSHN6UNXprdUq!F$Of2(539JiQ{m^ zh2?mH+B>us{^U%}v{88Df4F=wvh-T@LgWif8Z`rQ=KQEzsFpf`2Yr+M3+E6E8l#5r zP=jyWkHKdCYv@*5)UQXXkN^0=D65L-BmtD}ZK;as-PbA5t-nped;bp~6FtWqMtVy| zH0;?$kt+M!>*MJB6nTO z5M@(4-O;kbdXp1)`!{$@hOo_)!l?{;4b_H%avJxB-ol6vOo<%K!vAtSRT($R>nQU3 zi?hl-O5uX_<&)b9ITDuCrR*&FsYXWy2Y2#Caeb0nUe&D3UN7F@ik0$<&+LX>V>rz>bsLpJ9UqZ5FlDN;uEl zbka(4!jkU6HZi8Vb-_9Vo&@tQhUJlIRXlu2MI9b~;j=~RQAHol6S6wH;B)lGw4h6@0Ze#Vll}|%ag|OqWA<>5ewX+K z^3yk_1AoXb4n#p@h|%lG?i_jS6>Yb{wV#UvtI}ZT0bk6$I9ZqpmxylVizE!b&-1D8h6&4RahsvqIpdkZP}FNi-FjTI4kMa^gin{_PGhiZxHsTVVn zOV^~f8hYRskCs$zhs2^)Onx6Am5KgUnR^27^N#U%7sqE4C%(BoGC_cH;f){4Hq{j# z9CdFW8L)hYI}SO0xeP@Hj3aI9i=7%ApnmE1z|H@LWN+ryf3Lbxk>#l-#rCkWK6| zPWj6G&q>vLUFV`Uvst z0MjX=EQrkfcih|U=eQ(akIzurob`F^-z-V;eTId$q>It>f8(4_t?qe88jxE^4#QyW z?5;8yl-pvIy^9V@@_vq{>fHaAL(54v7r1wQh;J?Nu1VvaDtGiZ@;8-WI@`oM4U(hV zT{Id>UwCsgYW|@a@zS#I=5x-4pucFwCDHIqc*&5_aQ%yBee*6I@yNr$ym=En1YG zBlJB6|K;nZE}NBNOZeojo7!3{#Ja;au$TY0q7YqSdHoe{?e2zq_N|_psXm#>TR_@l z^j~GuI8zG8TptaMsbQ~6v&r>6na=xb@_+MuR8vNaBo5DEy|^wb10CZ>aL<2(7h6(o zlAc~f7gH~mTW0fMFvgOvK#K2w45D*{`;hI{S)Jmw5g)g3#o%>g1g;*5gg%P)= z^8xgV_%#u#>9Rh&%s=8o;R_#3%c_hV2SxSM9_>b3s}j|+>S#glMAC2nQwhS6`qEY> zo}un}*V!zh=Om|mh>YAu1jFY)kXyhRmNl$Erz%bLcNjka3~swwF`6&x9tpM}4rpUeT5+`0GkZj^9bEy_spwX6=iG zX^s!k=Xdk#>eBZ&m1B(gk8roLRg}*{$aYzyez)i|ywh+PjFxb!oz^Yd zhx#@mwaXy693O?&_&LOy{IdmTS{OW}m3+oe{Kq-O`oAcTa{G&Noaiis8|} zq$8lb3_Ve^?81@g%=_x=9Qj%7sH0q-64-Ymd$7kmf+p2`chl@HHv6+KyA0QoSGc&O)#g{&{G?rW*aFijBCf2)@MjL0 z*X7PwR&OnJ6Y>kkP%STRdlO5Anp4yzVi2LrD;_Rc%M4AwVere#Y2HmXM58=NP$5s3 zo23kj2yD=G^WziXo5v}D*MM0`L1$6hrPPc0)RAz<3QpNDNInu{BmDqq54Os=$NpDF zLj2QhnzE5zpjd*qkp5u6B!P|Ltb`)(4Gh;Y_sQ(eIc@8kj~M4K2pDc{a^!LC`a_f7d?63HpbE z{oC&y?OMvm-RPsJEeIX@`wm(_!_9ng)iwbgUHeV+(Z>k?|D_}$WfRMQ!%`(KAk2K* zrjziLv&tcRH5wk>&JloOWMZy#r6RVogv}+=lK*oRHfohQQ|gE-wAlRsUp0>&)9!FS zjoZqA-umI{hrGek$V5yQ0^?V8NjfbV zAz*TiOgK0#f~Mt;*kU2N+(`|W@dR3HbmcUCf9NpulVmJy)p8siaMGE-aTO(<^&WMX zRaAIuPFwc1x@#gxpmDc&Gkv5>neOqyIzGXswx0H8`Vuugg};sG4LkmSDM^4?KY6z> zTIVKs>5S#~s2uw0|GelgBCC+>H9ptvwS1cP4TFbl5UBaQhU=oLlpCa^b75Z}b zN_57GzR;{9Icq^9lU%!PO1;ptr6OWDRMXe1LI#5M;ybQWBP%uGUG7@QA8w0lrk?9l z$}4JadR4w)ePqS6`+WqYZ9VK9pA3alvlQ4D%7q1*Sc~jLu!!2z_UQ6RQKD{00sH|& zp%!>F@gc+}bV^$BS;#c?ltcIYI6+DblR+;5!eP35^4&*4M2Q&tXilYbFohD1LfTHO z?>#tLk`z;kTe)28db#p!_m#`rqnAs(f9&vaes+rP*%X$B`=dxTp)tbZIQoJPd5;*~ z^(Agm@@4gZEJ6Khe*Dhq__1TX7%wTP8>f1CNCAPXsH*#00 z5}pLwxJ)e1{ZU$aTO_I%G|vr+0!OPL6<%|^=OWS>3kAk=?qy(;X+T1uxDuIaT+BE* zAdWTig>_EY-_%uOr}%RXI8zO+ev>W+6h~~F8*a~y%pm3MWgJMtehZso*^#aD3@Gdm zU48@qlqe9Dwgl}Mc^Dc(RK7W$KiGmAX^Fi)ZcGvVHl{3`J00kcA9>FbGb3YP4BY0W z!uLs^^JftBz*XRZ3bEWSpeWfnGTkPO9FMt!fY3|B7?VfXH zXVM>}9HBKJvqt-;iYY zly(9K`Fn~uC=q76iiFi^(PnW@9!QAv0U^00h{9jHAd~asqzepz1Le(eNdhKsNdU($cGY1~ z4p2kbrA-Tmr|JGmvJHaa6;^sL5`db+S1|y8H16P2Au){tCRTgRm|fdfJw~^UItqP& zCaqNhKg;&Cvz+^8w`bVJcd>%%@;Sh9p4@CMZSdWSk!TbAo zXrhA3g7d<(6QG9zoMCkhq?nlhSMpGS82Fo0g=17d&4}|;@z4WZDGeec#dMh4^CK3H z=u8_cmp zzsK+qCt}B{cwxd73 zAxR;7)ZfmCtCO67ZWNouB-_#20hj9a;-Y?sE1VIo=!zl{xo|Au>|=5 z!DPWHzg}JWSY%wF;qkXN?=8+@+#w$;q~ezC(@&}*rS94QTpY5}WI@0@f)X(LYFQhom!_pjUN;(tT*Pw`;4gdM2qn6b?_`hLD)yO1n_X1oX_i7F{d} z`zGkbLfFPDsE-78(I{LNeI!cqJ7}O1N-UyA#LdFUCSNS!z~=iMoNGNSJ@L@lCrG`L zDIukrn>k{yL+NT+kt-gt2?#-5jOYk#i6;FIpAD%A<}uZ)Vo|Xu$e?{-Q9Cf{z}E<1 z#+yOtneqrh9bhtpme!;m%a2JQzeqzW4$sEjNe~G+_9G4JD=ADtUu2@9vTDXUq~=3E zg3-dxGQrxyzQI|5yTw8jA!xW^6E6`aR!sMx0ua;aDEwmKUUY<;jnsq#MDt;TA%05Y z0xFJBs8oq@z4r0~#Y(rWcPUwst#ZMwJ+bJJCOUe#2!sOs@j`;kFY{wLUX^4~tpW^z z;82L!F!XT2FGP(b9p&CN{?Bd!*8_$k`tYVk$*nq!9u0W7x73LL?Fs zumS`LB#CtXpxPyIWyaHF^&Mj>B~tSKo`y|+O?vB5=tcD#cH)6*KRX_r2j_$KFiE1p z2$6KTN7!bA2NCV|&cJ1pp{xxDQKX|$jF6PI3FF`}%7@sp1~NfMoZO{ zaU3TsfQ*4`)dQEE6@{SJ4>4GuRKt>L;3p_N z6b}Jkdsj*_$`YqUDlV3<7qD@Z{+eeG3IuB~B}87vj!5c5B;&J6AV`#Wkr67QpW~(Y$QD%yQkTX7B7xrA0h)_aO!d+R0#y}Uq zLQ4q>`WafHT2{^4&`3}91nJLk?@B*3;dM{5F3ZeQRsax+gdFe%ui5>%I67W*aVDt>H+z|>9Do#TZc6@E9O4Kr)J?z>s_V^&2B90xCZrh!L#&^IKq67{3H90f@jL@j+T_C5$YO z5R%SGD6%zKgjPrhA?ELxdQR|m5mu5^|Ji}Bu!+mf7ii(^qV8Wnzr>?)=MUTfw(X>`&Bj*aw6Sg5M&qQhZ5xek>%K|)zxRH6pY86Roij6MX0n~%o|gvNG)P!g zUS?cVxhsNDYk$`gGD)4zW2RySNg#g#a%k=$FG%V@lyX=d-xri?$xCUI@3E}SdaJwN zN~%wc3xY;z(bwAf*uwzG5~OcIB4q7FlAJ|gG-fz|j$cRWCzC%(IOSjH`}H+trZqB= zD^)9i78%3l8EK-7uMFV?3nscDgG;B3@F7QX)VGoT;fiI~Z$et}! ziWDPk)nCR8S1aZ|?;((p8D8{mhAaFNtsJ@CBp+lj)`@B1Gocy|`M$ zp^Ya@9P;aUt#Grr+@;BnZdYx1f}lC|1^TllSBq5N{PTztOc(E1M1)hhJ)y@!g`4?M zRF0V%1DSmI?EZ49D4OR6Hj|?8)Y(7C2cSsT`fR274D&3*&&pb*v0y@kez!4Rq@E34@HdAqIT&Y- z|LFZK&b$HDs$(UXM;H1E7GFWFgR0vy$JT`&k)va_zhR2bCO8FlljETKom=&Lsi6(a z+|LRAUViu4PrbO=S+vS%y0WO_N+Uz^=2+hg=B>xIstr61I&kTtE>XQem_@SCU|oJ7 z35An@@L)79j)4r*gTP6!^=YBPdXH5K0j>V3Xkx(nl&>G(Ml=i8tv1eq63QVdAQf^Bhzg_2}jU;>|cB1Q}Ta z^~`U>FUFu1th?zzMfZ6Dx7*fGd3}5=;W`&C!er`2G=Zic_>QqrCFO9-xa(J3q4ol z%kKrx9P^XmQJ8mpR7>fWKlUQSYA5ko+9T?ka{Pdn;=lc=9*Ou9fCg0K!~NuSLdiD# zS#>lyf$b43oL)1LfBe?;MhYuwD9;*`O(dh&%j-&-v1f4$l3iF?$JD6J<8fVp-L+GltBuIz`LPn2q^?L1Z+DO&@R)NojMdRL;Fjs0HT1g~%EJQ}LrUv(27jeWE@ zV|mh(^wagQ#$f^_h45=Gj>^cRP&=XCYe)54w}sB;TgK-yEu#R`NNvfgFP3LDUh45u zg3)m|#|0j+pF+MG$8ci3oXj*0AHlX%k%af@cy7XF?W#6X)-d`4@d(&8}GT zgAr28k{=KC{qWN_`2^J>8mkV*jwMLQSF%>g;4iG1HK}7U=@C@OCM;5D=16M_-Oc7N zk|^wZhp-6W<`oNqceYaLwt{wJ^R3iBaNj(G^-~C*vD&Wp?c)uMao`v2kwhq?KkOv> zI)n5J;33dw=5n?8>Dwk_sx-d-IrPvw6dH@C;`{aC>Fo0y@Do(lCL7iGd*JjD^j*-9 zBY|jw4&!{X-m^G=%|g%k2k1LHTY!(<1a-!hIP7ExnqYA@gUW4PfJ|C9tV0F#_Nb76 zI5jMO1Zw^2W!td+H3#yf-#;}a>`mt1@QOeVR%fD@7%2f22MerR2pbsEa=nO@Kn!D@ zKWa_Cjh}jm?n(d63?4@T35_GX4$i-EYIL6709Z@2S|gR>@9?IUrzmt;Pj??5b3SNe z=%3LW2SIyGXfGYu?vU}`Og7VTVEWUdHTw9IJayWMqMwpqoyVff5q{2lMJ#8k-p~nC!ghNwq;w{e_D}gG-`^K=OcvUq9HN=ra@OORdmw zz4u=xk{S`%FZiO$XAy&gHM+1riN;1GnJ713TJfK^4D}IQgJLzlTlTA0#sL}C6EEZ& zpqk1S>EZF@VJqV|wk>2x*(x)HU8|kmNrZEd zZ^YVP*v9mYF_4V zqbPd8nI`3nm`>`KLJ`2YdXAcgm=ux_6isT`!%*wPL>rHzCigCqVD(KBPvXUI^wo1c zs-6oa8`I3!V%@5eeZz2S6=18iEzD{aH=#Sql3i5wucDeH2puH6=Tf$d0=Hw;H!0(> zAOk@JKp&{srDlD;;44~|7Cric1L&rzW9|9#GG#(iG@Tp^WmpwAp&f32@H6NeXlW^o zp-+Z@4$*y5c!$NKDSuQS4M+ALlQoDO4FyF-rIOzw5w}tHe zxb#ptGZ7&lnFD5Fm)&Gs)RcYqd_|cP&!-$52&z-L03;xf^*hi z=G6;d(b;`0cTJC^dLdm3Z|{~2wuE~BsO$SIump!r9-Y?@WP1;gp0mT0M@_k!!LyPKO!)w{Jpy?$_n(PWyHX=FF32N(@q^|x6iA;N5PXVQsQma~k z;DKl_x%0yy7lK98LG#OEsDE?p9cBf((Iw|3PrucvX~D=%zv%E+kCfqOGGvN%I^rdS|$aT7W(}@pheM^8<9dDK2*JHQ-3orIbCW4eVqoSpWpB@zc7uB4mV@Z+D@X zX;2mUQ@ddEBEg3IxNb-{Sx_GZa^ao{gk}!o6U#R-gdCy?iPtmohG;Y*`pMdfQGRr1 zQw_u~T&Zdhb_gSJgbyrWUeStWM-%nr&atKJUDg~su?^Z+fvr+m#X=H0fM5Lb?v`4S zD@({Q;yT&FSvr5VfN33}G{6l=3G^X3Fipvd;Ah$|E z`^m1u+~X2sVLHFT))SPKCyjP^#!z~K_^hDFAxC;_ZUkvWs=V5V=f8mjLK+0cRH5?= zGL7_LDLV1F%B~-Ko_o6ksi@C5&DJ3Jj1*V;p3x9o^w8FPkc`Oxrx{e^SW=)6);&uWmLE9^7ch6y;#i)>`xv;^-PNYLL3-t4OyOdr#`w#K94M zXfM$Tgk>5q3OsPZ;-z6^`$%aJL}eP}3NLh(@P8|;@|*SbLJuo~^IeHeSCW%2QjZ4a z$|}ft#nn#;1oD)0XWMstf}*z_C@>{34C7)U3$bXRk?G}2N)gi@h|8Ap6nfd{IX&j9 z74nmq&N@E7*n4wS4nEUm6m+wg%FTwpM#BeK6YX%gPSKH0iX9rg#Cnp3o$%{*-ECBMlo3v`0;W1QR`!9#+(eOiblX%_yStsyShj0)sh|lQA}@@Wl(0R!5%r z4Mip@fn`^w4GH+*8_$MfMbutOdqTH-ja?Rm=?X*|q>$)g>!G45h!-Ib?ULpQ7-3*5$ARtGel}Au#nD#3qKez6K&Rte9=hy%GK>Ptk)}hZk^O&x*c)c2vuRBfl4`05 zm}TxkiigoEITy(m4KX7p7BI-ve$Ky;t#!0lDpI#qpf6T0R`^T=**+`P@u{ZHYIlWNikE)j3Z|roSUDe6CRN zw|S&ELxg{uFGl93)|%qR*k0s6%M7wlFXhL|6tQZMt0-De$m5i*&gWriw_r=&5B)++ zvaP@|STXpU(^uIf^c5FA zVte~OkT{4*H(137Q6~{uHPRIYe&P~)Qt-IV$!APOGf5{mS#;(VN&(`(_5okw+NRvd z6&Gcks$~}hRzL+w(Uo?g(^9aOEDL?}%_g#@GK+r)jHVY`;Zf`ss|W50l^t+qUp5tM z1W7}c;E-~paIpwau$#?LfF=?M@{>V%h6pJ+k8NggLq$z8aDb` z0?X29!FSyM#M2n6cLbChOl!Y{r&OKw3#LdMZYD!? zCSWgLxVTiPUH~IR&i<81sWUr;rf3j#rC1Dkcn@5rcvQIFPkx)dF=<+MDhE@xNC0o8 z&Ws9ovZcH?nQ#SHLWyF(T)ntm?Dns`gIuFe0!6{3Tbm+s{0T~aaJ_v5z0zeKXH1cN z<)4fNSzQ(<{*;vb=a<8zKIwccNPmu`w3)0Bou290%#p#qd>^|bp9bN1)v=orx2e@D0i z=X*_xfGS}9QOtyty4gPui%nhc`QWDXiYiQ#yUJG#c$r(YCUU?SswvvyrI;^S*CKC_ zRN$2Pfb@=$#5wQ`FF2DDw+`p^4Tqzd2F;+tcp9_)sd(TijmJ{M>b25wf5Tf|hXK3@ zrm9v{5pvQ4>o=o##7IOLoH7Xjy0yocs;S!IqXY>&MBs~n$k;0p>@FDm;s>BmoFa?n zUM^Bv;U?aO`~^{h1d@(@mKw4QpMWByosjLJyDqS!WkB=nj+i9T_R3dUr0Ser9+zTQ zV!u#jVNgx!^Qu?6kN!@>6dT)ASwO@GZ}`nv>tBBmG6%)p?kSpDO5?ntGh!G>>6tMg zOZ`-(tI;JMJ6oLxFs0?mF;2P;GpSDvFqz!m#42rJGX-ywfR<1?HtH3;ruQ2}Af-=N zR^qBN2RND~ZWX~~p`6g%EF<7Hpf(Brh{7}`#8mJ9f=dcOVdfjq$@mhM{-AGeGVS+_ z=Pp3pC9#-(MyhM~d2Xn^(|#s^JE0^YS@`rcAWf#M{k-M=YZDsN;u5Q*(8DH23Ez{X}{x+2Eu)95Lj5tN|@IVN1dJU0f z_!y5lu)CL5$7(S=%+(Vru)z?&p)h~0dp)x(EKS3J=fPCa+8rhRVdN)$%6b`Adq!`M zUOQVgaa3++F)(L+5+vGq2%2~!Wi%%fvu+elO4r_Kn4|8wQ8M=5&kuVl5Lp+GJ`mI| z*V)lbi80HnEZ+ezOgib<1)KPAb!aNg(>(o_&}WywdC=yeZ3CR70*kz7&0Aw%Gf-_3 ze)kTR^_6az(E(vqHb%^n7diGbJ?*qVkYWzjE5ni6Ep5v$E<$AS89J+R&mLVM)Yp(> z($2cJmTU6_fGH~8Oy}_B0$3ObWmoyT{L$!Nl62+O3zedRV>i?+XFi4-k815ph>~5< z83{8MFZ@ZGWcd<3_ zzIHH5DEBkKwS8N#cMduv#+b!wWv5~mw;8wmLGZ+BGdKprvGy2(yVpmkc`GglQ~rJ5T{^QkM%$5l9?LM#$485-fC;o8Hy0=lOy;|eWE zB9Lk9kmmOWvB&m8p`P($5LR5o_P3{K;h?0njt`^48XXswP|F^3eC<6@B0ZuJR60qk zJxm=@z#~%4Lx~Rv#=K>#Z10T|Fui{}_v0>Y1FhM3;?t6gKy8yXO-fvDf%Ik3MDoDB zH~hEayYJ=s>3cp>iNq;?HgWVDg~}ZZfdB3M-fPTdlvwa{7Ei=@dbX3h>qw2v4I}TZ z%i0Z8a=~|MZfm}48oBGzLAR-k3($a%lmFgy2{WbRYzv_&lVPG;8B`?kId&Aa?VN9MOBHQ`+y$eVY?%!9xlK{=%+WWM;udSon?k{8B z(=H0CI;PQKwwg?1QM&`i&bAeyxsRSv(~SjZ z7pJv=>bNEtz?EkK26QaPM8OtsN{5j@2}%F^HHY z@fAIZsa{^SIuFg3|F|9plBg~&3}UWz(8Q5mq-d!UmIE-6_uhHy$b1qDc<{Rz;I@NK zqhKd5;aLDxHTm8WduyqHI%3p(JuBW#TMZ0~iR4?Q^H5{?Z}KCn9b(iINhY{;>b4Ce z8k_PD|5}f4<65bIQi}b$;)B04!$*+}9sNx-eJTEK$y;5F1*l(LtLUT*@HQ zlVNC_QMApsTkRs|mcM{TZ?{Nc>$+*_(~%#lP$^K4NLp$DA0m54#N6Vn%c6Rp>iUiP zKUpG+Lzlp;Nw~i^HYXT9SOZTPCcQ98E-awkszR|;*A!T!2f$8)O`+=in=SLI^=QF? z1Q{Hhv~{h)Dc~M1(ch{Kcn{!B_D2@YW;v~<3Ew}!fr1=p<-Gmds{dM*9n3eC>R+i% z-$!C?S7Z*>Zpv(h_-G&Y-=Fq!IVOLGm3;LAfMC`YQcC9K$c)cMdHWx8AgoCAc3$T!6l}^k@12M{l~8c|3vSRJ4>>e?e36-+@IklGN+o1? zXeZL}z6S6Y!z~A*Fr8A=%z^Ar;k^S4ZjlFe(7}}&qeTr>MEjTj{;@>ybV}>s#RYf@ z>J9ONF#YQuh!k3hU)#utYjM$A%ECq4ApIV?f1ha;Yt(v?BgS7Dv@M|77U_O@W0Kww zy)~T#{~F{750R6=!t#mlr zn>_u~E}0e7Dyk?5S0;Eh*kM-V;NVspLf{9h=cjGEptpWcd-TVWdu+jWVsV?B`}f&D zugq6vO|dLnXy<0G6M#0r+~m04j|-Fe;20$I!&0Q!np!r(8bpDmNb{r4{zs`_Z+S zk8BL5fH@d%9*Wbt-z8ve$$n?@w5W0+0Dce*;3(?(DULTJ3hUUQ=+`y3?-zQv0NfP9 z(t99rQ^QbL%`R%4)miXmv}jONoo@osYB^U@TZ836ckl$&1YIl~V7h3~qi=LsWnW(tlLb)2by&;}JP{YJ^pFhYDFKGBY5@ zzqY^OHxwRzIjfl$Dr^Sa{l@J1O--^kwD+DO0lC0svsUZWWn1oz$N~UhO2%EK(R-%@lkfDF|GxcE?;^x? zOJ~f#<7o=_84)+@rqz$du2>tcMLe-a_0LAeXS(qHFnS+6_ufErimSDw(J_dPZNNrIu!Fe7*f&~q#kg< z9DpUhJ8bLV989?2O-dMWF=eTn?AYPcdqEjcWQD37y5L$dAm~G#$OH3H<^boLt(|a4 z-fEEj%lE}Tp?JVY%BBw@)q~RMBJU5f?y^6?!fZc{F3~cbRH^!pCtji85gBr{oxo@l zkfYtYcr(-kY+|^UK6*4P`+}m1;j{!@%R748q=*eC$cxOngRu@rmB?e6@Q;j2hPlcI9;71+>w6?Ix6*(ZEXpFBbu zd0>Wl9jyDS1At%|CcJQZ+ArksLdm-^gtFENs2E~yQuw;_Z@lMS7D*o~#0<^V;xTww z!#^?rfDreMiPGLKiP3GoMqxrN(*mB_ReE`+QA?gIbiT#Gn`m~Z`JsI#pO2inNKaR} zpOYjK9r51hPV_Dq)z~AS6;DK9VJo8Vo?$pZ{!jJwtrq2X>Izh)ocgpU782j%_bDq2 z-@M}u#Wkd4>BhoGE``#7?SZJ~NNm$f`hNaKp5r;7Jdpb-RtLy|P4SLrUpNd*qRPJ4 z6-#t5y(uHg)|U3^oKA!lbu=offFJz)s0JVDwtxQq+FE4Tf*$JLMy$}HuY2mfU;ST(&EKkvKG&|;-dIn! zYR#7y*90!w)%_?)>x$|dhKO*=l5lBqD>gDF+Q|VaV3Flt%@cpXs-gFT>%67A|8c$2 z-!Pdc;vFUh)Cdm3uwyrLFSy~{jnTIjRMiIm708%W3K4A_?3gR@7XHU=utXj` zAMCYTB1e4cfDc zJjO79b@95kT7St^MYM2#t1=!NO0)gAF)Dz7CjrunXz&^Ii)xlg?~8}vu7PqCde2ES zQFTKOn4V|L60VO@X)qW1X<#VV8Fw#rGM4$o{`hJ4O@X9h;&(i$qAUs`Af(t59t#>Y z%ocE|wXgY%I259DhNgoK)uVL_y{sDMs|bl&uJWv}4r(06*`4;-`BD1_HzEc*cWki0 z!BF1(P}ytbf$0o#x{c)*mi-!m9dVKBYBGxgj&%>YN~G3z_X;Ewl5@JrshCE1(>nEu zf>P35a;FBF`2Z2hyO7fNQBIB{>!!nh6d=xTW#BCAjJk*a+aW# zRp;&0708l3mR0GD9PVQN+sFyJzc?oN%%ymT_GFR@>9i8^ZJR5VPdtdEcHia*G-adQ z?8xutKZy>9oI8ZaJ+eLBu8Cn;Dkw8rX{amap9$ZsEv4x6;k?CV+pUE14x ztda&z&(#s0)!5A5&T>fhY^hq(-B$!#zh5lw!G$Lbc(8>}@|i4uBlIL*K##e|zKGRJ zXaM9S6jCc2u5gM3kHX!%0+3q)QrF65APc>T+0ssfOp0NWw{Psf9~%TY<&Z}kfN8$+ zV%$+kj)?^}KUPFNKwBiT#S+m1Z$`Muc&#Fs0bqfJSP&^bY=VrwGlF<+sur@kcEO;M)5R<{E`Y# z6qLcf^O1i&k9E(inWfV0K8!BM`>@G_=*y$vnrNjG>h-VED=+U#HKpjaQD-Yi31aC4 zlbyQyzd87@VnI_hfE2}M9}`=PPO-nKd{Qwyn6=enA~(`i&h$Z;$K%81+Z~u+7b%kt zw9eGc9)!o={e(kuI|%%b?Mc>9k2&fzr_hlurc|%g(^w$EEucz2No9qrg z^=>n9+?#2X9H&uwRP3sSs(O;f;>jzAJl+qFu9>Ia@SvHswVP4ZOsuL@H-8AXe4iI~ zeoy>}uz4D5Xx?%v1K!3gkBkHG9ho*C1LgfaL_qNm%_%XKNtt@9AKjnFJ0-U^2 z3sS|N@e5`fkpvXfNih^N8n?=6nsUqg94OWV;OC!(q~H*tj=)o9dOW&%Ub!KVGY@U2 zdw`^rN^H0cDgBz25=!Zn=^q-g-hBgBft}=gi6n1`pwydI1Xd#S|JDv(35N0NzekhO zaIyg;ZHa~jGmy|?vlg79TUg1rm0M2fmY#_nBlhK0NB`$a=r#FIZ2ODwhz~bT4xWOp zkvr{z{a7uNNCKYPVRWU5{yY3V_(&;C0K)!1&+MU-9?HU|X}=nyCzI5U&$oM1M`Zr! zX0g02Ai9VH2b5Iym?vLho4zR=5M30ZgX>eN^{buuxu2aZK8#1lOmB^!n+#1j^;Nn! zf+W{OX}=Bj-EB}s6>I{(5>oaMla&_IOk+;|a}a8YVZ@if8>1N3(7WyS1G{hgC1h!U zh1m!#ucEn93^mI*uc#dK)Iv?W{euO8&$+VOb`0Nc?<=56YN&jgHs>F3O*HWQ1#jq+V5F1RbiEL4Mu zU0D?5+y0@^M}SETuI#OwZ6@yb{TpNU^e@b6Z4dpd#LuHPFfNff;Aue&N~Q+{6xb>F zb_H$j-JTVTfp~7C8MK0hf{z;j>OtbFZLN=6YaWmkZ(4Ui8PlkHAKx$$T;akfjGoyJ zzTnoXnjSo*r1Q!!@#V|g(h}Fk`6K7Eq6f>&Ubg5#n($%7{h|FO_4eDS$&9xsMkCdO zCtbGKrjuNxeC#2Z98Abs<9W*XZWVj2@`LH%vGTU6qa;`duLgs~cg#yOFT-^^{#Op)J>dBHKS!z}m!D^&32 zpFr|96wr0AMp}g(Y-Pc}K=a-MRE1dI&&s-FAT6a0U=xiOPL}tnQUX4OBj>{|=;6tC`E9^409dzLZy6`TA%7nJC`%EMb&NYKTw48Nn?GO%q}kezQy z*{eQzDDJunpw_U#kC&Y~4%oyqI9(_7%;L4^A@0ckOCi?tt&9BfuKsPC$o5@gLV+^+ zMjcH2E-NVZb)!a|n;OH62gof8#qcXB@If>DcmXOttan4R#)uu}u} z`!$|&$jGC#0xG`_W^%=*%hAPFcoyrs*N9uNuG5l$ZJAkNYklo^xZhe60QaZgsLnqU zY`}5SfWKbR-+?1mD_Ki?)>H=}V=B#eybSC)N{xJ@`vI&fsd^DPj>`70wzc+a;q!bh zg@2a>nc6@m3fJ3vKFpManNdQ{9NrbEa3iP-pxNmqHmnY4elv(01u0{UsXd{|@-e z004imvB$Xc^0fbsu+*J@pNJJ@^pHpd)8SEv3I0N z?~EzR+{GiYEdv1gb1?5*AXofAHj=nUl-JI1_ORPK$I1k9N_MzceWH{1tZWRi;_3O( z=5?aB{Ap>r-(9o1!{-hs3U{asNzV{<(-`3ri-^<^%I@d!D%UWxXu{am+A% zz~w+7h*>|KY~yNw1N}WH0igf<8|dG#Ci=KwLWgOV`#Ndj^#3=Ed_tKL-dXR_(!E*x zHNIuLJ<`|Mc795(26D%mc>f1h1THhdC^&V3ON2L@oj*G2HYww^4Y$w)-T@h~W5EVXU|2IPktz-mc!T4hUY;Ca`27 zC!xF*;ImOd#)C4lY$UPtI6>S?7H3BI?ng5=o` z7uYB`VmrFy*#T^Zx1B8R?2X~8rSp0MyvI4sW{mQCa&60(SskcvL|VsAqxYHy)ky%; z4fK>V7i_s3JkA+Y%vKlh6%e>5fnT44fo82eE5jR%m~)qjOEB^0LM`U8wN7}+d?&Ry z8v~wyJ-AkcO2;-y%=7&;`R1Cw0dedEQf$H1`s#`447Y1Cr(1Ep><$*z$^T_JOyK+v z6A^KdpFm^UVWUpd;jDdPo@;49boVy>3Tlds1uXWL$;!E{k}gCxXfZK(nm)w+GtlHN zU^^(+=yDj3Riy{V^CLKBQpi?H=r8+1%xzGqGJizdBnSk~N*AI6#0Z|*qH&bHo3-fg zJtx*BSU4|Kf%ZMU5C61(*&p+lvbrJ8R8b5JS=@Hdgc?E3BkYkaDQe<3IL7C0zyj=z zx8zBOieYz_@+0Ubg}-z~P0(pgAMQG(XCe)_XqA1$o%-|4W^m z{rx#$l!@VkA%t z7hfS{jHytbzRn)u`}{8%w|#sc4j)az?Q&EM@~U7U4bLGUgySZil=y3}XebuvrqAgH z{(L8>UYqL{WIe11H8veM=0x6|?ZtXZ0`s3|4mNzE4bZ25JQ0xpFeZF#76pdYfS#@m zXlG5%DRxd&s>Xv(0hS*{dxuF^1wXWxl6BkU-I(547ui^M}KRK}#$ z?3|_gN)V@@pOv$5o;>}1eq!}^1*F1bnalAUA+KSfI3MUmdZZs3~~SZ*V%t zP)~&0a_)>QxghN1!uHB@s5q-fVnJq01Ph`HkUD*D5Xt9&2Eldr%>vOczyw~qkWolz zcs}C06KJwjvKgZfFYxXmsvy0UR;ibxXE2`QqD+X4LO?`NQMhO!=g;@+dZ2SU_Jnz{ zcsh^IXQ(G(4rjU32YBYtD)cI72&y2X$(txXnqGyYVe({d8+wo82#RrI&-k_@8b+)? zwrMAXJ+T7N=S9CD(CeWh)fspvpa|4lVG5Xt^cO`_iouUYHd{LF2D_Q#(`NBmMZ(n# z{L#f25Ny2$LJ}KCI6Jmn74tV@#@U+v#gB!PqhR9e2|#46BZV|cOC8%XR;aptjLQ&3 z(c291#4(DJW>tS4@ddJEvg+Y4!9W2C))<$6uA|!(eE`?kBh^DbHRl$Kdt$7W1428? z<9I=;R~oo0S)sgI*4oJhPUJ1VJ%_2*0t-MIPB2#7p&It46DhRs1msRWo}AZLNT z?#Qa3l6*h6G=7W-fvD;eGAlQ=H|v=2z#s)(at5WDFE`cmS^6AnIwC-Ofk^4v5-RB+ zyOf+0Y^Kn~Bi^||r6NH-PBY6TFovS7qW}SYVeJFwU5`C)pEv#S6;VtvcKIo68dM|Q z1N`%{fCfoJ+9%U+(wi_LFVKN`t3+b{K-x4x#qQM5jLUh2bCten5UvoEX+U%= zD{>;S=wRD!frr&tZ?GJ5l2w9XHhJX>8eH`kEPujxq)YS?p=kch0R52vP@_;$23_W- z(Y^Y+0hbaQUH0 zFG*RU;ISksXg%}XkqIH_WX}fcyQ^{~5vz}gKHINkK=vvQ_B?u5XtQ8Pk{FIz*jLslFyYOOR7Thy{aLrqZYuoc z>$D*l|m(;ApqhpUDR3&VASMVOzy z-X5i91*Q>|gtgk-k#qxN&zgtJ9Tg4^c>))7>FYteom}QlP-!G=@R((sja*(D4DvWJ zB6XDDl+P!^pwZM7F;0O_xBmhD4A-n8@mw+#!G|hIW zfk0u(!^wl?!vlM_j9Uk2wC|Xjcw2%!VmFfZrgd{MQL#!}2Hbbk-AK1*tMNRR*|OYN z*+&UIR)U2umrXM5A~gDZk|9v{Zkdere{Ir$r!&JZCk(J!)iGk|POIV-jgm{sWgA!YuUf3=)2rVyMLATa`%kA;600B0Bd;muW&Heq>mxI>KR z;dUNh&(v2C5WuZ5x}E6r`wdkVm?5!|Nq;t3HX`sXApVk}o)q<$@%mUKV|71t+ zcCzAx26_wgib#mb5UT>+v1{n3xDhEsg6s#E)KJ-?589--lZP1-fnYQ->oz!s;X z^;+6hRpq*u{4B!;?C&z)ot0e_@Od|mp-#k7h1JTxd*^gyo%$f_YMo%6Lr(0#7+i~d znCMLYN{(|?Q$J7zML?M5vyp?bAb(FZEK#8Z0e_tXx%dH*y<}?7pwq#iD7_!%2Bmz& z6!;yeaRSTI6pdaBmkrYLY!Q(LYxql#zuy>VSOB_!5Z&PFG_$V;dwLHJOVD;UR=Hb2 zhZKY54}wo%cR|+2RT;X>{!luCYMm1f9W60Kh968dVPe`_D&vZQL5 zdfc%K)xXk#LBe16f+)Ii2J1tE%Xz+v2%jI529aMNhEdP$0YeZwxG|4 zSjUm}b-zqU1L&`=6Or)uPZ(=j_B@sFD6mw9K9+_Vs<>!_KgJ1|xyn>^(qM!tf@Gku zlU8ZCxJY<`KY`;CrEGp~B-Qz5`}vHa4Txyu+5o*r)EH~(`v{Y_BUkuYz;j3+U8pO! zC1&CX%3~D_CcAZgzjM@~+}b6JUl5F+`QOVOe?J&7=&5`6z5rR#GEMppAX=GDBDq_- z+&L*~d|w2@nkxbcXN2!e`G+T;GW>8Pjh;N5c^(NuI~i(a39rOyWCU2EDCcD>IgJI_ zx>)MC`u+mllT9y>q$HY4^f|y80zIOk`L4vkdA-UKFh%a~G+5DvHwM6j+w*kt|1>Eb zHu2t^@VyqB>VRhfMA4NP@8M;h5ucxvC6dU0-D$9M130W+c=0R_t1-r|2H9d-v5dL| zpSw`Xoxe0M@w+6#(D_T8+^>+@5zev5P&K$Mg&B!wt(x|v+zd2&O+Z0_;xWhwe^njy z1Wp_$w926do5O)EH?+UcT#=%a0Ay%FbeBYXr=bys4DqF(5i(rE+!iG;;B>wwJmrl` zfj@56u{gq0c|u2U&=F4c& z=@H_H*5STi(}C>iUm$}w~~y;?V2uNsXErEk)W^R$z<^p(SpMp{MH#nR$x70 zuMq(L!-oec`7>?eWTFY6!uB%eRxcbM(64W(j>5ztAB+y-OABCVvILfL8!`E+;OYHb zMOkU7nL6P|@5kQBQhz>_K_B#zH~fMUqsTqXDC8;HHMMKsUF+W-rC;ggRffum(d!&z zH_TsCjTiwm%PqOBIyzMRdCtd2|Hn`*1BAkp`vUw|J0>Zh`o*#e`tThSSR#|f#dBt% zHBoOUaMQ)SCA4ZgsWA}KJQ3Yq*^Hc4UmEYEGbDWb;Y|LBIU4W21_H79qj_4b#;^_1 zIq-WB_d1s{eWWQl)Su4sO-9&08M!OyR|@`;*fAnhuc9(G%1>leoG9S-=PdrlVxWRL zST`zYIgR1P!0X|y5S+a_75d5$z9vnV?7fj>IQ(*4d1{?0kydEe{$=8xx@z4qGAUVH6YJlyx}(4_bt)fti;A-P``Jh&L&?SYXK z8jfKRpJ(I6l$Q$?Zu>mN-$`N$KPgefoM_qz>7Q0i>dg{<`t*A=p1=5|WRx}* zBso&+Io?iQ!9wzqLQdib0ns&4bu6hYuRzTx2~M-uRD)N+Ale9E%@lOyc{5!vF%gus z;E;NP%@IT?rT`DJanatli)yg&J}N}g*cn;*M9i9J*&M+HyVL#mH)|++tf(Qx3vUUK zdm1&ZGOdo!G^TZ2!V7^hN)n&x&+%gHgERO#>g2qB?a(jv$+!YtKjyu^3^kAFhJ<2o z_q}0xrAEodC&)(crH#{)Q7B{w9oBq)NBO~>pFfQakfoV4w4z*2xyREJc*2H1s?qoI zazT)p#*L=Tsl_FW>kH*O?cys&g=%7)BKF@N%_PNg@EKr61`n`=YJr_$Ps9N|9|fRl zUbpNgt7};-wJDEe`IhoFm|%kss0*fVA3-a?PGuTh8JNP3?ND{M)JW0c4RttKz=JVB zn(UUa_xeGA=ciJfNlhx{$y`L)?ajQmsm*6!T1sbDe@b@gt>=`Z)KUL2Oa=jN$O;dTznp)|!`C#^{Nr*~`Wwr3lK}2+dvw zv4p*@aXX{^zL^ol+aK*)MO@--i)}E_k@JFknrO8dn;mQ^>^rC7_yhluf0?m!Ajuaq z=q(E<p^`rO&Emd2F?Bz7PZ@p^<6=UQD>4Y1W> z(Nizqw_`=BO5YtS-ZbSMZ|qdk(e|n0Sh(8c(WIQGoMOmv+$KVuQMOE^J0re&aXizVCP*g5cc1HbCZDaI*@n`el&aH;p0lwi$vu8X9wRSL2Mq%`W?eR^vv`hBjr zu4m-FjcdTngX9U)lS_WYimI2Mi`$o$S0qf3`A;@F2w4JL&VG_Km?qEG*@k=MS;kKOJr`hGpnWDW}|H?xQU~!<1MKVcaFV%mnLR+ zcnIa@+akkHvA(06zL@cD(PHx}P2T`9#%}yOb>=)w(<8r;=FpfxbF-OJ?#Xbs3|@9! z>QJqf07Qy=^uL#Hgp`{>xR@2+)hk8jG9(ntnkRSBlB$jDcw($%B+p&og_TPkf8N%`2eI{)bEn-8HzK~8vF9BU|v`Yyf~2?KYq(H zi$D0Pc+Dp}X@yWnTpG?w`Z*+9f^cgqm0 zW2en7bq3Bgb-Kb&bIu6dx2Z!lI1rubrjaCH4SzyOb|vkvq3JcmVv?VhEwvX{FctGK zucCI?7`dvJdp7lY#`UgD${W0iyH)&Q<93POdn0y1;!`H?{bWSqZ{2-!yh582>8yQn z2!nI6>>*t95nldq(EXhiGsMcq(69Sy+%780f=Yt#zQa#OU)n?W{EZ;cd0*JpI7I5q>n^)Ly*)ubx#e+*#iu|<6Pp9 zDU)^*2=&a}=(ho0<#|q7bLky$z>CC>QISs3c@1OR@Fgwfqx_!<@%zu8RJ$)^s93SAq(`&dC25dSiQ;z4SVxoc75#%q7Ng60wKs%VBuorga+A|7% z)RP8zlp-b0@Rqltt7#)h8H4+J8a`|MXntNf-D$Dr#4QdyXo=xu40|49uic`g`RD!j z)^Ur1jl8K=C8L@R4OhB-LMM3(nkB^xdXl0kDO;7nx}S|R)EGFsxFggozVpQ!t|hYL zV@%5r&h$UC_jFOf}a ze#2W&144ek&DAUS93%AnwZ@YNUPxDAn|5me4VU|jb=oiIgMXD^HpsGaiX5gRD!NLO zPM@S)EXI7Pz(`pTFXi0P{fu4GAvfIIdTbV^f4r2w#-B?_r@p*zT=S=VArvTq8N_Kr ztC@r=Kqle-nW^Ygk+4_fVFGpMt4`vvi$zc#p_F=DMr2C>4>n6YqgShpDs56y>xzQdo7p}-6n ze^u0=y6nqx7V*lVNq0*+;LVd%+ssnfA6KWC+{ZHJ*-twMgS>{8*R(h+dX z7fScSK&RElZ)SCNmON7CKlu)edC4=~jcGHq9`O>5mC|QMY=bWcZuvvRzH|mapkKm* zAZ1^aowf$ zcakp0pXp;VqS#8!tz=cYcW$j>X8`Yu^)K13rm@#XB;PN}uS+!T)>hen6WtISX-|=# zZr#ILbw4Oo1!x8b#sTWK!)a?>5wd(rlXdGB$}P^Xn(&hbuAmgAnbwP}3<5!YD%7^{ zg1CkDZA&^yEW{2!n50h4#_67uYpc5Fm*B_AWXaYStZ}SC*D8Nhbct^pioph-svks; zVzbJ!uiuHTO34WWq!_^9VPEX~Vu)A|Io5&E&tK&H0#JIvIG?Ex$0$;=mUF$*i?%Ar zF=qis!^R@M$n>AyX0_*zbdLtU%IRjQD~1I}saN!uGqcj%ca4Z9uE`N(rEG`s_hs>C zbZIN6nCmJ~G(#lCoCn?VU8{+?2j;X~z}u$)phO{Nv>yjp#wgdK`i8rWpw>;5FFFlC{rocrvW3M)WX14&lZ z+cAMulE><4 zQ`T2I>7-;ub7;O;VW_Uf&?KFwbT))JWZr8^@oDR!d5#m^)~WG%lhA}4 z`?kcqe>dR=5}HD9qEXv@y@$ikJfpo*5UXhuQ60ze|TK^f@`z5kWzfO|k zz4vUv_cg9Y*K`N;Lf(1|J)kF_^Ikq(-mYG(NH?4HU*P+2*<|(+e%8FR^*Ij)m){@S z?)#PRqfYPfGjSM8?GlkTdpaiL)|TYBnCmx6N_hA%Z=2dGz_im4biJl=O0s-t|%Mp5&|-2>;x%&iD-p=xS%Z>q#(- zOkyBP^18-(*~3wWxi0OpdK*q`xi&D_Z_{!lvy-(G?%mfpPkf2Jb%_A|_T)`sK65cb zT;d)l{&qRKvaaE}nv!#s){DJ3xte(2zBKO-J{+QO_}x~JAp3eJbiC(esVxtRMF?Uy zQ@AJRI)`{vwV1j&t=b9R?^P?Mo<)Q_&N9CuV;nG0wA`D1B+UkLGVQO7vA{v z)Oq>W)pAZwjt;<&Z(#fQe9pA9Zg%P8gO8to*P5*#T)Z>e{WLct4cf(?Phf19e|(GQ zRQGBKyf-vIKj(P~dY3-A_o%&o*D}Sc)ob_n_)O-6w@h9{ZjbnpX8jwX-+sR}?1#tW zNhU5~+j#SGXS2-7xu+{s?|>$+L(;9G=QAYd`PGc&*WWJd+bceL)ElSP!+ z3#hmvPMUwv@BY?~@lr5bKU(45kEZG|A$`^m9zM?f$S^1qDBJ+D0Wc9h} z624LE&S2{%^V0W6lYBK5>X1fHW@)F)`N804o#D-wNcQNQpC{OFTde!l^kZuq+60c} zlz8UJi<9Q_-o)Os4#i(hzpG;GnI%>a@FKih>Pwi2o)3eXtmy-X_U$qsZr+{G$NBi= zDa35Cx7R^5q)?kP7E&QqA1~7#>ZlHWNxDq@;r9c?{CS70kkmk-HrvK4_FA7f5m6oa zB!%w=W5K(TxTJ=#ym8_EdPvAr(XZ(kaAHd@E~9Aqlb?;rQ`@=hMb!vXr|VC$Vy@S( zxyKBi$Q@uc6a_rC+5IEia=FjEEfR?THO=qEdAQfU-|9ZO%*n^Sy-Mo`w0kp57O;61 z*PQ^<4sgIPW-Ug@J6p)mvSGQnq~4E5ES$jM0|G$xU7(7$ zN&grRqSveO)W1dIBmVb|E^thzL)e{Jl8(3OU1tn;=zfVymXFL#1*0qK`|r z)JPrbn8KP7I@}7yU9X?+EYg&{!E;05+L5sHPmZF;52?3@*WNB|Rsv}$cXHKbTz@Rts577R7vxUwK#&OG zZu(kL@j_&qy6nvd{l7rg3GZ_^g&{d%hUzp)Cei!awwZrXe%Zq7qZ6KzB47Uu4leE4 zt{Z2!-9T2iH1mrui$weG4ERv_Yr4dzcg<6m3EaO#qo4)7QlrKnhEXTl!Gy8~MT(G3 z>hwhc>7=wp)`{OOnJ^7!w*GKW$cd;He8PwZTuyn7f0112F{leMACA(J1qS zTUmia@5LkVpnFe;;7(5#_JUM42JYqlM#5)F$GVrh9bzvB@iPZ-Rd7s2CD2(Y1S#}I z+4mvnqlhSqmhNyVheeIMgyU0uf5F{pTvY4s9;*)vGhVHvfmz8Gz*%j)HxvQ87s4rE zOD(1M%}Fx|vz|;OQnKp?vPn9gv$U4z(`dbN(hs&Xb2dJE(}i|MipzL7S9o=p;6Ha*=r3E;3sR3*-T}~6h&kBl98sD-k?3RV%x00Dm) z8g68wI7U(K19dR&r%MrcFTMa05ffnAHG32{`EnlSinu+X@a;e3}#HTMIz8 zy}Q9k_-~E1EdA17_%CBwk%wtw z>21(#T@=t45AvHFYcBA%DS@i--g~t^IW7{l)@6mSS;!iqAPFu+Ea?{ErA?YIMJHN{ zg0G|_xX>V8zVX}Jw2Q^6%V*@+j+GI{rK<*S?*8=+p-yA7os1R61D4s3ILy}1Ef^1V z-Owb1mVUivsH7TET)vujmO2#?e}&=o#-sEbZa}*2pN#O&raB(+pJauD zeUJ2DB1Eg~Y5CP!N_dnztjb19XI^{#Is*m&PiOY|ZbgvXOlc{r6SCza#G`3Db#j9l zFDdjaY$#~Ji;DYEr_)1M>^1BiJ%+}Z3+f0K)d{^ldJ-C*&Fjj@<=wD*n#=xo6iP9_ z%gNy`-;l3>Lq5u z9G)N;!ew*A1Q_@h`SsMQyhNga&5InD<5^Mpg}64F4}b*yJBsHyr16pQkaBo)ymb3G zsyilLg7%biR%F`1n!8SEF6PS@Y6RtH1jyaN;%Kc%&vI~-^Nq;h zJo(M=a4vTX`^LV3lUtI_eu*663s^cS!OzCHksjFs(D;x6HO|b9zoCdlk1CChQav{2 zxJ)+CmhNY;CofeI*lzZ=dPPI4)JS$=0{FMm?(=>6m#-2_0fbafv4O=gN($N^s;;*?@kwPeakd?(T4e#4iZ1=b%zNOO8m6t z&)c^ZeiL}2+Vfx5(3pFLY}F44tGM#P-*;X%ErknlaBKg26HnoOsrMP%@?m(&rU^{D zLpoyPE)$x*gWM;z{8JxU;@IjupHVrBB)_EDrB2%_&=!R@u3&hl#V2+^+o&J3xLF*; zZ(pLxO*FQ#KOA@`yOX@d5G{x-oza#tKcfpYN6OA(f07ewVUiuSWKLO*|AeuyeK|jD z|CVune}?Dl35m$VFa)?-?&n~xAMg@ArUo?Ja4+T^skEP7~yTyPs z1WOmv*Brcu?$&>{avU!uBqfcGv^v4xYz&6?D*4{iTaU(&??#W_EU`4>#6ZTt4t0E;sNgQIlwx}z z<5}|T4S^whQ$3ofq&(r-iJ10h&)a+xAM8FQWNbdcD$8!XX2?Zerf$C~Ha{O8kwg(5 z?v%kOpS$b`pk)H;hC;reEj58GtD?hV%_G}m)&bc zK)R2;FZjw8agKHzp-n^F7N#TJ!FS{pxvU5=sFK}2Cq@r!AI2OD3mB$SW5ddTAct4 zvXHTsB|+0OYiFF+mN15nh~ec4lg*#_Cq|{_Bg;tw;^yv(ZG86>a~9z@TSpRB#Zz=p zTfcz*Sx-H8?;Tf52AngV-fZ`YhH)eX1;rt30Xla|npuLK7(SQ1H$TC^WI|D+{zkf` zZz4GIw*vWiPZMGjYoVeYk+B`~o+NM)?#~Y4M{yr(mTp2vBeL#hjIuz$5R#-){l=1i zB7kz(E7X>&ij5L`PKDJO%?Nj>tLkNlMf8bR%%0=s&neu@ z*#VsK7btGxCRw6&#F!A$gM*Ye@tyZm^ z;H@2ZBf5?9Y~QFS0%d7 z@S%`m%%u`^t&ebyRrE)P!~6!AKFW2f4B~_Mjqe7|5oc!Y#)+3 z4N8p^Gs@MY>21iETy|#B(RXu{)Rt%^F_q*Xsg|e*^pnMLJ~}B@QYi4tv?~R=Rdnj( z59>mib{=&2<0Fd@k*1m`@f920FKiAs1V_^b4RlZ3wMHKwCije*1wq5ed=aQJ2?{(Ne9e3uNHNW}Toe#KTzJ@V+zEQxC4j8D-XrL3< z1?=TtpD|$!y_3_wOmrRg@CXSG4xYWTv_1FTZ=0+JPn+$>S$hY+ThRG>BaWT(Cahb-R7UM9WUwfFKw?*cdxf(UkB|j_XS1#UJcK!I6%@*(dANRsalMmxjkgFcy-Vl}b@K6rIoo@o zzIi*i6N&%?0jN7r1Sll&j}Z7*Xeo^R0=E7~Ec#b0BSQ!P2!Ne^ydS|FoqYgeC@qx8 zDByuJKtSK#)ftu2adv{(D|!0^ECrDY;*!DuF(F}VR1OH{{ow!1Q1WzkcKSbaj9?J2 z|1(419_9@71&IG+1IQcdixl_(P>lc+%E|p>y#z9iYUz#jH>Rp0l~D#6K63Cy+l~?o zp(IN7KF+9IfPlKQC*0W=;%JW&t3VySogh$GfPg6kstEOg{3G~}icqH9RP>)7@gWod zc|SrvP>4`K3*zJhutd2N46p|L+eFEKl|;Tz1XP6pC?9~46(XMn^L8|J_61l9=qsxN1T?&m&sO?- z2O;Zr_V@iy%lu)^E`)*rAwfdHe|-RAqM{?n8eD?~g1fuBySqzpcL+{!O>lSTa&pdl*Z1SD@7Ju= zJzcfCYFG8ln%NXeViF9@jBKzJ6_r)hu*}3jVmo6iSUx^jCM5?uQ)d%12V!brdn1#t zX2cSTO2isw4vv;~--uZl*%*NgstUqNs#1z-Jj9=7#OzF*ZOy(pNjezWf3-AmWD%o* zWfFBTGjjS|AZFxbMocZn!vbXHW@ce#WoBVxW#Og+GE)J8R5Y*x0QVo~ko*p_x{?71j+dj9UkeZi};`S9ZS#vQqNVuRR+KWalqM=i_;p1j}@sScmA5CH*r{e}HuYyoW z6dMu6#{lPcI%H`3TqX_m=r;Uo;w6$Vbk`75zu_6MSE+&VOq%5da@L+j!WLAHauIOg zL`gdkRh;zU?XsLft9RD;m@R%37lD8={8e#T??S{ESX!CLsUlISGfm4Zn^YF^wFpY#Kc*11ApkU z+yDAkY#&TX&*8u4fTMQ``JzbCQ1g?loQdVF#ObtG|rVHB3uhV2GKA^m`N`R=o(SOY zlmHQQ%p?~>L^JO21rvhMk!&sOBcj9sKeUcg8~A406++vsO#ho-b^X%o6-KaAIu;hK zp5kH)o3cMW&`vqWalhjjNtblw#_1W<_YK5%+HQtdF8V4C6m%wM52*@mZIg{plSK`k zEBjk3<703Tx8WfelvY&BOqm9L(YGu<&Qby_LkgrJ;>vm^oynRW>3~S{^*0S$pt`=A zVNb_d?-Z#BeNxp~qz(^Iq> zi=M2Sys@ytss&32HOK7B!;|jFp8d^_&ObMp^=4TDvA-_(2=upx9Y+nZk*MrPZPGyY z;SQ)wzbtqieJk;%fQNrRfqK=cJ0~9Hdvxbn;y$MfBH0y?xm%AFs46IucU#+ZdIupR z?5Pd>F6J_G0v0I{%#4U@5p}S5R{wL96nDZDDUs_s>7?@j6Qgj5CS%)c#5ZDdY zxRf*}MM^IhXIASgN+OLEx$QWGw!liFlV9gz%OB!L*2~_SCuzy;I@fD>H9emH3>E%0 z0JVS;!9lZ!W&5`#-9`6Sr~y**c~2R=Ekao@G_30`}!8B21+MxwJbfOgUK75dkeX8$D%KM-gvv<$>THUv_P6w1?UWAO^F zXcaua{xmcd&iiOZgQTm3k%`J+Th@M;;jtO|`c)X@9`Qm#TSvB+NMQY|75CJ8L*LS_ zdtK=cP87qu!V!=!uz9G-7!~3osqIgMi!I5|`y~@$GW|LZ+Q7&$5%F^t9F2wA6k;sS z(DUwwA4-T?WAe&~kYR^XFUR;($vZ(VcB*Tfjm7=boIOu$VcU)_#S9;PJ{5hmf!684 zPyHe$tM7D?3M;;606+hIx?2Azd2>za!o|C=E2PD|CbE1@q#m!CQa40t{0JYV-i*AY z7D|K&{kO1&uDu_Wd%Ozb+FRex$6sSk=Ry>|yRpT{kQZ{Rt1M8a1u*$&>K*e6$wZ&S zvpm;EZO@UR1rt3mBPEvae)w|qlC853R1`r7WNy*ck64^k=FoA|juSs$VL_I?8biE; zPE2Gek2BP`nDmRQR3Rdfw+Pb672K|e@iwN;-;gkID0>JC%`ro3I#IN=AC2hxn9nuKj>6W6f(-^6FrX*?)GB+l~6p@EImq=aSr6FR_ka0+c zfESTX6qSC15-o+M-FXdna-&H2cE1#;$Ww1C&d=OPbYSzNXeKed4zUbiIrBg@-cqBa z#;q>mlw^lcG_`XhL3UwLrTCCJOkaqc0+f8^dS*p~wNV+Oh8&9FtU#uKXonPlc22|M z{&7a2lI)FOc%_YQCRvuIqrxmp4}dDn4%frJoWa)S0@zo`3l%jdQ9BP#X->-EO> z!^q&{YM|>~@CR${$6n|Z$jL+>ZW5}YJ*~4G-l3}902XR`; z%aiw|2ZAz1g9~C~G9zE76GDk~f2jGb%3_R$kqeKN25>@;Wsh;B4lO~J!IEe%>23q} z#Z;u~TyBYlV4c8d*DYja`q}C_P5VJpi2Nb=f@DyWLCDD)Vbl9Sob13S;UKY5;MuxE zN0T5WrC=drs7Xd2!F2D!hW7YqfX=|3`nLqC&F#~@K;ph!rZIFn@(eUUT9TZ~P&>U} zcw7|uwQd-;huLB)I#bxyBVE5ZH3$v$D~+5ibrux3jxjlfi5up7R-9iDd`Vz1lN}e8 zC{t`w7&O!>Xk`q#9f`$7a6Mrk5f)z(xb#d6VgZVT+c26vGqPJE_^b!91a-=oeHx2T zxVyd>8Oa1OkTML-Pdd2>oqQjyD$#-h&mMuCnuZH3fsLG|aWxJ<30qoV0L(-g8YTkP zxPSZ4m#}tZ1w5RNKt4k!?Q^+lxRx-N7x>;MB{iXK!@iVw0M9H()^bio=LU z51Agd7pf;{CN<`W(V)FhYiHBwJ?DE_D2HqRmokDq8_3oaN%3{GrnfPRp&GdlgwY1m&K zuyKIH^PXl;>&?nDp2M!lrrms(_+&Pg^B5t2toVA#5?CUY9<$=0Sws5(%^+kpl#lcm ztTXubu|n5HAQRgPf$8x_P{h@peztP7VCVf`0@aah&-=uA4tNVOeXgq(A^#D!` z#Bz<77fNQ}^nYmP!_zwRb@w-<`kyskvpUIh1MA?dCWPKZ*e@+$)mi1VZP4AoKzX#O zFWpGH72t(nLc)|}hT#K;#rTcK9wTgs{3-o6DIkWYZ+d2yPZch zTB_iL;K?6TU@q-(NqLR=Jk5Sv;1{WaRgw4%&&$|z!$HL8!Ru=Jqf^G1e31@jRNQyC zsvTWbAA(!98g7izB55=QcL7&OoWe!HP8!NMVg;M`qoV&R<>Zp! z6>KRk<@ZxPz}tb4Ng+${4Im1&-h*ls`J|(~72eMGBo|Myq%AW9#qB*BChrLG=?%Km1Mp6={54EGiF zr4z`xT%c(_FYTW~3Fy_4fvDi_YT*5VMe8Y$Ux(|DtL4OigSlP=s$M~W-sgf-H1BX# zQH^#Yp(RnPN@ruED^4uVK=7m!Sf9xie43zAK&5Ab`EZp;GTB5o3y` zRw=bFMDosF-aw_;OTuDqfD$8*hgYL2O!_A%@}(>r!HV#pM6qwhBgpV6Bk|8_0;uzu z(7&d1`vlGW(kMU301V}x)UP^b2kic2*WGAq5w0Jp2+cTc2brEKr?TR@3sq|W=FfA^ zb8vvPoLdu{*WZx?R_ufUS-r)M2mQ3*QHQRF2U~0{laX2@A}piVF-PfK4JX6L&cdLr zxhQgMg@68Dz9kG>dR}VDX9I?(r06KDx^@OFb>76>G`;Z%U5-bY_td0Cykb6;CQ;IN zVXh#x0X`>x*n&b%=8`zEBi>qww~#A%xZSr*nm|03tDz;uHVdioEG}5G_APGQa{1`Z zDUyl&JJdFjf0CjgXpt8Wic?d&E2s*O9#Xr-1{KQOPVG$Ti4Qz=JvTRF{BMN|NvU1j zS(4(HWpBzj5yvv(11#^K=aw+iP4LD`scsb=p7)73e&_A%4=xW!L1LlPvkaJ}kC))S zEK3*PNcAkAV=2OFOcVk^LAxkWB=-O~7&s<>df*?Do1<2Ldy>*=Oecg5FsQ{Miww z0&mcT3W{rA_VfD~;z*sVd~%TS0cpOYJif-F#Q<>6bk(eM&2-mEEy59?LJF%|KrR&A zv$T>E7^?GXUnk?n_`B&VD*QQo_&B35eB-%g4yYuCzAf!!>hyLX5y?x^XebW7~N8eKiH%eLHh#BmL&b+0qvpr%$^Qsx?Mk;u%TTn zbgpKw9?2pRe_4S+M!+(j=B$?K;v;zEIkf6qlS_v8D^J%SrKm=7|0D&`mdvzl&OzB`B{p<3KKOVr zV#3LyMu&B%Gza_42O?##^K$XAN5o<+GP@3c%%1oQtZZlaC%QN!&Ci)y5KQ6U%*|7x+1NE)Q1&ok`g1P)wX^*UswcTUF_buu%9Hz7YE z_XR)OBcEaq=@BY-)4GhhH*6o7WK^YKK}W6T8C(HIXz|6ENr1UVO=X)7Za<3coMO)m zfEw-=G|L>5`Mk@Vzf? z?fYbAzY*A|sh6n0=ni>nFk@i*U!hBp!K*FG*5kesL zEAtQp9N3H5S&iRtCpJAgE9N@M;1+J8W!($V0^5c)%LMYL`ZpA?F}RuGDuUt33T`fH zm?75LgLKr;F+dK*JSRC6{|0v1Le^`RGI+=#d|I41MUlQ>;IIVGO+}74L|MTG0={EC(Ee7Cxh#c>5cP+l;3={m zqk`4slZOV!*M-QcIA&!z)GVnq^qs9Vz5BV!6l|4FCyCX@To^(Xd$3;S@H6d4D3>&Q z_oK;Hi&~5Yf44;*Jq1()&5E)G=8^Msu0EZRREDDm5~hnbB1oPdkNCy3$%j+5pcqCC z`dckfVwiiJ2*qn?lf~Y7VUw+h_@W~%tIOM(ZA-QIQLP+eh#C-GfHIb-^gv@NWv>#h z^l6kC^2I2tRNkM`k=5{n7;(#A-vrswbvtbYf&_C1dk8Ao^zjLQXsD<0rnpE2P@o^2 z6`u$zh2kx-P%hKnm|%>}D+W=pmT=#iT!lA*{X|~_JFGVk7J{*coDF@_Jtjr)$;mgk z%b+#gY?i?_-Kh9(Vib)-mPY1gc=j;tfM2-|L}5HtZ>^6QiD))k-qvCMPXEqrIUgOx ztnWC5>=RWuzWKzWftwx@Kq)f?e)wEuaSgH~2M4RBp7{RF)S}Yb4nH!#3a633XG|eg zX$TY+wYh75yt1@L2K);hLM+6W=|2!7gUyiO>icHXWGQ+Wy$VA{!*%foIz@`?*t=^Jh8b+SRf%2KFjzW8&L-xWkYEg#>8@iS+;yfX6so1Y{E5DodbDg&-}k9YUtHTmS5(~Q zdb?~Elgy+U!_vx)n{rWC3`;+}IBgvr{|&8cWZbV0CTXCj<+X|imlo&N?<8E<{7>vi zz!BCLc18LF);D%ma0Q8J->Ik|rdc$@Mvy}}e4ILM`=M;^I_+(WEa^HN>dVzw`sFC5 zM>Ku}j)8_GRwRyr^tTa7QX759D%kV%I`=y@*OLByam}}MxJ)cM{2($Mj@qjX4-T6p zc=p_*I_>-!QLbyFMA86M9#-Q-FcXKmgF(t6C|d{0AV99KuX^LXlopK@J=lN;uCD z8v47s(hKmP0x0d-9dvP(ZWgM$^QP-Yg@m#1MW(jwiYVc0N?I z#N7G05YH014#@8lat<$uYAyrnrerqo)8zM#Io?dw$Nsvxf7#azF?JuPv@^ zV6)TAP46dRrqz0f*i4LDX;UxJOPHreUvVUq_77vihjWB714PVmJz;GlDAKJ?xtnOf z&1&kYW=lqs$A)vnGr{!D@jOXwBNBJIv(uYsI?ZVtO6Q!EetMZG7R%@JvBvPHbC`jo zIh?MrWpf&i*IUe&*aVvJm@1aabHnbFc?#H$+W<*c(5zHNf^f!ilr!h3<)rVER+GHr ztA59;W+rgR$=(;OCY>1RH&`r|prhE#rEAW+Q|!}w8rzObFk7#%TC1W)T2AEXWI7m3 zez{*?O=21LaVpny@a5#^&9k)ze!a7QVp>m07=KnJd;Seg5Hg_&&rAeXMk^_A~`&H&DaY_A` z8qRjb5v?69wSBX*I`=P5<2=#A$rB7B7MCn&EkH;QV?QOSIs{2bej>25lL ztBAFICRuzhfhz0Rza4aH%r*}@pPi3dsP@(YX(v;HQ{Y6k@;`YOML^$ZF1srBAYi9= z4lN3}S05{`*N8peRg3&~{H7M^Y=xt4t;?A~JC)a=nkP8hvQf@+Z?bUi>PRvf&^en9%GgRnGiGFAuLeJ*oL!%rM^*CekVxM9alCSF z<7FHt)8joEiPIKCse7wwK`6!h zXO~LdFHOv1Pp`T6iSYIPod{-8%=;U3CN?Z~9ylf$?zNNHaPqu1!^l>fsjOo9H{WuY z4Kq1Gqy0BKoxj2(mm)}-=yIQ_;10}MTFhe)DXirWZ);xUt1vfix)qDqc4=C}&)mH; zVl17=8`0wBxh6z&gLgg2nGxQ`uqW3lb*!tUh+aggj-fPXDio{TBJw4N&#v98fk|H6 zsk#$&2`d#xE|l~$j}$$SR7@sqc9fy&c=QyG2Oh~M(0Z4+YE)EZZpM@+I9tJ$%3K}U z=F+m3Jw#Ll6>J(-%*9!$R>e9(T3T=2mjvR+K5fCV7@VG@`hj8DaU~C*XsXR(I9~f)<@?Bu)*bcDNhx&h@EzJYDf(L__H>W(6!!BB{^CHs!m4sM(X&%dy@4suoP`Z* zIwBZuhHA-tU`R~L(O`Z(k~vSwSDV~)L{8j{ZzX8)!y4H~*v0h&7Cc^-Ht-oSHn^+d zC5}16ltoAOW%aI>JStW;?iq*$xV*(BdzHhGl}9t5UnZ@2XsvAyG7y(>J9k@f)u(RFxC(fWH7eHI&8(+sCi*qb5Qe8RBY5Tk*&{d}uADQDmKJ34kH8}J1202R zcde*zUvKav@2FgQGgYpevF@CTX$dL)wFHaQPQ6`39`^BsY*O1aP;E>Y5GBvf-P4hZG8o zRhzxEc59n%?I`V9ZE;XjVU@?Gx>qdNoAj49zBUXP=g{#;KJ^t&W?^x4yV`Z;q zhJ0tU!Y*Ury|Fvu5JBt*k;nmguC$)Ax=5G0cNs(pu0KodJXW?qf=W+hgD|C?F@n3~=HDVK1Up^KPn4`;WAbr@4CsBnb(pEtZT;dZ5rX}@Y;$Vg zq-?AR0N`txIT!q?C%*#jkSd>S?rWC{&Y8cUZSOU7r8UOw{r+W)S4#7vZ${zLLC}JT zk2BC-p}R4OpwavO49MR0!uoVy*R|40F=p*8dx8w_(8H~GwdyA8k$`v^eaAv4>D++T zS$9XIxcBZ{1;rHm{!HSX_ZuyhjeJ319I->sW#IYXXXk=Xh2YDHq%RLO#vx;y*c%p7 za!Gxs%gQO);q)10=SW(@^g49U*l1gR?8X3<$PXhjvpqN3z7$u5peDsjuiw)sxk&D_ z?8Zh<$0Y0=l(--8PlIQw9Ldl#xW+X_ zS$VA6zd3l`bJQYQuQCs|C;rvcQ_R?WP-mGdwnSL=((VoN=p~$g)4bs`MxB&yIJ-^%Si> zXWqG1&}vY-qiu}DLJp;^DQl}a+T_w{|1!}JN4*wFV^PTo_Y6pEF-L(~y=KW)!O%XF z{sSfM^&PW^gISjj$76hbGx*luGwJqt57SgD&ezg~$|eL$nrl;U^&GK=Ls$|wZWZz+ zYZ(Q(@|2mUvGIucMB`oNKQcISVojM|`d)U*1<`#TDySFg)~p4wf#+6LJ|8}ZAfp`!51IV8 z$D?8^qqovlZ{?`5>%!NrvB}G*4+vf^b#=oo5KM(|eU~8-Tyo?k=S5=PVi7-w!6QO zvsWG8;zQnltsd7ZsU$P$PlHZd7;SK!afNIAe-l=Jq!h_UPOeGOH-l98V~Y%gyr)&) z7>KYG?6%pi@;XP!+}*)tjZYLAC_OvupY?g}9=vq9y8Klq$b48kefNGpTRdu{Bn#&V z^~62rNObjnBH`7N=gaNUu!g;$yzP7p4pqN-j|yIFt^4nM8dr@@H1c)rHArrSELJ)_ zF82^rboT#ybXmEf`byQe@S3}0NZ9j1d%OQH33i5yIGY~kRS2ix4yWMb=^e&<$CW-v zm8t(E4^Y{T=Y|2&9lI!-rK{BysNOYU{71d#4D>Z67OvFQzM_3ev-}wH-v~l#IMZFq zXnNySXkxd;c>v1WG2D_XyQ3HWW-L&x8SU$0X;vs zuKL-wOyB6Y$T32Zf+xL3^YNNe*WlmytDp6r)J0r~-ogGo-<*%3^bgcO9sLK=ig$*m z=J@4*XXGM(-wAl$=iR8EB(pPAKWow&sqn%p$9nu>?*S-Py?ExSI9`+bYnxYV@vZm7 zH2K2hf4I&XwWuoBdyoG;f{zzEx??n67}aY3rB*eaGabpAj@urV@zRt>qKWhbz>O1N z|4)!P>yE8f9AMQM?_e+MvMT$qdy z5Rz6W*CP}cmlO0aKhPdDQ?fL3$2(yE+r;8y(-W>+CB601@HYW0lS)0DMb7%aB;l;f zkXg3b&Cb!Tsoudj;DEr>c>3V~U)WdG0EG)$DwnpgX272Oox3}-b zM)LIR!2D7z_NdKW3)}0d^jr4!^NmqV9Qkul!*<|CpOKTcmKuS>Nhjo*qREf z7yTZmfdg$hef2Y;3e)BHom)tS>KpUO#f8(aO){G{!1CQ5xU!4#1-O4(gPS@Yf$u?- z^_suRJxY-?P-JO0KKU%EX?BNdM~;y zHeS858VK8ZP}~3P@RLK%fLgi5)_4#9Pu_FdS9tnsRv*9ok3#C6{u~GIe;{?<;R&*o$f69?S^M5#?Dk}yYvca4H|2AzvrAOirkItXZ z0{r)}Gy7hv3Q*aN@IPGo4cmF}B2o@N6V_PlzBHL%)Hgl8`Y#R(#iVF%7L6P5eg2vp zq#Z3eFo1OD{)D~)^tpMZDpxS~5Wo>U_5q~QB|Z`8zS~khO%N7paV9#@Dy?2d@GpVi zy0-iYN9|xqACZmX&+kr20K>8zdo;geG|CrHGS;NLaSKNY>-z;QuHsf`vEdNLK3Mp2 zs{GG_Qd#<^rsQMe(eUbO_HPtP_=WY;Xv@iMe0usEB+ZmXHYA^t?f!&19{jY_*-6hN7%YlU z04D?KNI$fwOLXX@n?5oB2cr4&(Squ8Nh1_?z6IN+`Asi`izSO$UhGG7r}vze7Hx>*oHrgLSZd#)-bKUZm^@ZQTf*38F93 zmD~MBi0sqUC)k_U36QX0i<*+K?fC_zQ#1;fzk85I?28PJH9Lb-NL~YxPMtu5a4}+3 zOig9wHql5=-c6My>Bnm6_IT-48~Gc)_S1*U-lsWJLMCQC9bY%{f346i2=J|Z{|9nf z%?tlpeGf}&>4Y`y3qS8aqo3Zbg55k?_QwBNrY_;(aq4CE_ugtjKFki_-+QYCd4GNX z>$>8Fzcc-ITsMcYw*1o@;tSnB=~1H^9KbuRo&0ljJ!jTa>S}F}J~>ZOLU%I#?Y-+? zck==rUGM)wyYqB=xJVx3(>JcDd%r#3`fI|e_VlCS@7M(t4K??#o!o`bMy4<<__Jv=BM+2K(yBc3 zdKu;SuTUEaK`C{OzdRZt(HWxHEa~QA^ZrGKDZ0YKSDs+&?v8hA-arEcN76O^YiLDe zh{)K~98V+f2Lpy(7Q3RZ(O)X#SaVJz$-*-3H;8{>CFGk`?EHtvQJR-Yy1Eg3&(s=( z!*=w9d_bq}e|8&5>Cp&cw8Ie2$kn)bYAeSmsA!n_PetJ9e@DPB>7_i-na8YX9$KYx zQP4}DyrD=r-PhuhajJngOizfU;d6-o9G$1wj{+bk9-_1qcl@9rYJ|J@&)F>=O=g>wq$xT2cYs={&^46$OS)#7!tgbGN;LZaFxZR%-!K%pQ7aIM zYOh5_#d%l&xbc?`*f!T1x-=^k!%X$Nkwc|a&*4}l*G`sWFcV8Fr+|gd8z88S-95XY zlKx-t?juEO^=D+*9pXZB8aF~{e|@Iayz;MA|D}{H)_YFQ$q$zF16doJ5I2vSPfF!5 zGOIs%x@~)zee(8~nvSmrzKhX6oTFV7;9LBUl&}1}=pFyWO*VBYmoWTu?|T#_vdysy zpTU{f`%^sbqj<60{nsviwO|+E@gKYOKX?_t>>?H?05 zB!ru$zJDoBOU~bA@$wgsp02M8+~wbTQT_h5B7gt6Ij3-Uy3+hM*n^608$X;d8gIl|q_;i2-roW?Lz)5dzbBxW2|vXh0OZhGTR0?^*Gs(JLTtS{ zk8=9@Rw6yOU*+I#g)svpn)OW_f<;%+ssaYk<30&!Nlha0fa5^k67!B9? z8({R=OK?_3{^}94pl#0^@GBUs_LjA{%MN=;=w;>Wa0$WgJf7$=>pt~!RTy2*UP2PG z_lmo)4iu$j$-=PkM4|t-J3%3^JcY7S5na=U!TS_2_3d}iOpppI)CJxU#C*{x^Rk0O z*RH#-LGa5jciHa;|34xRim!|Rh&-Hjj+*k-+=*^g7|cglHERD*^Kf`ycYy6Y`RUyU zDc;Ty2go177}P1aLV$su-waiJehxr%M?Q(G#&`-acTi{}S#=;as8JD5U%Ho?Kn~@m z9D)cy8ovZv!b=g`D8>^xduB(3`_h~6(C2T8cveu{tsLqNfl)kUK1Wh?PZyulg9U~@ z17yj}nx$U{5 zrnvI2$|G=AY`g_&-vF)LCMgk^s_M600p;i;YIPm%y-zsz`I{tfbZF{%KN4B6B;-X! zW+C<_r_%c~^Xzia_RlTY)A?(}NUeFUh^)G**LMbMXc}b)L>Efpg)N$zQ_A~VB3pU4 z`5p{%Ycd(c$OW8$9?K7hfM^$zP!76hBxfxsCDJRmEvXk8wjT%>9yJUN^WcGCLj;cN zG)hX%_&q}d){}ja-+*g&*=!7qn*ikpoR5qIc0XVL^xTJ?Lmag*I+nukMRH+*=C(3B z7u2litzezSflj2e(LpF-MqcT|`J|TEA|qhI6e}?K1)jz>H?zb+-z^!}so+I6aP6L5 z6`=dIga!LTc%p@L*r1ZcIX^`f{;sCGa!)W3j-9RrV$uBAG_O=oZ|;(WIRm7vTQfiK zXk>u)V3sbsTc~XNKA=%AaRbM}bUko<*#jTHVrgNE!oLxNNQM_EfW1rA%->r)9#1Ln zWI3Fl!*@r_aMcgP6Lp%q<*-=;Z{nt6a6CN-kK49z#qO~XlIp%2?mCledCJ5B3QE1e zDcxDS+k|)34UxY?shBIr)FfIfl^h74n#E++I#0F150c~z0GB8!P?&WwI$rvEOXKs2 zWJWlrV{s>uv(5TbjUT|JL&KN71CDuph|3IM1}1KMd!a}6l4Bt@55W5C!nmF`rio9C zsfy-L1}72@-?Ik|$=R0zw|VJl&<@SwYbdFitx)^%TVGgTlYd*;8v7%qZglsfCWWDi z!SrQy7gB5wF+sTM;2gle zG;ti{#w{Qd^pE5K+@}6n97U&%rXa)H9Wfq@y8QA+zeJLZMxW>@OV4sbFc(e-fg=`f zgN1Nx#wA+$fOFe-HL!k<2{_0v&KxtQI^1zNtnF7nc1mlR#+I{}`~rsagWN7+gKbe> zqSY6Wu>3Sm+=HZn@`^2KiP}33dd?JCXo+t7V5#debBjRcO>4qevyUj^>^W1tEFPJD zYJ`muS`Kwgm_-{81PW@zB~LBG>B)L;ovgWcfu^e)9;9Q0+0DAO=wRXLdhi406DUExLY_gJVX~R))$CJtQA9L zg64H^O_sURQdXS&KE%yLK2~J9+)$Ayo!|?0pvuVeQG}B3MtOCMl5ymPDQ(eIWT2Th zFeQA*%^qHg1bQfj{{s^{_SRyb}3Yx2K)uyf+W{O&{1vhv6e3XVa5r z%T)95{CGa41l|vv%uxtUqYzdUyqZ%!+I#!@xyNkxcSM5g%BB8HE%g&bx^$qBr6Q%I z$f8MK;PrKbz`c=0Cm-D>jV6??De76k9~MNsh9yZr!Q7zG4KPu`Wc{>^o5$@_5PsHp zSNaWaS|lJNKy0#D(n|YV%D(=HyPQvNupH>EtBa8#6K=9cM?-q2DmT>Y|MjU}fd9X$ zgk~fAH;H4)Ck^vegilezC8!;$A1Z1VH})lI5g4>*%lB>Xe?$qJJ{9O?U26VOQm9E@ zw3s)<;a`KD&Ag5qmRCX4Ns2~K$?%7>q+rAMk#2}#mN*9xq{Q{pfJjwL>CBnF_}nv6 z3t-6ca+O*VfJ?U@C&;1=D6>K)ULl%Bd73P~l}+|tkT@hK`zRAoDND@rIEI6TuWBh} zIM?vk0{WZdCCns7<)AFkXROi~bd4a?BCwM){qK@FP~)&tGy-tJD<)B(*HpoR!R{~+ zIQQCSL=hLWDVRjqJl_CYU$Me3PyAsKnoJfi{NIMO~e$hopaK- zJR*W1vMebZ?*Za%{&?^m4?_uRlnc?pFHaO4`J{v-bkf(@L}HWKK;mLzWdn3nHH~~2 z4mY9&bX`zmb*Yr}*57%f*b@Ooqt`;wRmBNGKj6GrS?;0Tdu0}Egi&KKy8X~c z2c!dKh=W0O?rhOfJaX{_fOrXpnRNP8y0M_$q&Bo_R}*B<#dhs*TpsqeBh?nv$N4ka zK+d_*FYTp-z@gTi4a0b7if>APW>Lv<>l+6(mr=qDWF0{4YQcu>BKD=)tDYOQ3-P z3F)wK^#}pPjzCqVJi?sHz+b9sCx&G^gho0!=)^165fllJ!W^JDW$Iq=wXq-_K+Ias znSCKg?|MCG^T-knsc<;73_vb8&DE-I6_BK_kwFMf_fXT15R3}tjsw*kgCKG#xG132 z1qt1G+My#UiuS?Me&wDL=sFS zmPOTs`H2$eh- zOsrU}?HL}U=q)4+8>@{HzuJ&yhk-Xyc?g$#hoj)!0+d0AAgi`Fq`8EDfzm-nu=b#m zL>vC(7(zq}_$7%Ibjw7o3_yr5qibY|W9rS#Gm#E}TE4$dFx8eSi>D=3X6n0el>eA% z^J4|IT){$j2{9^m0KhPMC_%d;`m9kWgN4$iy4&u=u^+M5Nc5F z2Cig(P>x*%ilZY}ksHKil7^5Z{Te{)RSdqdkY-__j@zXhajYZm)7()*tpyvCE`c^s zS_ZfHlO~A3w_-fxFmFjdk9vCyrw^LGLVkKQG!xuMY|s_~ez*chlXFe8pM)p9lSJ!< zCc|6m6&DsPwuDZFJtlu<0+9v1s}D9%R_i?mbD9?|1OqmL@0eL@YgkOAWjq3;kpNL3 zxY=a`@v>Ka9Qm^9pxR22TN#`*mx7uIEFMKI{NbWv;8&ajmsm7u1}EdKUQWh*Z)+ga zuw(-HUV%m+)In3Ud<#(LKoRKz#nP4%Zi3~5_M*#LEs1~Rx##M#LMMQj*8ZK@^%eN_ z_7W_J;?L0o46m~1q(&!*SHlZ@NG&j0-%PTuP{Y zF&h*v+r|#{MVs@z#hwaLRRsLhfJ?Ai9;&vNodH zSK%sqXArW})-;QDSCJdzP85tAPyH&M7ay05<<|seD9Z68__Pv@Jia0IvgC`XUD2d< zdw5)a_$6|oiK#n#`EX&PJ@@|}63kUAU%GyE0e zn>f~vIZ?lrv$@nC6_+iuke5;2okAXs)4X2vEpsw1AyRS~@zLd0Eo(OHegg1~U0G=T^2X3YjR78&3dDcNQEPci=0KTGKv%dF*ELt)z&*bDm z2?s8L8wH=>aAAmC8rCaOE^WX1SVzw9eN{bk!;H?1bJ0BJMdUwG&xi0LIkk(NnGn>W zG-{D{sBNOzh`5G$flB$1Fz)tLCz(4B=_us*B zvoU#iK$%4L{Tx*=R&%#cEswNiVL?3xHF7m&LxrqvvM6L0&BudCi=Ri?bmWQjBNuj> zEqubU^AFCBajmsSWX|xj$YYLxe7W~Hh_J=8zH3{~+x%=W0FMXj3f5Z}^vDzD=j^w3 z4kk|qhE!LE#w5Jy&|ON2NezCRVX$Hjf3(s4Sx1lR+}pgFGa(6H&x54L!vqFb#{NUn zA!#pb(}Y=^JJn=M`gn$Do_Ga)z z!jRT8eQoJWl~^=a>W8VHn-t+fmFGc76IbxYJQW<*1mMjgR|<8yZmD@WR>VD46gT%tu6rDx|#u!KJDD;nK~ zW(Q-Jdxc#vtBzRj^icN{%eqt2z2trS(HBrFg0j8P{Y#|gWMY=GZ+h{b+5hAj37 zq?K}b^)#;7H1!Lf)m$k~j`|t2*7lP`ZpX+M>fml7e2mznsi0Jopb}Zz!wivif*4Q+* zoXM}Q5OdxnU7WJ6T}_*bNQ!5rqpY6*q@$r`nVUdI^|iRnR+xB@pd>#UyGTF#DT=~H#4qpSm|?1sG;_2~`8vS-X=j0E z>1uOdnd=Vp45Slyv0>;}jw}i2L?cs5L`TAGNQ|q&+wM>`WN6|g796k7o`n981@`=A zD|3$1T3;oPHZG9(i?=RCmC>9-JTJnSX=mGHU!Bf=5U_HD`pwt#J+4=h z;CcKIvGOJIauGuU{Y9T{Z<N zvNPF$kYOmj)gkz~FxA2uHVB`U_KdA&ZI3@t9x>i&MlTF7ZXVi-zxNFpfIZk-bp=N*M2>bxxA?)P&KG(dUS9KRvrmD|@kywLJG^ z^%Z@k+3E8X_^(gI$M~8qLCyupt_M63h|5)d2h8Un75=H1DGBVC%-S0%xShg`aX(Zf z5c{V;OdPtDMiil_nz5y%UuCn{t9H@w$1qg@?nIhej(DF zNVUf@6j?WYHHOYV%Qzd(d#!;hgPLL_jSEY>36jFlV5n*yDjNRGQoW8OduM-KjUg~N zj~QW?Ci-P5a#Ajn&*97|=ljCy#H6XnB!UH@VK5$g8X9xKp`M=}L>b@oOv*+;tYL7F z2l(P2gfJmhoRLnlKkTj}l+8mYpgH%!?aXjtxiw!vj;)$HNn8$6w?tbHw586XspaH| zV2ZI1Ula?_=f8*R3p3CwbCap*bLTMJC@L4U(wW~GFFqwH5>7T{!C))qLvH|#{q(o? zAN79noQx2NU@`RoTKbDv#(42DLVG4OWId&oMDQz(OP%T$5EiVNAii-SGYaFyZ|0xd z9JVHV_iHsL+qCuM>;jC}`81m)bMY2f9z+&bYwkfOjK1#!j34>%#&S4Y$FsjdXnbks|dx)KRZSIQ@?hB|kwFHtf;QR`7 zq03MM#g(q!wf@_u#%UQr!?0j7DmL(!I^hxdg>x%r{|z>ZT2(|y5;K*v=)R#^eMBd+ z@lk0<+N~E4k^8~nKC&KE>W1b;`MOO)Tk!^rg#rUCbKrAG;$H>0se4+i9*TJE{gY{h zJg@;~(zGEF7+jOzo@y{~`-KTN0dzl=T1^do_a7^q@QRTv zA=Muytd4`TtQCGt7K~LN^fbnDPnx*n^7~E zY)BmHe*l<$E$xh%jmsTgwF3XNE{|vBREPh7sPlnME3XK*#WWDIKj&ODao4Svm1F9} zSWWqN;oNv+b{#$B%!iI?;`th$kY*oWNGIp(TBS@Ip0l{$pzRv>UjVdc)n^kW0?qxP zY_4&oZ5a>Db@5yBID~*q*Ng^#*YZv`3&PeE|uBl`^BD{q1{g5iT ztWgkFM9Gwc!^?AxkA*IzAG#*hmJ+t+n?-S_SvK!fOo@21#4k%BTU53P@qUPJjj2)< z&LRS?RACUJ_~0e+h9{CfX#^^|p=bBoFiftWn!uM`hakx43Fooj7z8N)Ntw`VDTyp| zvohl%ML5ElM}IA<`#C7$O4*VOKAXkWD5pDMig-GOl*kHwYwmkJ(m9G&qp%ITOvl4Y zX3qori}YouXJA04P7KioRWRQHwDFTgp~TnNo9C~3lzw81U%T02v+YoKr2Uip)7LSK zkGPh@+ov&EN0!=l8`b|6=Vu6H zA5?PjdqWKQymhuFw)h}9ilD>~q&sDB$tQ(46~4w(d^?Wd27W?;XOKZc+ft9DA*m!$ zb3W+{n2!wPHj%kSs!x5s$c$2Y&d)(9lzTd%=JHAepU1a7k4k;jII znnE(z@#U}vw5y#Ad~acb9jAOC;ZLkzI=s&I2C>x;rc}kTQN$$AM@&za3g$)DSN7DM zfgWPH5rer-qp?o=!FJ;$UP>Uu7xScP7NK$qu7x((&a9EX5;ZV_zlvP4t#q{_&Ry~dHmEBG0>pj^k#p(HWXfHbO%a`r#4p8SfU$mcQ?MS3?Pk6O1 z87sXh`3mlhzlTNxiRkV*T$_!Z<@7hnUsa5AEgLY8lrC)jqXr40My@(SN}_0mT7FL? z$N7M>cOQF;JwPv>b0w^s0#g5}{pFX+FvH=qof4JJ8{?B61RL4sRzPK zQJ6C`Hw)L9R2+b(=Aa6A06+B5i?uIo<*UsR4M+*Xy))|&z1^r{&W8KsgjoIafTDw3 zx;tP6Ei`oGoHKo~hCQj;C40qew6&Ck(c6#ng`1@2r9efkq41&|ATeerV?@GHHR^aN z0YY-JuG)01VEaq;u5|lBhT^98Z_-EhAH}GAseeBkQEz7n7aFJmNv?syb-`RcTtA>F z4@Z8<6gBpcN}qiuoZu}yL&bvf7LIsLc#v8qwu85p#G$Y$D2I9v)q-O`hjSAZAB_|YUaEfQ2=MKB5Vd3!$e2$0ku<>nXQz;_3#+Ai{9-t zv|<6_6!-N&!iF4w#)D}we9Y|itkM^8>C5RP$81`ZFrC?4%0k%B7x&W@iaVrXd5uRq zMFw&E&jb&i#kC#t&a6xrX5!zk#XkjqKjaR}75`~qwC64ldsC~TNDv17$BC9>CR;qu zX*(CmVFlI~wPfhdx!fi8vt`5|pW^r*$n}^qc8t;G73A*UQ|PA83Y+oGS1eNw-I$a% ztwpH|_qmD9SEN!8L&74FLtI#A2+$m~LR8siXeEwTrM6zn8wzt&MU`<-5V?lTY`2GXrsCnB3lS*X=RW zqz)?p5mb{992Dc`1t{D-X$WZHUlNl*$NJl#7#=rz47!4ySvHRT@vdl--3~MrfQ^0E;vLHo!j3H2`o!Q^x^- zpmpK`pwa?(0K~M{yZ{E;I(`5ztpgK4l9rVPphkPi3NWFq0RS9n9XJ5~w5(i!7}`s2 zKo)HcFQAmxfgjLJ%b{lxqk7ssttQ}3peXRmUZsHFduLnv`E`gZ?FJ!&A#v3z2fxZZ z+W%s$pbcT@Px_50m5<$`RPNJ=Ia2V2TwxpDP(|jACzX%uBJKC5ee>wBi}u1c>LJ_g zn_4O#pGCO5%|LUc$Zw1VZ5%WVsW-8`@-~UvK8Xj(O^tnLK1^dLE7G%G?9caa zHGhqVMZB)3#!x&QRiQzj(X3U1DB*A}>QJ?XRy?m>6)otpYP**HwCCQP277qT(7=q5 z)6f@r58jq7YfNxO!JAkj&vUC3EMj}B7=}_OCjUe6s;`R~CeMYmcsg>m`zH&(`(B8Zn>MI-BM9?V@LFG;9KlsY`>}_jGKMtlTloOYycr=w|<^O~z z7m2ootB@1V%xWgqPd_>-*DL z)lE4}9`987S@_SSsxeYqgRZjFv>!-u&v!W#`9vJA8(*6JeKa^F0`Y8zoFTCXM+jx7 zNmH7i28sM(LNkq5_Xx#o1#({U7yvJoK$@NdGzz6>*=(uYA@2t^IA!{2Q@#C`Fq41iy2Ka}KqTwE2_^{eGsEa0`oKSRe73t(@ng^B*Fx{c}rA%Xue99LHz9E*H%Akf|UwGxU92k301IEe0qG#_{TiKdkxPFI;qk@0Bt=F_njuqYx?hFkf8dC7$gBxWPZT ztWqkB<5!jfa30h&D(NQhcS_YM9yqisVI}d?O9N~VSo@U5llfDn>%NWdr6LfRTvD4| z=9&xmxcTLy#a{M#>@qBDLEqB$FCv=NT--k!5Ht3huzn&>-h=n?9;k!uKn^JSmj`WM zGnSnFc-L!r-2!|Z{__7#gnqt0NmS*$PuC2?40%13BTIXbG=oTEN&+%TH ze)WGNREpU;g%5B4%Pby>8?1NvMt6IKsKjUoOkIXjS=j4Ni*%XX9M*6j;YA^(uX`u} z|N56%@j)yh7h?}OXJcyrn~JUL@OHYYiG^{&i%e|l4%Bu}y4ca={~<1tRK410W5LS+Q zl)@shUMHxB+3(`rBK)Zc+K+&rF%5F)!5egpSitBczF~D?5YTAM`L_l8{d2$5U;c5iDI5v^NQq-8_{ft0JHK zMQo5NczsA)U1zJeaCp1K=QRnR{Qdp|Uc`D%1rSgBtiYOv^Uz0LRvBQLhO9C1b?tan z>}9iGRW12%R0-@-n!dvvzEZD`j8^a!|_rgHM)qzFFq?<8&kuMFZK1c0idq1 z4nP?;@XuL%C4n2D!p2Mn!J0&60XKdL2U*rXPs3DI~cDKI&M{OOFu;1WWwR`Ep zHTkbeQFi{)`=_RtJA6#}FKz{d7$0XUky(rO;gWgst4uz1r94IIKWKJSV;u|1T;?EhH3R;LMNNW+`9bqw(0r76Zc9 zwa7QS#RE8LIcT#HTdBgVBX`w6-Ss)CfCP3IXC(*+i zy>E3!AX<5O3J@F2u!yH@S$KA24=FLAi1|94SAP$itD*w=C@0IEYweiHqx%wH>($X?)AjrBmu;zZ7jEX( zICCPrKeP8%7jNLpAkP&LeBu6O;+oM~V|T|aBm6w3>t~v*5qGZ97Kl%6=dC94+JzjuPkAeJt~MaS72V zklVfgv7pY$YhS^f^fSB_?)w4ZWwqGVa5vvQ(GyufEs%bp-RM8hncetDzpVX_ev$hB zL%;M6tciApclxADjbshg%BNnKxpN6Mosq*8*?zpfea}U=ZNuNiMiw9b@dKkcZBJw` zXu2Wh4G?jO8PW`KYcfT!kN<2<*=*`61Xuh==q-QWRzDHi;UNuw9N^S@Hl}@d`E>zH zWv%D%9~HyYItk8PBSrS##(N|4+Vta~JGLb+}mctQHd*ESE`mIZS4z^geAO9ldK865KCSAJ<-3K!{#zkb*B<~n#_JaY5!tK zt?d9@>mBbXr|Tf{KO6#k>K4CVMRzt!Gs;`$7!BWdb4m*b&fEN73cGTDxFIbg;`XOs zt@Wx8nG1VOIS)xHZ5?mu<8{#7@d-3!dq&xEWvtXUn;nqV>Gv#p=#r@9m;wv5KWI*^ z5tFW}iq~(l1Ovh%e~1CfI!;H{rL7m}7QX4wA8iYC8P9vZ+i9Q z-c{CvwI01QDFme#5Y9S}$FAeewB*(^A~<)=l@Ao}IsS+$C4jHh5&d&#^yx>zO!Z`^ zggRG>R#GfD^lnV?bhKVV+vKp6Du-?|q&{I=@Tv@IipWJU5`@BENUSNdzO z;vb!15*?j}ni+OuTtXgVSq)$yT9^5ctZ~=8P>IVxg|J>P39?~g=58NSv3&q}qYt1< zV#VUru}iQohPyf!zrkb`TGE#SmFb-)P*#mwu-GXgPDByfV6Nrr(Nc}PmLXdIOK#cf zIqiVHr08h7`2zRsR!hAaLWU&jyJ2ivF|9sjSXb3D9X%k&Ly-U3wtkucb1c*dZk+Fi zy1BY_h9mbMhccv*e%vfwshQhTi3sf}0QXM}&8;&6K{GpLFH>qe=flfwCY>fX zP>G|L?t#E1VEAtdB5%_#Vb)-Fb~+Erl8&D*RMtcf|J(x+ALzovyPX+*C-9+-{CUyb3A_aB9eJ8k->`%}`d^5_O@LN!U$WNskESi= zo^f^pU;Q5+~GCTiy=+4{KuZak?*gb;bwoNga!w5C3B`4wtNF zPya$k?}(BUcc9y~nit+Xbp>5Atoy8}ru}j#5HWLry<11Q{x4Pn(n^I(6>Td2M}+XR zdYguTf9YwCY#!)U)QgE z?>tpABbi1BHv5mwt;u3ri~o3%1Fc7`Elh1uqe_j^wVC2}(|0thAqd?pSYG=ZGZ4os zQvS!hTqD4*CO0c%9nyfbmMQ<^@CsQ^z~>1(%el%b54FqwMUTZ}HFb5tqg=X*FeU8| zD^@e_Ztc*qz$Wt3GoDTA&m{bzzxTpRWN-GF5D6<}-b?`~C3IUCi&kjB2*nu!7E zxC&MOjlHl$IOjvX()_TEs@Zjc&Ohc)TisUxVkQytt}wRP7B&o%?GMfIyzpUq(aahv zkTOJ6xL$$lou}VZ(o*NXmdSrpcp$je;-7r|TA%0c2MpX@V$vF?K0+E=iI;hdLZ`Pf zAF<`Q7#735;X2BH6jq86N-HWUsUAoBV<JG}XL@K^y-PhdgSdB-XuKYq1{m#k9P( z)H_P5I@j8!*YCI$2I35+Wl`M_AIYk99X2~$1;6h2hqv!iR<&O+06taaC0KS}#oGN|M_cMX^`iUNJ0avhpdXpklmYO1 z%KB9H{jChO8dTd#{?lmfQo9;zQ>-{+COtQHHJDij(`%W!f4&RW1EYT5${8|P%DGZA zu!?yX*yaBeCrALJUQZfSmsP7ghGQ5^9}%wP&*99!MUNi0qN_k3UcqFaqkq&GYVLjT z^7*%{Ge!-msEUy3xp>lx#Zt9~mICYl092saiv^TwmbOQ~n`VGA-cXWd1fkH;aF@R| z*PYqZV*LfhfAs4P+aqc*{g^Nor>dJ&BeR<^=qfObd$$%ZX}9o#2aSN8`yBo5yspn1 zf8RFn54WRv3Av@;Lh2St{vM9^(tCnAtm&orzQG^>AK@HEAIxB=KX-?raxqqzxe+HWfUpSJP;whi?kfv7rj z7<~^?VsVXRsJw<-eWUSzQ0^4<$k&Q`jR+TtvUISue*qL+$stAX;gE`fEEfs4+Fy42 zzrB!pgaqiFKu9rXbxJt2ecvL3fSG*R2F5-s{`qbFVPI%80;csh0;Df3*6up0Uk6U< zE%*&ka>7EJ_FbXr_A^si8%hVVgl~8AnX>f=>n?*c<%fqYb~FEW><6PqeERW*@Y%b> zGIzB1jT@ng=D3?ZX9NPLcS>Gr#Aj|7T@7hVRqC0`PY+#AUjKo?j>TT~ZYBI8A_*9( zZT|(}%3c+b4Xgft{Y=$E0rc0uy8uVbVYQ#4vT#mC5EW)KalW32tOuLk`8{}Xq#u46 zfTY^`?rAOr%>+P*fFv-zx1(s(eK&fUozIx;l+iSUjQx+nE8{KeP;7HQIHf6b!9@ua%?JJypE-P}l^z7v9h)fjjNQFmER z`op<*dQk!KMC6rl4sO3%GlDk7NoJ07?=~nPEWC8H8@tN?HU-z0KB{7C?U>cF|M6uA zs=k?D&ftw_YRcG5lCENA!ou2AS=Uf^sNLd~cxUC@@J^CsipD%Ry9ZsL$W0#IE}B`A z`-f@Ms#DYaL%`wXyX5=fGj&(MNvqz`%Q54cRZJqw9K(za)0rVnxGc)|17O5WiD@;U z{0l|V>ox9%aUMB6K9>6|BlsRLFIJ%8}Em3uO;Jf zsLlw+Xh-z71DC6b^d6=TP;~V0*Cxo_9mDSbT5_oBp?AKeQ4P*!z_KMw$!TW$3*Aww zTl2RV;Ky^11ta7}I2G|Tt-W!K*nft?&Wh>6Q7V6XOBJ~H3vXY(6Od|>Hncde2$+b> z_$8xrN|IqnSEr1BN9wTJMZzA|plB4xL~V6v%2v5C9zPF6>~su%Jd7q`<5!^3G7DdN z+-Yq1nH&#k5i(XBMrg@w>zC+8J)+0oE-PI2U;r6QAXq6!=tJ@qhF5WMVZYu8W#a15 zJ&WwGlv;c6k5Jfgw!nX3#;5QO5cQl@w}exK8nedv#q{Ey)lojObAB;2_%$lgYnQP;L_cbRW>%n*bZ_!6U}syh zpjAgvn1DR8U3;HFYITE_xA)e8S%%bRQ69y)3S~o+kz#GX?3kFu@f!oD+G@%Lb6UCF z8y3TwhHpuYWHr?ESGFUsuP0u^7${-_~1*L(m)BE6rFnkPm{i$QsXGIuiI9RC%&r zZ>C24fYV@}!RK)6?U*nyNlwZ7&UCvlKLDJx>KqfV6T-~fR}NAAQwzWM%M$HQOP}9{ zV{?}EXk_))g{5)E^Oc((^OTfy1KhYa@HQ^xfV?10jyh36y*F~7)4?U6^t26{J3VfeK77Vx zZRu(D-e@XJLZmlw4?CD`Y%=9SqBn64b3*8jmy>#Rr=J>@x@Ji$vL(g-+sPy;Iz{#t zP(BOf1$Y;f*){_2{bi5+>rc8teU#tL!w4uU>4t4N{{Lqb{J>EF<+Bne@VI^QCaRTn zzFRMdw*lDzYkOt(%*w1dNQ{W=*)qG|b&qrhS=Aqxg_X-T_6K9Kw)NOoX?FQAsOU87 z(fN-hL}p%CSs4L^R61Y1U{-b+jA$pLSw4%!nx}&QS4wzIg5J1ck#xYxl%;3y#mzNK zxblaoH{kSS9uGo)4p=bo&CRk4i7YjCb}RD;G>uOQK&wlIz)mtUhg>&nk`G9=lN@_n z#s=RXD}?~J6wp#^+RRCbCkyhL;h`q%9AOJU6u6|qfTq(Rt|2A*+~0MaZ~o!I5?1zT zRv3>RpAXqtP(jXX1pxilt|74FoAGxUm~nKm;w4~S_4IXDBCe_LafW?E{;tDp=6H?7 z2xuIBH*W4zs{fW*E%G-RRtg^A)PV<|3xEed?KPlE4qogkR1R2JowM#1z8@fWsI`YuWp2aQB`ZD z7;cueWXp5q<10aTgiZgOfkyM&%wUz$D6y+Al=Y!IWZ4P7$zgtA<-F#D)n9|KTp{93 zZkZ*W?`R2D90p4)F|&9qf%*%yt;J0WfnlK59HVM-@XJwFIr*F!q2e`j zdt-(n{B7(Y_-T-q_f6W(pZl6j6M`>TEo^8(cU=BRjYM^WAk$KA7Qn|1O{gT9ZV_ylE0 zBO>9!O7$rWZpc5&s1em$^#-X4%ea25=W~aSkLvZB{}v4qo>CX5q{Vj3*4I9|8&Lzf zy13PCn>+i4EmzW$Kzrgi96pXaBsx2A`ETIp_EDAqlobidjPM9vDRSqJw^@nUw5z76 z0&7V$WIqfqCO08udD&zSYF-V_Z?RIR?&A~X2o8`0ZsO+Z=__ZI+VC&YKzOH8X8%`^ zE(BPR&W9}=QuL>>^SLv6CBmbwYmLuZ{4R&th2EGPpAWTQLJ_m3Ko+FOx?|C*ErXEwUVDD1Z|mNN=;_9a+{a2c9FS?$xl}iAl@-brGXI}iL^j~WE0s`+u7|~k!is;aoNHDAis5iCQ z!U0S2q;2N8nH1RQRHrFhvVQ)>J9qTEFF3 zw!UuGIDV#5UZE?WSh1ErQ9uQ2b=QgB(Lw-82}yi`C7LN;V+GNscLoNCv6mrl6+{?f zsC>8vxq<=QKp0Y6lM~GDgW~JX`i)xSWVy@|OhtVLG7=z96=@pXdn+Za6v5&c@{KU(U`iS0WB)?ybK!R`Zh9EoPNwM3<_DnT}bgcM3L**p+?QvSy}$cNVmM46JI3 zL8E-Nw@b))FY$P%E3h1!O~-ra*4VLo6vLUh$=KSr#gp2U5Ts;2ApO1VYC;HE#sHQ_ zuZemF{x%rBv61>Wh&l;ZC5pSaxZipuuQsYe^{-8-z-&^r%^!xrMeT44um z)p&n#K*pgGcbBHe^x%rDNQgiQMiK=x(va;#|C|{JBY9fc=c+H|3--hRh^_2aDyR#& zEK_Y%Om!@8IndQJL9jG4Y>4dH`Hh7%Y(wj~21n zhS30}D<&_koec2B0J(4}b01+S5N&BU$AyrD2!BAywk3oi3o3dD1|WDP9RdrP73#Gc zt3#!Ckf)d@v30fQNADGbtTLUGaY-kAl$Yq%EWJ3U=;Xx6X%!p*!CL07x+JrEf>?G< z=h7f@X2fjtI%xnChiV_84D{?khcgA<`jA5BtUnJ7#13tS+yuqlf_g68`K>7B!lvIv z?&QO5w#Fo=?LrHvi0eURQTbnz&ETI|27esH81Yp^N8>p}b`pg0P2;qyi;-K#-uDf7FzoVryH_2xQE+6e*#xj1_m0=IHFWA@B4#~`VMVcuyRf=JRkWYA<8e`Td&<6*vtlBN4 zz301t8q>aZoWc)JUedmh3?hU621+?djo-s5bs#0EIjMU7&ae)I^Cf;{o9H}R-qcn2 zS&3{#ykMJ5Cd9%q{acP8{6sk5s0oDl*%RJ0EaJ{z#mVw5h$Spz zUrC#_2emB^!P#ez)RV1(YNy?TWz2;;iaD^}+F*fZtvuud2#S&JWUvP#U znGl-b1yJxeTi%4Xp%WepWLXVy=(G*d=G9g16H}LOan0j3CgPYh+leM%Cn-7UJ%NleQF0Gd?wvNwvoJr{2yRt>p_35 zZY3+q5HoWJ%678CQZuzlu0%j@GeiIK+=Ij%JZC2yCJB4(t04jwel_kPzx%jWDG(T6 z(O(~m#1t<8*HNEceIb9PNhne50)HeFXkQe}En`jo=4`@0HZ-DB|K^kT!t{ z*&oc&H=&(Z`75b?X@A}X!&v~0 ztSKnd0?p3d5I$b;oDe@6h#58@6V7FaTggR zXxelF&6+sJeGmodDI_)@u5UUaUu41h%~JgGtf=lp-r2XHq*CQ^yI zG^{U|Dpz{>JDd6S)b#5?uIhQPReiTozkw&=_93{Ta=uF zF7$N<5DeFSBw(uLU6;(5ZH$%GM0gEg&mhRm$7VkJ>OwRFXwh}yN-b-G3pEw|-T>08 z=#1(G({b~qtr0u4BnYLPp8%Ot)=`?cw=q7yjd1*W9ou48%lQXlVd9vq_&UVn84~5s z*nN`D)(~i|mMMpi)Zv<+ww`=N#9iRTX?ViM)avKw>%IYNO4z!@SsPM6cXvJJ+lKUG zDWLWvJwR2_c&WGsjx|Oqy)JL~GcqF}JZeiWW?)&H*zz$j# zDuNiV?7VnTULzms-73Jp*E<|Cu1lB%`Yl)492ULSD>;BZ!V(^>apw--5SEu+U@xl^ z%G_p2M2;e*t%qviWPFp%AM{cP7Ii^TxW6C!wj-b-=Mzk5j^UPU9*Q3TVi|xaJdwjL}1-hTRMV>W2M~NA&nMFJ< z@$2)f#3GxqNnpvt>cDgDjVxt~ZVXCGnh{VCA*y2Jx6MMxf$j8XK+@SPnt!$6OeUl~ z6H*|U(Ct?wL^w#Q8jmG5CmYOS^7I{wsr|MVS(uSHznk1K`;Ay?6-$*&)$o9CAQOsT z??)XWTY)Q>u^5l@wl{7hJT->?cZ4`Oh_xpne}1VaCp^(Ldv;S^v*36dRDoSGK8#zz z(iwzfdB09mmEk>CUJ3`D5fc`-`rbJtJs&-vLT%us!_gKq?9mY^9^@xECe>S z88G!;#5>)2w3vNLs|eIKgC*R@E^khMN8Hk-1y>Bs{99P+)apEKf!zB3jPZ#^9p-%pief_tkc&;~R#0=#SMK z>&O9F>p^WcN{ww17RY!H-aeNG2t5rglPxqsJqkU*cS_|3W(`5C(%15^<8h5}}av)u_ljb=Tud^_kJR*J@C})%56@(MA#% zud3_s14okpqov7kdS4E_6p^KX%@P>DVOT>Lht}8SnTrl{gsbpsfzpL3gHFq!obRGr zZ9f8*hD3STh25)S)DfXHihnhfjtF9JIrr=0812%h9ELyUX(4doD?!kGU0$+LMg-wi zYJ}-q+Et+G&t+mVzOaGrnc47-$5pd|u{_%>L^lb@HJcQ2Z|1mC%K1@nBgcD1kpCIT-IJu4+NR5GMXUZ@A&!cDZX+06GzV< zz?a}JtMHP_`6v)YZV-fWkPx|iwlGB&(?}GW9i?sm>^(LS>WB2>-f7Mkh0zw>yjYCR zEjTrbklr!_x`ILcg+u^p5IB*b^=s5A6ZP*EZv^a+F#_w*r~C zzSp8Ho4CpfRGF*^h7Il!-f<)@wW*U@zCM>Lr=}XL8mC2rSmSe`7}`V$8UofwD&6}+2})_h)k8AQx50yO8vSSq_(#0fqCfbum>$BuW% zM8OH^zFZxr|59_UPw{2C2|q5yT3~rt3T)tuSDG`K@Fc)``{zdoqg{dHTGpj)SCE-F zg^R>FG7R(nf|nvi%_wNzSaRJ_6)iLad2G7cp9Y2AhrDU=hFE676QW;b+GAC)akuL~ zm80S^9jtVi{`Th}f zeaJ^cek5UW;dSjO;(K?`O|VSJLBjg}){N$uBvOG>)+0qZfDm>mf zi(x~iaTMZ-Y|Y@Zcjxxz?j)>Z9T}D&H+Muf3>dn0MPtXL^%XK>-oKVlAS1NZSev|> zt5KTNJ3mOM(`~`;|YR$@9*7MlEcn|0r=U z^kFMswGrB5<%6@JH(x)^Z}QS6wO2nNGKwVHQgq>v z1^vnV)>Zs+4lxxjy(6nCb`as+!4qn&uQ`h){V7FL3%BE%6zVV}nv3;F4QS&VRgChJ z1Y=e=l7$ibzt7JOoGZL`4&~Rj6l%|WSc*-ZvbhE{&j-3UUU)YCR*Hlj2G2<=gV548 zhvQ>cH>cfeQt9bXIalCRys#ueu*Q#fYpRz_vwTJ{Tb-<g5k} zGwa|fxJjAACCMu8gqz<&)YgDVQ!<_JlTnUM;AFo?kD0_!Aae3Y!&{J)_x0iv zSHs_p1yF7Hc!ZH>v>m*S4P(GDOKF0!ZbHal8af1vu<%CCQtgg<5e%h>rlv6d=%W@J zEo;QgcEa^VQ#W*YczLLOK38#3{gj6jd??*?o$hOTDmGNM#>+%2-Siv%mlbykwCHOr znuZQLZO8)&x@GQJmGDC%nnO>ObT*|ZtRsmIxjI-S4^)5JMhmdDnU zo>}y!aAR&b?}ik0k{-;a)9*r!yQ^8B?9ZsE^(st-$ByXO+XyX>j5V@wsIgwIGqR@^ zbsj>zG8SYMb#__udU@G_rr;VO$T}$39s%KNXSo`T#T}3j&&3 z9PD5n0{ZaFzu8B^7FrO4#K+`16uDOHq&gmHF$ZSGIl_$~SRf&ad+aXPu0ekhP_)Tx zQTvwh|10dw)5h{>_Qm37!28kv2SHdC`*j2DeG9Xjb);2 zg%BBQWM2l6Av@nYGkSkMzt89Mc>Ly{nS1W*zV3OQb6)4Z=J9wv?|JX~Gh)1p*Huf= zr8C-iCBw44C(UGjfUzboI(njLbexTIMWfD+|BA+|G!~0A-+30?3eaQPpOZfmjnH$K z?QE}JPbxCW&0T(a`k|!)-KCD^txt+st2mf3d9dWICna%}CRP0JsijhF2a2hls1?6` z;jQ#tQPVrywy&6~MqD6WRqW?4r`k5Vn}YKLqDb0R)Z=(}2j^T`s;t{L=Q*DjQgKO; ztNV(z==Q=MK_0|A3vdN&P{v8SJDYu@dh@{a8{Cs zIIm*9_`3t9?5#=;@=hpX*^b@4B%k;zRC;M3hy7z?o^s9|*6V(r zrkU5t{4;#e;Hs1N1XrsSbn~n&OnWdU$o6ZhDJu88CCT(89!;uX7BLTI1zAI*XLn@A z^m2YW^wcBlxcgoJ4aZP!l@D(!^l`PKG-8JE&SpZz9dcTer(Ys(vf6nUcE&dkwAXi3 zPW`4g>nl}592`E9G%)n3c}gzGH=4(+dgBJGLq>hSb>g|Dm>@GHdK3dgBoFHqrdnGA} z`ZiSQ8Wy9u+Y)*6ic(E^wQN30sw#h_{AZR?v;qMCkxOq^ci@(Eiy)S!)_zYKaM;T|#$l*j{<#&Z;T1Or&?Fpkkl`V=7**OP#)v_SY zl@067TDKT|R*OfqKdve#w3!?Q2lrpKGN^NpXdYt=N>EZB6H5B^qDwU-Y4-kQYd3Xf}oeQXWv9blC#GwSw8JxhQ57huy_4*-wTU^LNicg z@w%H#f1*^ZQj|h-A5v{i)TqtF&9OJpFxIo}X`PS)IIDQ2<{ke6XeC;zUOx89cVWvF zN)?qm->;iZp0lHl<(TYaD2nwwGhmiQWq0<=Wy~Uu`C|922A+Zf-ais=k4i2@R0=zM zOI(Zfv;oRWWpay+RNhoH5WIJh<8#4~S^9&-^?hlMzC^CLwo86-I&@|O_pWHY^MPp^ z&?xr3u3dbdAIdp@`B%<1YCY?v#sh;&j>;R&{S1C_o;JB2G0CxSzDWgr;Nhbmi95Tb z)~DikQW04WV6pXVRW4%`dhboQ6i{DE0LC(Huz1P%d){!CIvIooaW2cI5iH$r`JE$5 zZKSU6LC8HO6?@mkCbckCvzG<2MTO#{R(Gvh@5`w-UR;bfFXlxQlnuPEYcX81F-s{z)Pd~=s_!D@dFbErz36bl42-^-UdT@o8`}#L&0q)pu>B56+3h2@NH;P*e`G(4nKlx`> zA*Tvz)V$6YxN2;%72MMF;whL|9huBNsWirrGo>-6p3|f|_9W-6@fbSiDQs*dNB$A^ zdhSV=F@xMG#8`~yxpf3ZY6tZ~iCCicw-0XIbXj+nONOb&lJeZx>yWD{w|i-Vxf|cs zpMmNtZCycGzxbt%$qm*sc-O(QsHu|Z+;@<`t(sF0hB~Wn*`r=1+ppg(HIvCtirF@wUsL4_3^yFL7YNOTdQlagF8(E` z?_)Ohx~T6{U8WH{4#8BZCbKkdmsl~tHpq=F-m8R$n|gVf<8gHyrtoPfOKr#G(m38> z&Rndh5Px!Pw&cZSJqL_r+P8xZoQ8teq`8*7$5Ml&Z12G#u3u5>oOT4nxBBDeGiAD) z+7t@D&!0$Y^;OXI3%<%oexq5skw%VK$jKAVuMm>{E|*@msCph}q1p3Nd)~(v7b*L%Y5aZN!DTA75gJgGnC%a zKHsFKM>G_1W#(JiN%JeF+j!~fgKa0q9wjZc`-t@@vehiz7QiJx?0NAZZ_jrsnw#>Q zyS?7+CmGJ~xX*8ButICza4qKhQb-3WC#o(KNDod?O5>ChtrvFg*2OE_XXx9!YR?!4 zW_ds#?NJq(;+Gwz*I#+lZ1k-SZ$Uh>^lMdU--3@O>V&e^6CL;+U(Z*lKfUyMdU3HC zx;gey8y-B+_-tFt0yR#EiaJ(yanS_jsMfQrgVp!#Lvr`^;Xmm)Av3r=i_b18#hERA zsoQ}c)Kp|PV*F2!(u&@!ezME^E5VFg;-&1-E^PK-56bxP%m+7_D$_039lXMsCpT`v zt8qI$beoY&=591S%o9`2;d9JT%O3JSotpXF+-QMP)# zjb@s?McXWAdH%$mme@ep=APjJIdQLRVs1=c4K@2@*^Vd8%F_jbdqJOxCD(vm0d%y& z(y8#@E_Xdbfz6)4e)gQD=jkUC(Svhkpxp+>1M*W$LaQL%m4n$RpoZF6Qg=DHRP>A6 z_XhCgGIHGk4n~Fn{LWVh;1N)^vBS58ycbRu^v5M!?<57&vBO92#7kOIs>*IzdM)5v@>#W-Qz{z4?hZNo*kni zQ!8#v6;gU!NK@8UakoHq*+}u`r1AH(UHSXFO~X-X36~6e3RmrqERZY%o$XXrz9v%a zzr1@Z+=eC!3_tCCI!CVGxO+j=e8}pHD3z#Jc9YAtg{>1@wq*1T`RJg$w;NTR(>hAX zMc<>~M0a!ly@sKh3uD+C#0gWkM|cvO|zoT9d2Z6_r1-`x}cXn9*uaH|?n# z)b*GJC)9fII{AF3;cMxi>ONDlKGMn&5mTM>CesZqvOZRu-4|#<;^ZCII98s}&#VIF z+g^NxnKL(Deq>!JtL!OOG?|DS8tJYz=t0hKp57^*R+Kv7nU8GmS)NBAY;W#0hzr?{ zmX2K09Wwk;(>lOjeG|1T)zTp?SJ8ZRAS>M=Dh}#%cZNi`DkyDQj%>A3Iu}R$0mG9z5KC+~E6wTQ;an zd+~N^;2K0Y#& ze@fT!N&HK8o#w(%CtO=_hn1RkRSJ3Uku%@Sgq*5G7`z40A57Io_du=_>BzB=uE7oX zqqo?rB6Y%^z02`!y6b5??pZ_+dn6uhP-L8Q=XZ;w#xtczNSQ#%RTd zo4FhIcQYBEP6ua{4(c{5qZ?`KZ98?H)Pm*?eJk^Jd{7y5p2bPN`I>(mM*yzXFB_ei zcVS@8J;=yJwQP!h)CYs&%NtE;Smoo&<6+mzpd4*aXBQVVJ_H74H4t7nC=Z$_wk$mrY_OLxooTHl< zDFAB~4xENx6HISV)00VA8fqW7_{5)(%irJ5Ik%-|8o#+c33Qv6}XQV3pk7!TOGHYVS2n~xwa}Sk~G#| zJbExW0g->~s)97q4xmFR5SW@UC~a>=I89gD$;%T$xdEDkO*lV8HUa?vBunb6TsN#= z)t?@zaUX3f1nNMA5mV;)CvGl8hm=(9`LC|O7?kD1%FA|39uhC2DRN`KL;=*ub7f@# z>o%S@Pntc2xojLm0#^k9gf>%m(6|GPjm}J` zo0Yw`Y?o1AnN+AQGQ>%u-^}?}XPWRwzmevS;)W=a@*lZBpK-3L`Rb?VGi*8RPm`p& z5{4CXFFZv;j5HZW3@0!1a7op(dY{t~gcV@Lu(%UMvJSGo`&HZ93ADQ3b-M$io;Hq& z-A&SABj87T*}HW)Uq>@|R|hu2g?oIA#-A4gg}+V!kF-?_2+KHqvYVUR7J69iapcM+ z0?&#FCc*?)bV9+m9MjeRd@5`ZW9%7CGtk>~K4TF~WFtBPBf4@P@s_@>z&!hcwU%=6 zF*XcPFD5?mX!R$xoiN-2zx8<{J_fJkWQ`y!HcKjYAtZ{5>9dXNxJ#Rf5j9JRDFU+< zD7PtXi#YB!bzIEqLb0)?Bm7A$J_G%E2jGS<$HuXz#?ZWCVna(Pw7Lvjez@HLK%Sd8 z!lM}&2S@$;-vjszy;OxEQ<3gu;JGRGUXp~k(O~Xe-q$$8>WMikKJzHrYsq!f?1Ln! z%pG*>)6!RLWRb^J)i-d`@fxVA@n*wYmKN&mFuxH;;J zAgw-7k|97>G^7;+0C#%CBC3I+csGcC$Cg9|U{40J6cT4e2o%eTu`&GlkvMV}i>j-& zWj2OEqZG^}0vh*c0x{iz&XOb))B>u22{R4E@QA%3+JeOpo4)J-UOPU^qOy__GRVgG zGaPrGXhkT3qVx{0v&CPn=0b|@@HWt4$q4h{uKnQWhTM}uETq}_1UlwY>->IOMn8fO z)l`MPb4_)vQ@{vGGZgijYKbulSly7+I#Z*U8rkmsUDNoYcv^DnLz$1MhsVCF`l!DX zpWfcq+)3%vDUpj?x^iyK({U3*a;)$fm1n0Nvt~Oy)yGe>d|fvH0Cm!G4AQnB%Bio0 z*vk=h#pq}NjL!X_W6kZ&#_Yp&?w;K%8{Xm53z@(c(GMKQ1B)Te(2mJ7&TUHCJM&X> z_5#>E1mjvRod5|Mig{ly@@0tC9o7>Df9YBU;r*~%LMK29mf367?YD=le>8I(LN%T- zR06T-A52DAU468FCg_62Hw&1hih+Hn4U{KR{~Ymv!O`O%Z%tt_pYDZCJv|k{90D?uSm;Yn@_Gn#9?$5+2cf79y6reXkz9gV zK1%&-%y3h@zI^0>YX;knQ@m_C zUT6P;nGMCcPbCWpB`cVFE4vH!1z3$8@6_ivP(V15J{Je=`VG!QhJt zs1bq!MaZkut78vO=Hry)m|7rerVwX%n91i|T znRPtgUB*YpSpdkOLSIs<4g-p42`>zy)$alSL2!MeNjtVQO}n3d*=x`Z$KNB2um)3= z+Q&mv2Naqtr*aw5=9=YMld9f9+z8$}ND!}H)Zg`rH5y-puTIPzo;z=QX=u>lwb?^K z1~fzW6wi~bjBpG&vLfPFrj`Y9ul%)~=&f8!rx}ltOQP&sIk8+CP5>a_8TmfcLLt=X ztWr1qnu$nBf9#6?MWTvSwb@;>%*E7C(j?J>9r!Ei22y@a= z3P-x8$GSZ8=nB`+NYd#T4h4TAS6r~TsW9m*SIGMT*bS-ebAmAwELkq=c zkZBkRj#I@tX{xX$$InF0WMW zSO5?M&*$>X^VCo2^LJ)e=G3@LG%tG*F&A?0T9*A=EEUby`6yEA&Y!Q-$fpFrfDbMD zqV__OttaLSPKH9bx-D(TEWo0p0$D9YCG}qfibl#=Ibxx_!eJ5967eBqXuFPtIRcX< z2(^;%Q?e(}JVpFg8Im_31l*^ZTZtNC$0i5)d!2 zafVcoIFS;HvgDG*1K85?#U%&cyly3cr|^v|xVbnpoKM7opx!b*q9nA6r#x+s6+oZ> z?kT5=OO^ug0RTH8k}AB?UJ@}L)N<_%7HOm@4S^F|B?@WDKmZjgfNF8An&Z7BE@=sD zo7wbx(>NE262#c5K4G&)4Pn0Wv#d?Vp4$efg>d!mKi9JeLZl8fGjFj_B2=duiY?=rT+p^e5>0Tz_ zTT})8U7yc$vrc-Z){t}5N=-5n<1VVbwJZDlTXbIyjn|OTJqV)Bf=D_!&iWs*JM6(Z z0$fwO+7c~s&GMrz@8!SOUoIXX4RT4~b<5jLxWbqCce54Hq+p56p;JXP`9~gWa%fdPa`IuAJaM3XQ7ox3~*8p4df1qZn z##vFXy)o2#g?{vAzwq^Yd15T_mZ!^*=SQ0Inp90Q%8RsWNvt{$NUpD!8zsE8#zVhO z4^eNS^$l{DIj<1zQ^DyXllLVhBBD6MKIf9b_vnmC!hMn}Jg0v=*A{mRjdZs1pL_B% z^dbw9z>#QazgexRZAJyHkF%{tG8}X8fkG66_QqL)5vttg}uLOlD}%Erp3oh>&Z zncFtwPCYS481!A}LYegn1nh-U`i?j)hZIT_WTJDW1(_iSpN)H?& z_d6Nz+dDVrJ$9H1WW5*<>yJ*D<`qjFZf9 z-Q1xpQ{)epIow|QZGPA#d$1LB`19z`Z}Y1``*~N74quu>qtATdwxOToZwP$6H^AmC zXMOSGP?um3^y<8=<%Tro<&_Yl3ES{XO11`}Z`G3A{>Wo;(?+=ucJ?w9^WC z6Z7mRT*>@QH>|4h!coxvwDjbbd8gOtaOly_^+Sepvdm~G6P5h$eUr%}^btPjXs7h( zH~Z;beuMCN^9*&X^V|Lx67E`j{g&JnzPs(Acy@QkT!zupFtriPxL}t^tG?+T6nwNl zeMI(tO2~~8?riPu;Rc5}5q`N?+EWUH1VDsu5g|cg!M{S0W1)!<@I%M!uNZPHmXe|b zf%tXc?k)&7E4VvIl+cPG((`eJgZQ;!ws6AHeYmw9Oy0#CWFi1G5R(uBi3$pt5zZ*M zxw!t%6Y`F5xb^=$qvvMl^gmB%!`$G`9w4#5Iw-g}djJA=5MdBHlrl1ZwHF7D2_q$G zPf}G0XiQK@7h&l^)SVy}BuM08?r_3c5WfoC(G%`rX9XjO6`ieItnHj_LHq`G&T`J~ zc7Fx`b|Zo+q#OOaMcgU*6UP%dAQOT)bwFmIf2k<(&y|FGkyKQGdB7Z9 zYzYE_Vcq{VQVkfO$1QI@gtLRQidHS>0Z+fWLC1O+Gs{`r7JArN5*$OiO}Ob{3n z;RAC1M`yL-UgJcyPR5t0xPq~zdG)Ka4SKcQF+ AKL7v# literal 44391 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 literal 43107 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%0ALAhtr$ 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 BBRK#7 diff --git a/python/tests/reference/Rotation/PoleFigures_OR.m b/python/tests/reference/Rotation/PoleFigures_OR.m index 74e1365b7..ede2a0e0c 100644 --- a/python/tests/reference/Rotation/PoleFigures_OR.m +++ b/python/tests/reference/Rotation/PoleFigures_OR.m @@ -19,7 +19,7 @@ rotation('FCC') = 'Active Rotation'; for lattice = lattice_types for p = 0:length(models)/3-1 - EBSD_data = {loadEBSD(strcat(lattice,'_',models{p*3+1},'.txt'),symmetry,'interface','generic',... + EBSD_data = {loadEBSD(strcat (lattice,'_',models{p*3+1},'.txt'),symmetry,'interface','generic',... 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', rotation(char(lattice))), loadEBSD(strcat(lattice,'_',models{p*3+2},'.txt'),symmetry,'interface','generic',... 'ColumnNames', { 'phi1' 'Phi' 'phi2' 'x' 'y'}, 'Bunge', rotation(char(lattice))), @@ -28,11 +28,11 @@ for lattice = lattice_types h = [Miller(1,0,0,symmetry{1}),Miller(1,1,0,symmetry{1}),Miller(1,1,1,symmetry{1})]; % 3 pole figures plotPDF(EBSD_data{1}.orientations,h,'MarkerSize',5,'MarkerColor','r','DisplayName',models{p*3+1}) hold on - plotPDF(EBSD_data{2}.orientations,h,'MarkerSize',5,'MarkerColor','b','DisplayName',models{p*3+2}) - plotPDF(EBSD_data{3}.orientations,h,'MarkerSize',5,'MarkerColor','g','DisplayName',models{p*3+3}) - legend('show','location','southoutside') + plotPDF(EBSD_data{2}.orientations,h,'MarkerSize',4,'MarkerColor','b','DisplayName',models{p*3+2}) + plotPDF(EBSD_data{3}.orientations,h,'MarkerSize',3,'MarkerColor','g','DisplayName',models{p*3+3}) + legend('show','location','southoutside','Interpreter', 'none') orient('landscape') print('-bestfit',strcat(int2str(p+1),'_',char(lattice),'.pdf'),'-dpdf') close end -end +end \ No newline at end of file From b662ca0acf72d4a6eac8c8587ff518d1edbe0704 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 13 Dec 2019 13:23:13 +0100 Subject: [PATCH 68/78] do not modify pdf files --- .gitattributes | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitattributes b/.gitattributes index 8d1f26a78..7a5c5bde5 100644 --- a/.gitattributes +++ b/.gitattributes @@ -3,8 +3,8 @@ # always use LF, even if the files are edited on windows, they need to be compiled/used on unix * text eol=lf -# Denote all files that are truly binary and should not be modified. +# Denote all files that are binary and should not be modified. *.png binary *.jpg binary -*.cae binary *.hdf5 binary +*.pdf binary From 57a69ad4c93ce54740097bd421e574e806d442c8 Mon Sep 17 00:00:00 2001 From: "f.basile" Date: Fri, 13 Dec 2019 13:32:16 +0100 Subject: [PATCH 69/78] Reupload PDF pole figures. --- python/tests/reference/Rotation/1_BCC.pdf | Bin 43263 -> 43264 bytes python/tests/reference/Rotation/1_FCC.pdf | Bin 43263 -> 43264 bytes python/tests/reference/Rotation/2_BCC.pdf | Bin 43017 -> 43017 bytes python/tests/reference/Rotation/2_FCC.pdf | Bin 43017 -> 43017 bytes .../tests/reference/Rotation/PoleFigures_OR.m | 2 +- 5 files changed, 1 insertion(+), 1 deletion(-) diff --git a/python/tests/reference/Rotation/1_BCC.pdf b/python/tests/reference/Rotation/1_BCC.pdf index 599b892105907e96d19f52b7d927dafda0500d7c..445f1d250fea234be7680d874b149e52bed42851 100644 GIT binary patch delta 97 zcmex=k*VPl(}YS^V`BqjlZ|y8{EWPt+xYosIvct;S-Kgx8oC;oTNoIb7`d4lyBQc5 X7?~TInmL)78`>$@5K=Pv#tL-+B;Xlw delta 95 zcmZp;#Pt6n(}YS^BNJmIIU1W=nwuD!n3qFW+rYHj&6=Ft|rE& Q29|aTHiVQ+ezaU20EpWdssI20 delta 90 zcmeCYz|?txX+kBdk%_U9*~U7><<3Tq#^#nr&gO~2CmK)&d!$3j!v!yrp~6OE^bB^rY6Q_KtVGD PCp!fjLP{n-TCNTNkZl;Z delta 90 zcmeCYz|?txX+kBdk%_Uf(Z)K(<<2ISrk0MT2Bwxy#x72dhDMgAj*f Date: Fri, 13 Dec 2019 14:20:18 +0100 Subject: [PATCH 70/78] Point based vtk file in DADF5 class --- python/damask/dadf5.py | 115 +++++++++++++++++++++++++++-------------- 1 file changed, 75 insertions(+), 40 deletions(-) diff --git a/python/damask/dadf5.py b/python/damask/dadf5.py index 1142d02b4..1f4af8de3 100644 --- a/python/damask/dadf5.py +++ b/python/damask/dadf5.py @@ -846,41 +846,58 @@ class DADF5(): pool.wait_completion() - def to_vtk(self,labels): + def to_vtk(self,labels,mode='Cell'): """ - Export to vtk cell data. + Export to vtk cell/point data. Parameters ---------- labels : list of str Labels of the datasets to be exported. + mode : str + Export in cell format or point format. + Default value is 'Cell' """ - if self.structured: + if mode=='Cell': - coordArray = [vtk.vtkDoubleArray(),vtk.vtkDoubleArray(),vtk.vtkDoubleArray()] - for dim in [0,1,2]: - for c in np.linspace(0,self.size[dim],1+self.grid[dim]): - coordArray[dim].InsertNextValue(c) - - grid = vtk.vtkRectilinearGrid() - grid.SetDimensions(*(self.grid+1)) - grid.SetXCoordinates(coordArray[0]) - grid.SetYCoordinates(coordArray[1]) - grid.SetZCoordinates(coordArray[2]) - - else: - - nodes = vtk.vtkPoints() - with h5py.File(self.fname) as f: - nodes.SetData(numpy_support.numpy_to_vtk(f['/geometry/x_n'][()],deep=True)) + if self.structured: + + coordArray = [vtk.vtkDoubleArray(),vtk.vtkDoubleArray(),vtk.vtkDoubleArray()] + for dim in [0,1,2]: + for c in np.linspace(0,self.size[dim],1+self.grid[dim]): + coordArray[dim].InsertNextValue(c) + + grid = vtk.vtkRectilinearGrid() + grid.SetDimensions(*(self.grid+1)) + grid.SetXCoordinates(coordArray[0]) + grid.SetYCoordinates(coordArray[1]) + grid.SetZCoordinates(coordArray[2]) + + else: - grid = vtk.vtkUnstructuredGrid() - grid.SetPoints(nodes) - grid.Allocate(f['/geometry/T_c'].shape[0]) - for i in f['/geometry/T_c']: - grid.InsertNextCell(vtk.VTK_HEXAHEDRON,8,i-1) # not for all elements! - + nodes = vtk.vtkPoints() + with h5py.File(self.fname) as f: + nodes.SetData(numpy_support.numpy_to_vtk(f['/geometry/x_n'][()],deep=True)) + + grid = vtk.vtkUnstructuredGrid() + grid.SetPoints(nodes) + grid.Allocate(f['/geometry/T_c'].shape[0]) + for i in f['/geometry/T_c']: + grid.InsertNextCell(vtk.VTK_HEXAHEDRON,8,i-1) # not for all elements! + else: + Points = vtk.vtkPoints() + Vertices = vtk.vtkCellArray() + for c in self.cell_coordinates(): + pointID = Points.InsertNextPoint(c) + Vertices.InsertNextCell(1) + Vertices.InsertCellPoint(pointID) + + Polydata = vtk.vtkPolyData() + Polydata.SetPoints(Points) + Polydata.SetVerts(Vertices) + Polydata.Modified() + N_digits = int(np.floor(np.log10(int(self.increments[-1][3:]))))+1 for i,inc in enumerate(self.iter_visible('increments')): @@ -900,7 +917,10 @@ class DADF5(): vtk_data.append(numpy_support.numpy_to_vtk(num_array=array.reshape(shape), deep=True,array_type= vtk.VTK_DOUBLE)) vtk_data[-1].SetName('1_'+x[0].split('/',1)[1]) #ToDo: hard coded 1! - grid.GetCellData().AddArray(vtk_data[-1]) + if mode=='Cell': + grid.GetCellData().AddArray(vtk_data[-1]) + else: + Polydata.GetCellData().AddArray(vtk_data[-1]) else: x = self.get_dataset_location(label) if len(x) == 0: @@ -912,9 +932,12 @@ class DADF5(): ph_name = re.compile(r'(\/[1-9])_([A-Z][a-z]*)_(([a-z]*)|([A-Z]*))') #looking for phase name in dataset name dset_name = '1_' + re.sub(ph_name,r'',x[0].split('/',1)[1]) #removing phase name from generic dataset vtk_data[-1].SetName(dset_name) - grid.GetCellData().AddArray(vtk_data[-1]) + if mode=='Cell': + grid.GetCellData().AddArray(vtk_data[-1]) + else: + Polydata.GetCellData().AddArray(vtk_data[-1]) self.set_visible('materialpoints',materialpoints_backup) - + constituents_backup = self.visible['constituents'].copy() self.set_visible('constituents',False) for label in labels: @@ -929,7 +952,10 @@ class DADF5(): vtk_data.append(numpy_support.numpy_to_vtk(num_array=array.reshape(shape), deep=True,array_type= vtk.VTK_DOUBLE)) vtk_data[-1].SetName('1_'+x[0].split('/',1)[1]) #ToDo: why 1_? - grid.GetCellData().AddArray(vtk_data[-1]) + if mode=='Cell': + grid.GetCellData().AddArray(vtk_data[-1]) + else: + Polydata.GetCellData().AddArray(vtk_data[-1]) else: x = self.get_dataset_location(label) if len(x) == 0: @@ -939,17 +965,23 @@ class DADF5(): vtk_data.append(numpy_support.numpy_to_vtk(num_array=array.reshape(shape), deep=True,array_type= vtk.VTK_DOUBLE)) vtk_data[-1].SetName('1_'+x[0].split('/',1)[1]) - grid.GetCellData().AddArray(vtk_data[-1]) + if mode=='Cell': + grid.GetCellData().AddArray(vtk_data[-1]) + else: + Polydata.GetCellData().AddArray(vtk_data[-1]) self.set_visible('constituents',constituents_backup) - - writer = vtk.vtkXMLRectilinearGridWriter() if self.structured else \ - vtk.vtkXMLUnstructuredGridWriter() + + if mode=='Cell': + writer = vtk.vtkXMLRectilinearGridWriter() if self.structured else \ + vtk.vtkXMLUnstructuredGridWriter() + x = self.get_dataset_location('u_n') + vtk_data.append(numpy_support.numpy_to_vtk(num_array=self.read_dataset(x,0), + deep=True,array_type=vtk.VTK_DOUBLE)) + vtk_data[-1].SetName('u') + grid.GetPointData().AddArray(vtk_data[-1]) + else: + writer = vtk.vtkXMLPolyDataWriter() - x = self.get_dataset_location('u_n') - vtk_data.append(numpy_support.numpy_to_vtk(num_array=self.read_dataset(x,0), - deep=True,array_type=vtk.VTK_DOUBLE)) - vtk_data[-1].SetName('u') - grid.GetPointData().AddArray(vtk_data[-1]) file_out = '{}_inc{}.{}'.format(os.path.splitext(os.path.basename(self.fname))[0], inc[3:].zfill(N_digits), @@ -958,6 +990,9 @@ class DADF5(): writer.SetCompressorTypeToZLib() writer.SetDataModeToBinary() writer.SetFileName(file_out) - writer.SetInputData(grid) - + if mode=='Cell': + writer.SetInputData(grid) + else: + writer.SetInputData(Polydata) + writer.Write() From e5448fc381b8524cfeaf7ea89e8a6423d6b62f80 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 13 Dec 2019 14:36:52 +0100 Subject: [PATCH 71/78] avoid code duplication --- python/damask/dadf5.py | 63 +++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 38 deletions(-) diff --git a/python/damask/dadf5.py b/python/damask/dadf5.py index 1f4af8de3..0f32b4b5e 100644 --- a/python/damask/dadf5.py +++ b/python/damask/dadf5.py @@ -854,9 +854,9 @@ class DADF5(): ---------- labels : list of str Labels of the datasets to be exported. - mode : str + mode : str, either 'Cell' or 'Point' Export in cell format or point format. - Default value is 'Cell' + Default value is 'Cell'. """ if mode=='Cell': @@ -868,11 +868,11 @@ class DADF5(): for c in np.linspace(0,self.size[dim],1+self.grid[dim]): coordArray[dim].InsertNextValue(c) - grid = vtk.vtkRectilinearGrid() - grid.SetDimensions(*(self.grid+1)) - grid.SetXCoordinates(coordArray[0]) - grid.SetYCoordinates(coordArray[1]) - grid.SetZCoordinates(coordArray[2]) + vtk_geom = vtk.vtkRectilinearGrid() + vtk_geom.SetDimensions(*(self.grid+1)) + vtk_geom.SetXCoordinates(coordArray[0]) + vtk_geom.SetYCoordinates(coordArray[1]) + vtk_geom.SetZCoordinates(coordArray[2]) else: @@ -880,12 +880,12 @@ class DADF5(): with h5py.File(self.fname) as f: nodes.SetData(numpy_support.numpy_to_vtk(f['/geometry/x_n'][()],deep=True)) - grid = vtk.vtkUnstructuredGrid() - grid.SetPoints(nodes) - grid.Allocate(f['/geometry/T_c'].shape[0]) + vtk_geom = vtk.vtkUnstructuredGrid() + vtk_geom.SetPoints(nodes) + vtk_geom.Allocate(f['/geometry/T_c'].shape[0]) for i in f['/geometry/T_c']: - grid.InsertNextCell(vtk.VTK_HEXAHEDRON,8,i-1) # not for all elements! - else: + vtk_geom.InsertNextCell(vtk.VTK_HEXAHEDRON,8,i-1) # not for all elements! + elif mode == 'Point': Points = vtk.vtkPoints() Vertices = vtk.vtkCellArray() for c in self.cell_coordinates(): @@ -893,10 +893,10 @@ class DADF5(): Vertices.InsertNextCell(1) Vertices.InsertCellPoint(pointID) - Polydata = vtk.vtkPolyData() - Polydata.SetPoints(Points) - Polydata.SetVerts(Vertices) - Polydata.Modified() + vtk_geom = vtk.vtkPolyData() + vtk_geom.SetPoints(Points) + vtk_geom.SetVerts(Vertices) + vtk_geom.Modified() N_digits = int(np.floor(np.log10(int(self.increments[-1][3:]))))+1 @@ -917,10 +917,8 @@ class DADF5(): vtk_data.append(numpy_support.numpy_to_vtk(num_array=array.reshape(shape), deep=True,array_type= vtk.VTK_DOUBLE)) vtk_data[-1].SetName('1_'+x[0].split('/',1)[1]) #ToDo: hard coded 1! - if mode=='Cell': - grid.GetCellData().AddArray(vtk_data[-1]) - else: - Polydata.GetCellData().AddArray(vtk_data[-1]) + vtk_geom.GetCellData().AddArray(vtk_data[-1]) + else: x = self.get_dataset_location(label) if len(x) == 0: @@ -932,10 +930,8 @@ class DADF5(): ph_name = re.compile(r'(\/[1-9])_([A-Z][a-z]*)_(([a-z]*)|([A-Z]*))') #looking for phase name in dataset name dset_name = '1_' + re.sub(ph_name,r'',x[0].split('/',1)[1]) #removing phase name from generic dataset vtk_data[-1].SetName(dset_name) - if mode=='Cell': - grid.GetCellData().AddArray(vtk_data[-1]) - else: - Polydata.GetCellData().AddArray(vtk_data[-1]) + vtk_geom.GetCellData().AddArray(vtk_data[-1]) + self.set_visible('materialpoints',materialpoints_backup) constituents_backup = self.visible['constituents'].copy() @@ -952,10 +948,7 @@ class DADF5(): vtk_data.append(numpy_support.numpy_to_vtk(num_array=array.reshape(shape), deep=True,array_type= vtk.VTK_DOUBLE)) vtk_data[-1].SetName('1_'+x[0].split('/',1)[1]) #ToDo: why 1_? - if mode=='Cell': - grid.GetCellData().AddArray(vtk_data[-1]) - else: - Polydata.GetCellData().AddArray(vtk_data[-1]) + vtk_geom.GetCellData().AddArray(vtk_data[-1]) else: x = self.get_dataset_location(label) if len(x) == 0: @@ -965,10 +958,7 @@ class DADF5(): vtk_data.append(numpy_support.numpy_to_vtk(num_array=array.reshape(shape), deep=True,array_type= vtk.VTK_DOUBLE)) vtk_data[-1].SetName('1_'+x[0].split('/',1)[1]) - if mode=='Cell': - grid.GetCellData().AddArray(vtk_data[-1]) - else: - Polydata.GetCellData().AddArray(vtk_data[-1]) + vtk_geom.GetCellData().AddArray(vtk_data[-1]) self.set_visible('constituents',constituents_backup) if mode=='Cell': @@ -978,8 +968,8 @@ class DADF5(): vtk_data.append(numpy_support.numpy_to_vtk(num_array=self.read_dataset(x,0), deep=True,array_type=vtk.VTK_DOUBLE)) vtk_data[-1].SetName('u') - grid.GetPointData().AddArray(vtk_data[-1]) - else: + vtk_geom.GetPointData().AddArray(vtk_data[-1]) + elif mode == 'Point': writer = vtk.vtkXMLPolyDataWriter() @@ -990,9 +980,6 @@ class DADF5(): writer.SetCompressorTypeToZLib() writer.SetDataModeToBinary() writer.SetFileName(file_out) - if mode=='Cell': - writer.SetInputData(grid) - else: - writer.SetInputData(Polydata) + writer.SetInputData(vtk_geom) writer.Write() From 5b376712ef80091a618b384cf723a8b02a927e8b Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Fri, 13 Dec 2019 14:39:10 +0100 Subject: [PATCH 72/78] bugfix: wrong coordinates --- python/damask/dadf5.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/damask/dadf5.py b/python/damask/dadf5.py index 0f32b4b5e..367d15f36 100644 --- a/python/damask/dadf5.py +++ b/python/damask/dadf5.py @@ -436,7 +436,7 @@ class DADF5(): np.linspace(delta[1],self.size[1]-delta[1],self.grid[1]), np.linspace(delta[0],self.size[0]-delta[0],self.grid[0]), ) - return np.concatenate((x[:,:,:,None],y[:,:,:,None],y[:,:,:,None]),axis = 3).reshape([np.product(self.grid),3]) + return np.concatenate((x[:,:,:,None],y[:,:,:,None],z[:,:,:,None]),axis = 3).reshape([np.product(self.grid),3]) else: with h5py.File(self.fname,'r') as f: return f['geometry/x_c'][()] From 2fb5ac652b0d9fa5d319a78c773bc052341be4d5 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Sat, 14 Dec 2019 14:02:16 +0100 Subject: [PATCH 73/78] use new keyword keywords should follow the symbols in formulas, not their description: "T" for temperature, not "temperature" "F" for deformation gradient, not "defgrad" --- PRIVATE | 2 +- examples/ConfigFiles/Homogenization_Thermal_Conduction.config | 2 +- examples/SpectralMethod/EshelbyInclusion/material.config | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/PRIVATE b/PRIVATE index a4a216604..62842dec1 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit a4a216604ca07f6391c209fa75b593c8e8a887e5 +Subproject commit 62842dec152d30213cc586852b0825ad264fb56b diff --git a/examples/ConfigFiles/Homogenization_Thermal_Conduction.config b/examples/ConfigFiles/Homogenization_Thermal_Conduction.config index 48ad9ddc6..36fc7ea6e 100644 --- a/examples/ConfigFiles/Homogenization_Thermal_Conduction.config +++ b/examples/ConfigFiles/Homogenization_Thermal_Conduction.config @@ -1,3 +1,3 @@ thermal conduction -initialT 300.0 +t0 270.0 (output) temperature diff --git a/examples/SpectralMethod/EshelbyInclusion/material.config b/examples/SpectralMethod/EshelbyInclusion/material.config index e002584b0..d1ea80964 100644 --- a/examples/SpectralMethod/EshelbyInclusion/material.config +++ b/examples/SpectralMethod/EshelbyInclusion/material.config @@ -6,7 +6,7 @@ mech none # isostrain 1 grain thermal adiabatic # thermal strain (stress) induced mass transport -initialT 300.0 +t0 330.0 (output) temperature #-------------------# From 898352e2220b4edcea864cc40a34095ad821d8f9 Mon Sep 17 00:00:00 2001 From: Test User Date: Sat, 14 Dec 2019 16:57:23 +0100 Subject: [PATCH 74/78] [skip ci] updated version information after successful test of v2.0.3-1255-ga6da8fdd --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 1439ed27c..dd4016408 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v2.0.3-1237-g5a2053cd +v2.0.3-1255-ga6da8fdd From 4469f2f8f0712202d8175a6e1ea3ceb3b05073e4 Mon Sep 17 00:00:00 2001 From: Vitesh Shah Date: Wed, 18 Dec 2019 10:14:19 +0100 Subject: [PATCH 75/78] More general regex --- processing/post/DADF5_vtk_cells.py | 2 +- processing/post/DADF5_vtk_points.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/processing/post/DADF5_vtk_cells.py b/processing/post/DADF5_vtk_cells.py index 9e8585773..b3afe939d 100755 --- a/processing/post/DADF5_vtk_cells.py +++ b/processing/post/DADF5_vtk_cells.py @@ -90,7 +90,7 @@ for filename in options.filenames: x = results.get_dataset_location(label) if len(x) == 0: continue - ph_name = re.compile(r'(\/[1-9])_([A-Z][a-z]*)_(([a-z]*)|([A-Z]*))') #looking for phase name in dataset name + ph_name = re.compile(r'(?<=(constituent\/))(.*?)(?=(generic))') #looking for phase name in dataset name array = results.read_dataset(x,0) shape = [array.shape[0],np.product(array.shape[1:])] vtk_data.append(numpy_support.numpy_to_vtk(num_array=array.reshape(shape),deep=True,array_type= vtk.VTK_DOUBLE)) diff --git a/processing/post/DADF5_vtk_points.py b/processing/post/DADF5_vtk_points.py index 908474336..925a73a5c 100755 --- a/processing/post/DADF5_vtk_points.py +++ b/processing/post/DADF5_vtk_points.py @@ -77,7 +77,7 @@ for filename in options.filenames: x = results.get_dataset_location(label) if len(x) == 0: continue - ph_name = re.compile(r'(\/[1-9])_([A-Z][a-z]*)_(([a-z]*)|([A-Z]*))') #looking for phase name in dataset name + ph_name = re.compile(r'(?<=(constituent\/))(.*?)(?=(generic))') #looking for phase name in dataset name array = results.read_dataset(x,0) shape = [array.shape[0],np.product(array.shape[1:])] vtk_data.append(numpy_support.numpy_to_vtk(num_array=array.reshape(shape),deep=True,array_type= vtk.VTK_DOUBLE)) From 3c42368f6681313a6efcd55afe9b145f1a5166a8 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Wed, 18 Dec 2019 11:29:13 +0100 Subject: [PATCH 76/78] also use newer regex --- python/damask/dadf5.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python/damask/dadf5.py b/python/damask/dadf5.py index 367d15f36..2b86cb5f0 100644 --- a/python/damask/dadf5.py +++ b/python/damask/dadf5.py @@ -833,7 +833,7 @@ class DADF5(): N_not_calculated = len(todo) while N_not_calculated > 0: result = results.get() - with h5py.File(self.fname,'a') as f: # write to file + with h5py.File(self.fname,'a') as f: # write to file dataset_out = f[result['group']].create_dataset(result['label'],data=result['data']) for k in result['meta'].keys(): dataset_out.attrs[k] = result['meta'][k].encode() @@ -927,8 +927,8 @@ class DADF5(): shape = [array.shape[0],np.product(array.shape[1:])] vtk_data.append(numpy_support.numpy_to_vtk(num_array=array.reshape(shape), deep=True,array_type= vtk.VTK_DOUBLE)) - ph_name = re.compile(r'(\/[1-9])_([A-Z][a-z]*)_(([a-z]*)|([A-Z]*))') #looking for phase name in dataset name - dset_name = '1_' + re.sub(ph_name,r'',x[0].split('/',1)[1]) #removing phase name from generic dataset + ph_name = re.compile(r'(?<=(constituent\/))(.*?)(?=(generic))') # identify phase name + dset_name = '1_' + re.sub(ph_name,r'',x[0].split('/',1)[1]) # removing phase name vtk_data[-1].SetName(dset_name) vtk_geom.GetCellData().AddArray(vtk_data[-1]) From 9d7248f8c49c62727194c33d66b7637a858ebcff Mon Sep 17 00:00:00 2001 From: Test User Date: Wed, 18 Dec 2019 22:10:38 +0100 Subject: [PATCH 77/78] [skip ci] updated version information after successful test of v2.0.3-1264-g80b559dc --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index dd4016408..005c93723 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v2.0.3-1255-ga6da8fdd +v2.0.3-1264-g80b559dc From 0fdc880e2cd51f693984f3195b4040762ac71229 Mon Sep 17 00:00:00 2001 From: Test User Date: Fri, 20 Dec 2019 14:10:21 +0100 Subject: [PATCH 78/78] [skip ci] updated version information after successful test of v2.0.3-1294-g034367fa --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 005c93723..287da9b11 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v2.0.3-1264-g80b559dc +v2.0.3-1294-g034367fa