def __init__(self, order, multipleSimulations, matricesDir): self.order = order self.alignStride = lambda name: True if multipleSimulations > 1: self.alignStride = lambda name: name.startswith('fP') transpose = multipleSimulations > 1 self.transpose = lambda name: transpose self.t = (lambda x: x[::-1]) if transpose else (lambda x: x) self.db = parseXMLMatrixFile('{}/matrices_{}.xml'.format( matricesDir, self.numberOf3DBasisFunctions()), transpose=self.transpose, alignStride=self.alignStride) clonesQP = {'v': ['evalAtQP'], 'vInv': ['projectQP']} self.db.update( parseXMLMatrixFile('{}/plasticity_ip_matrices_{}.xml'.format( matricesDir, order), clonesQP, transpose=self.transpose, alignStride=self.alignStride)) qShape = (self.numberOf3DBasisFunctions(), self.numberOfQuantities()) self.Q = OptionalDimTensor('Q', 's', multipleSimulations, 0, qShape, alignStride=True) self.I = OptionalDimTensor('I', 's', multipleSimulations, 0, qShape, alignStride=True) Aplusminus_spp = self.flux_solver_spp() self.AplusT = Tensor('AplusT', Aplusminus_spp.shape, spp=Aplusminus_spp) self.AminusT = Tensor('AminusT', Aplusminus_spp.shape, spp=Aplusminus_spp) Tshape = (self.numberOfExtendedQuantities(), self.numberOfExtendedQuantities()) trans_spp = self.transformation_spp() self.T = Tensor('T', trans_spp.shape, spp=trans_spp) trans_inv_spp = self.transformation_inv_spp() self.Tinv = Tensor('Tinv', trans_inv_spp.shape, spp=trans_inv_spp) godunov_spp = self.godunov_spp() self.QgodLocal = Tensor('QgodLocal', godunov_spp.shape, spp=godunov_spp) self.QgodNeighbor = Tensor('QgodNeighbor', godunov_spp.shape, spp=godunov_spp) self.oneSimToMultSim = Tensor('oneSimToMultSim', (self.Q.optSize(), ), spp={(i, ): '1.0' for i in range(self.Q.optSize())})
def __init__(self, order, multipleSimulations, matricesDir): self.order = order self.alignStride = lambda name: True if multipleSimulations > 1: self.alignStride = lambda name: name.startswith('fP') transpose = multipleSimulations > 1 self.transpose = lambda name: transpose self.t = (lambda x: x[::-1]) if transpose else (lambda x: x) self.db = parseXMLMatrixFile('{}/matrices_{}.xml'.format(matricesDir, self.numberOf3DBasisFunctions()), transpose=self.transpose, alignStride=self.alignStride) clonesQP = { 'v': [ 'evalAtQP' ], 'vInv': [ 'projectQP' ] } self.db.update( parseXMLMatrixFile('{}/plasticity_ip_matrices_{}.xml'.format(matricesDir, order), clonesQP, transpose=self.transpose, alignStride=self.alignStride)) qShape = (self.numberOf3DBasisFunctions(), self.numberOfQuantities()) self.Q = OptionalDimTensor('Q', 's', multipleSimulations, 0, qShape, alignStride=True) self.I = OptionalDimTensor('I', 's', multipleSimulations, 0, qShape, alignStride=True) Ashape = (self.numberOfQuantities(), self.numberOfExtendedQuantities()) self.AplusT = Tensor('AplusT', Ashape) self.AminusT = Tensor('AminusT', Ashape) Tshape = (self.numberOfExtendedQuantities(), self.numberOfExtendedQuantities()) self.T = Tensor('T', Tshape) QgodShape = (self.numberOfQuantities(), self.numberOfQuantities()) self.Tinv = Tensor('Tinv', QgodShape) self.QgodLocal = Tensor('QgodLocal', QgodShape) self.QgodNeighbor = Tensor('QgodNeighbor', QgodShape) self.oneSimToMultSim = Tensor('oneSimToMultSim', (self.Q.optSize(),), spp={(i,): '1.0' for i in range(self.Q.optSize())})
def __init__(self, order, multipleSimulations, matricesDir, memLayout, numberOfMechanisms): super().__init__(order, multipleSimulations, matricesDir) self.numberOfMechanisms = numberOfMechanisms clones = { 'star': ['star(0)', 'star(1)', 'star(2)'], } self.db.update( parseXMLMatrixFile('{}/matrices_viscoelastic.xml'.format(matricesDir), clones) ) memoryLayoutFromFile(memLayout, self.db, clones) self._qShapeExtended = (self.numberOf3DBasisFunctions(), self.numberOfExtendedQuantities()) self._qShapeAnelastic = (self.numberOf3DBasisFunctions(), self.numberOfAnelasticQuantities(), self.numberOfMechanisms) self.Qext = OptionalDimTensor('Qext', self.Q.optName(), self.Q.optSize(), self.Q.optPos(), self._qShapeExtended, alignStride=True) self.Qane = OptionalDimTensor('Qane', self.Q.optName(), self.Q.optSize(), self.Q.optPos(), self._qShapeAnelastic, alignStride=True) self.Iane = OptionalDimTensor('Iane', self.Q.optName(), self.Q.optSize(), self.Q.optPos(), self._qShapeAnelastic, alignStride=True) self.E = Tensor('E', (self.numberOfAnelasticQuantities(), self.numberOfMechanisms, self.numberOfQuantities())) self.w = Tensor('w', (self.numberOfMechanisms,)) self.W = Tensor('W', (self.numberOfMechanisms, self.numberOfMechanisms), np.eye(self.numberOfMechanisms, dtype=bool), CSCMemoryLayout) selectElaSpp = np.zeros((self.numberOfExtendedQuantities(), self.numberOfQuantities())) selectElaSpp[0:self.numberOfQuantities(),0:self.numberOfQuantities()] = np.eye(self.numberOfQuantities()) self.selectEla = Tensor('selectEla', (self.numberOfExtendedQuantities(), self.numberOfQuantities()), selectElaSpp, CSCMemoryLayout) selectAneSpp = np.zeros((self.numberOfExtendedQuantities(), self.numberOfAnelasticQuantities())) selectAneSpp[self.numberOfQuantities():self.numberOfExtendedQuantities(),0:self.numberOfAnelasticQuantities()] = np.eye(self.numberOfAnelasticQuantities()) self.selectAne = Tensor('selectAne', (self.numberOfExtendedQuantities(), self.numberOfAnelasticQuantities()), selectAneSpp, CSCMemoryLayout)
def addKernels(generator, aderdg, matricesDir, PlasticityMethod): # Load matrices db = parseXMLMatrixFile('{}/plasticity_{}_matrices_{}.xml'.format(matricesDir, PlasticityMethod, aderdg.order), clones=dict(), alignStride=aderdg.alignStride) numberOfNodes = db.v.shape()[0] sShape = (aderdg.numberOf3DBasisFunctions(), 6) QStress = OptionalDimTensor('QStress', aderdg.Q.optName(), aderdg.Q.optSize(), aderdg.Q.optPos(), sShape, alignStride=True) initialLoading = Tensor('initialLoading', (6,)) replicateIniLShape = (numberOfNodes,) replicateIniLSpp = np.ones(aderdg.Q.insertOptDim(replicateIniLShape, (aderdg.Q.optSize(),))) replicateInitialLoading = OptionalDimTensor('replicateInitialLoading', aderdg.Q.optName(), aderdg.Q.optSize(), aderdg.Q.optPos(), replicateIniLShape, spp=replicateIniLSpp, alignStride=True) iShape = (numberOfNodes, 6) QStressNodal = OptionalDimTensor('QStressNodal', aderdg.Q.optName(), aderdg.Q.optSize(), aderdg.Q.optPos(), iShape, alignStride=True) meanStress = OptionalDimTensor('meanStress', aderdg.Q.optName(), aderdg.Q.optSize(), aderdg.Q.optPos(), (numberOfNodes,), alignStride=True) secondInvariant = OptionalDimTensor('secondInvariant', aderdg.Q.optName(), aderdg.Q.optSize(), aderdg.Q.optPos(), (numberOfNodes,), alignStride=True) selectBulkAverage = Tensor('selectBulkAverage', (6,), spp={(i,): str(1.0/3.0) for i in range(3)}) selectBulkNegative = Tensor('selectBulkNegative', (6,), spp={(i,): '-1.0' for i in range(3)}) weightSecondInvariant = Tensor('weightSecondInvariant', (6,), spp={(i,): str(1.0/2.0) if i < 3 else '1.0' for i in range(6)}) yieldFactor = Tensor('yieldFactor', (numberOfNodes,)) generator.add('plConvertToNodal', QStressNodal['kp'] <= db.v['kl'] * QStress['lp'] + replicateInitialLoading['k'] * initialLoading['p']) generator.add('plComputeMean', meanStress['k'] <= QStressNodal['kq'] * selectBulkAverage['q']) generator.add('plSubtractMean', QStressNodal['kp'] <= QStressNodal['kp'] + meanStress['k'] * selectBulkNegative['p']) generator.add('plComputeSecondInvariant', secondInvariant['k'] <= QStressNodal['kq'] * QStressNodal['kq'] * weightSecondInvariant['q']) generator.add('plAdjustStresses', QStress['kp'] <= QStress['kp'] + db.vInv['kl'] * QStressNodal['lp'] * yieldFactor['l'])
def __init__(self, order, multipleSimulations, matricesDir, memLayout): super().__init__(order, multipleSimulations, matricesDir) clones = { 'star': ['star(0)', 'star(1)', 'star(2)'], } self.db.update( parseXMLMatrixFile('{}/star.xml'.format(matricesDir), clones) ) memoryLayoutFromFile(memLayout, self.db, clones)
def __init__(self, order, multipleSimulations, matricesDir, memLayout, numberOfMechanisms, **kwargs): super().__init__(order, multipleSimulations, matricesDir) clones = { 'star': ['star(0)', 'star(1)', 'star(2)'], } self.db.update( parseXMLMatrixFile( '{}/matrices_poroelastic.xml'.format(matricesDir), clones)) self.db.update( parseJSONMatrixFile('{}/stp_{}.json'.format(matricesDir, order), clones)) memoryLayoutFromFile(memLayout, self.db, clones)
def __init__(self, order, multipleSimulations, matricesDir, memLayout, numberOfMechanisms, **kwargs): self.numberOfMechanisms = numberOfMechanisms self.numberOfElasticQuantities = 9 super().__init__(order, multipleSimulations, matricesDir) clones = { 'star': ['star(0)', 'star(1)', 'star(2)'], } self.db.update( parseXMLMatrixFile( '{}/matrices_viscoelastic.xml'.format(matricesDir), clones)) star_spp = self.db.star[0].spp().as_ndarray() star_rows, star_cols = star_spp.shape aniso_cols = star_cols - self.numberOfElasticQuantities star_spp_new = np.zeros( (self.numberOfQuantities(), self.numberOfQuantities()), dtype=bool) star_spp_new[0:star_rows, 0:star_cols] = star_spp ''' The last 6 columns of star_spp contain the prototype sparsity pattern for a mechanism. Therefore, the spp is repeated for every mechanism. ''' for mech in range(1, numberOfMechanisms): offset0 = self.numberOfElasticQuantities offsetm = self.numberOfElasticQuantities + mech * aniso_cols star_spp_new[0:star_rows, offsetm:offsetm + aniso_cols] = star_spp[0:star_rows, offset0:offset0 + aniso_cols] for dim in range(3): self.db.star[dim] = Tensor(self.db.star[dim].name(), star_spp_new.shape, spp=star_spp_new) source_spp = np.zeros( (self.numberOfQuantities(), self.numberOfQuantities()), dtype=bool) ET_spp = self.db['ET'].spp().as_ndarray() ''' ET is a prototype sparsity pattern for a mechanism. Therefore, repeated for every mechanism. See Kaeser and Dumbser 2006, III. Viscoelastic attenuation. ''' for mech in range(numberOfMechanisms): offset = self.numberOfElasticQuantities + mech * aniso_cols r = slice(offset, offset + aniso_cols) source_spp[r, 0:aniso_cols] = ET_spp source_spp[r, r] = np.identity(aniso_cols, dtype=bool) self.db.ET = Tensor('ET', source_spp.shape, spp=source_spp) memoryLayoutFromFile(memLayout, self.db, clones)
def add(g): db = parseXMLMatrixFile('seissol_matrices.xml') Q = Tensor('Q', (8, 20, 15)) I = Tensor('I', (8, 20, 15)) g.add('seissol_stiffness', Q['skp'] <= db.kXiTDivM['lk'] * I['slq'] * db.star['qp']) # Reproduces recursive generation of zero blocks in Cauchy-Kowalevski prodedure, # described in "Sustained Petascale Performance of Seismic Simulations with SeisSol on SuperMUC", # Breuer et al., ISC 2014. dQ_shape = (20, 9) dQ0 = Tensor('dQ(0)', dQ_shape) star_ela = Tensor('star_ela', (9,9), spp=db.star['qp'].spp().as_ndarray()[0:9,0:9]) dQ_prev = dQ0 for i in range(1,4): derivativeSum = Add() for j in range(3): derivativeSum += db.kDivMT[j]['kl'] * dQ_prev['lq'] * star_ela['qp'] derivativeSum = DeduceIndices('kp').visit(derivativeSum) derivativeSum = EquivalentSparsityPattern().visit(derivativeSum) dQ = Tensor('dQ({})'.format(i), dQ_shape, spp=derivativeSum.eqspp()) g.add('derivative({})'.format(i), dQ['kp'] <= derivativeSum) dQ_prev = dQ
def __init__(self, order, multipleSimulations, matricesDir, memLayout, numberOfMechanisms, **kwargs): super().__init__(order, multipleSimulations, matricesDir) self.numberOfMechanisms = numberOfMechanisms clones = { 'star': ['star(0)', 'star(1)', 'star(2)'], } self.db.update( parseXMLMatrixFile('{}/matrices_viscoelastic.xml'.format(matricesDir), clones) ) memoryLayoutFromFile(memLayout, self.db, clones) self._qShapeExtended = (self.numberOf3DBasisFunctions(), self.numberOfExtendedQuantities()) self._qShapeAnelastic = (self.numberOf3DBasisFunctions(), self.numberOfAnelasticQuantities(), self.numberOfMechanisms) self.Qext = OptionalDimTensor('Qext', self.Q.optName(), self.Q.optSize(), self.Q.optPos(), self._qShapeExtended, alignStride=True) self.Qane = OptionalDimTensor('Qane', self.Q.optName(), self.Q.optSize(), self.Q.optPos(), self._qShapeAnelastic, alignStride=True) self.Iane = OptionalDimTensor('Iane', self.Q.optName(), self.Q.optSize(), self.Q.optPos(), self._qShapeAnelastic, alignStride=True) self.E = Tensor('E', (self.numberOfAnelasticQuantities(), self.numberOfMechanisms, self.numberOfQuantities())) self.w = Tensor('w', (self.numberOfMechanisms,)) self.W = Tensor('W', (self.numberOfMechanisms, self.numberOfMechanisms), np.eye(self.numberOfMechanisms, dtype=bool), CSCMemoryLayout) selectElaSpp = np.zeros((self.numberOfExtendedQuantities(), self.numberOfQuantities())) selectElaSpp[0:self.numberOfQuantities(),0:self.numberOfQuantities()] = np.eye(self.numberOfQuantities()) self.selectEla = Tensor('selectEla', (self.numberOfExtendedQuantities(), self.numberOfQuantities()), selectElaSpp, CSCMemoryLayout) selectAneSpp = np.zeros((self.numberOfExtendedQuantities(), self.numberOfAnelasticQuantities())) selectAneSpp[self.numberOfQuantities():self.numberOfExtendedQuantities(),0:self.numberOfAnelasticQuantities()] = np.eye(self.numberOfAnelasticQuantities()) self.selectAne = Tensor('selectAne', (self.numberOfExtendedQuantities(), self.numberOfAnelasticQuantities()), selectAneSpp, CSCMemoryLayout) self.db.update( parseJSONMatrixFile('{}/nodal/nodalBoundary_matrices_{}.json'.format(matricesDir, self.order), {}, alignStride=self.alignStride, transpose=self.transpose, namespace='nodal') )
def __init__(self, order, multipleSimulations, matricesDir): self.order = order self.alignStride = lambda name: True if multipleSimulations > 1: self.alignStride = lambda name: name.startswith('fP') transpose = multipleSimulations > 1 self.transpose = lambda name: transpose self.t = (lambda x: x[::-1]) if transpose else (lambda x: x) self.db = parseXMLMatrixFile('{}/matrices_{}.xml'.format( matricesDir, self.numberOf3DBasisFunctions()), transpose=self.transpose, alignStride=self.alignStride) clonesQP = {'v': ['evalAtQP'], 'vInv': ['projectQP']} self.db.update( parseXMLMatrixFile('{}/plasticity_ip_matrices_{}.xml'.format( matricesDir, order), clonesQP, transpose=self.transpose, alignStride=self.alignStride)) self.db.update( parseJSONMatrixFile( '{}/sampling_directions.json'.format(matricesDir))) self.db.update( parseJSONMatrixFile('{}/mass_{}.json'.format(matricesDir, order))) qShape = (self.numberOf3DBasisFunctions(), self.numberOfQuantities()) self.Q = OptionalDimTensor('Q', 's', multipleSimulations, 0, qShape, alignStride=True) self.I = OptionalDimTensor('I', 's', multipleSimulations, 0, qShape, alignStride=True) Aplusminus_spp = self.flux_solver_spp() self.AplusT = Tensor('AplusT', Aplusminus_spp.shape, spp=Aplusminus_spp) self.AminusT = Tensor('AminusT', Aplusminus_spp.shape, spp=Aplusminus_spp) Tshape = (self.numberOfExtendedQuantities(), self.numberOfExtendedQuantities()) trans_spp = self.transformation_spp() self.T = Tensor('T', trans_spp.shape, spp=trans_spp) trans_inv_spp = self.transformation_inv_spp() self.Tinv = Tensor('Tinv', trans_inv_spp.shape, spp=trans_inv_spp) godunov_spp = self.godunov_spp() self.QgodLocal = Tensor('QgodLocal', godunov_spp.shape, spp=godunov_spp) self.QgodNeighbor = Tensor('QgodNeighbor', godunov_spp.shape, spp=godunov_spp) self.oneSimToMultSim = Tensor('oneSimToMultSim', (self.Q.optSize(), ), spp={(i, ): '1.0' for i in range(self.Q.optSize())}) self.db.update( parseJSONMatrixFile( '{}/nodal/nodalBoundary_matrices_{}.json'.format( matricesDir, self.order), {}, alignStride=self.alignStride, transpose=self.transpose, namespace='nodal')) self.INodal = OptionalDimTensor( 'INodal', 's', False, #multipleSimulations, 0, (self.numberOf2DBasisFunctions(), self.numberOfQuantities()), alignStride=True) project2nFaceTo3m = tensor_collection_from_constant_expression( base_name='project2nFaceTo3m', expressions=lambda i: self.db.rDivM[i]['jk'] * self.db.V2nTo2m['kl' ], group_indices=range(4), target_indices='jl') self.db.update(project2nFaceTo3m)
def addKernels(generator, aderdg, matricesDir, PlasticityMethod, targets): # Load matrices db = parseXMLMatrixFile('{}/plasticity_{}_matrices_{}.xml'.format( matricesDir, PlasticityMethod, aderdg.order), clones=dict(), alignStride=aderdg.alignStride) numberOfNodes = aderdg.t(db.v.shape())[0] numberOf3DBasisFunctions = aderdg.numberOf3DBasisFunctions() sShape = (numberOf3DBasisFunctions, 6) QStress = OptionalDimTensor('QStress', aderdg.Q.optName(), aderdg.Q.optSize(), aderdg.Q.optPos(), sShape, alignStride=True) sShape_eta = (numberOf3DBasisFunctions, ) QEtaModal = OptionalDimTensor('QEtaModal', aderdg.Q.optName(), aderdg.Q.optSize(), aderdg.Q.optPos(), sShape_eta, alignStride=True) initialLoading = Tensor('initialLoading', (6, )) replicateIniLShape = (numberOfNodes, ) replicateIniLSpp = np.ones( aderdg.Q.insertOptDim(replicateIniLShape, (aderdg.Q.optSize(), ))) replicateInitialLoading = OptionalDimTensor('replicateInitialLoading', aderdg.Q.optName(), aderdg.Q.optSize(), aderdg.Q.optPos(), replicateIniLShape, spp=replicateIniLSpp, alignStride=True) iShape = (numberOfNodes, 6) QStressNodal = OptionalDimTensor('QStressNodal', aderdg.Q.optName(), aderdg.Q.optSize(), aderdg.Q.optPos(), iShape, alignStride=True) meanStress = OptionalDimTensor('meanStress', aderdg.Q.optName(), aderdg.Q.optSize(), aderdg.Q.optPos(), (numberOfNodes, ), alignStride=True) secondInvariant = OptionalDimTensor('secondInvariant', aderdg.Q.optName(), aderdg.Q.optSize(), aderdg.Q.optPos(), (numberOfNodes, ), alignStride=True) QEtaNodal = OptionalDimTensor('QEtaNodal', aderdg.Q.optName(), aderdg.Q.optSize(), aderdg.Q.optPos(), (numberOfNodes, ), alignStride=True) selectBulkAverage = Tensor('selectBulkAverage', (6, ), spp={(i, ): str(1.0 / 3.0) for i in range(3)}) selectBulkNegative = Tensor('selectBulkNegative', (6, ), spp={(i, ): '-1.0' for i in range(3)}) weightSecondInvariant = Tensor('weightSecondInvariant', (6, ), spp={(i, ): str(1.0 / 2.0) if i < 3 else '1.0' for i in range(6)}) yieldFactor = Tensor('yieldFactor', (numberOfNodes, )) generator.add( 'plConvertToNodal', QStressNodal['kp'] <= db.v[aderdg.t('kl')] * QStress['lp'] + replicateInitialLoading['k'] * initialLoading['p']) for target in targets: name_prefix = generate_kernel_name_prefix(target) generator.add( name=f'{name_prefix}plConvertToNodalNoLoading', ast=QStressNodal['kp'] <= db.v[aderdg.t('kl')] * QStress['lp'], target=target) generator.add( name=f'{name_prefix}plConvertEtaModal2Nodal', ast=QEtaNodal['k'] <= db.v[aderdg.t('kl')] * QEtaModal['l'], target=target) generator.add( name=f'{name_prefix}plConvertEtaNodal2Modal', ast=QEtaModal['k'] <= db.vInv[aderdg.t('kl')] * QEtaNodal['l'], target=target) generator.add( 'plComputeMean', meanStress['k'] <= QStressNodal['kq'] * selectBulkAverage['q']) generator.add( 'plSubtractMean', QStressNodal['kp'] <= QStressNodal['kp'] + meanStress['k'] * selectBulkNegative['p']) generator.add( 'plComputeSecondInvariant', secondInvariant['k'] <= QStressNodal['kq'] * QStressNodal['kq'] * weightSecondInvariant['q']) generator.add( 'plAdjustStresses', QStress['kp'] <= QStress['kp'] + db.vInv[aderdg.t('kl')] * QStressNodal['lp'] * yieldFactor['l']) gpu_target = 'gpu' if gpu_target in targets: name_prefix = generate_kernel_name_prefix(gpu_target) # suffix `M` stands for `Matrix` replicateInitialLoadingM = Tensor(name='replicateInitialLoadingM', shape=(numberOfNodes, 1), spp=np.ones((numberOfNodes, 1))) initialLoadingM = Tensor('initialLoadingM', (1, 6)) # Note: the last term was change on purpose because # GemmForge doesn't currently support tensor product operation convert_to_nodal = QStressNodal['kp'] <= \ db.v[aderdg.t('kl')] * QStress['lp'] + \ replicateInitialLoadingM['km'] * initialLoadingM['mp'] generator.add(name=f'{name_prefix}plConvertToNodal', ast=convert_to_nodal, target=gpu_target) generator.add(f'{name_prefix}plConvertToModal', QStress['kp'] <= QStress['kp'] + db.vInv[aderdg.t('kl')] * QStressNodal['lp'], target=gpu_target)