Beispiel #1
0
    def addLocal(self, generator, targets):
        for target in targets:
            name_prefix = generate_kernel_name_prefix(target)
            volumeSum = self.Q['kp']
            for i in range(3):
                volumeSum += self.db.kDivM[i][self.t(
                    'kl')] * self.I['lq'] * self.starMatrix(i)['qp']
            if self.sourceMatrix():
                volumeSum += self.I['kq'] * self.sourceMatrix()['qp']
            volume = (self.Q['kp'] <= volumeSum)
            generator.add(f'{name_prefix}volume', volume, target=target)

            localFlux = lambda i: self.Q['kp'] <= self.Q['kp'] + self.db.rDivM[
                i][self.t('km')] * self.db.fMrT[i][self.t('ml')] * self.I[
                    'lq'] * self.AplusT['qp']
            localFluxPrefetch = lambda i: self.I if i == 0 else (self.Q if i ==
                                                                 1 else None)
            generator.addFamily(f'{name_prefix}localFlux',
                                simpleParameterSpace(4),
                                localFlux,
                                localFluxPrefetch,
                                target=target)

            localFluxNodal = lambda i: self.Q['kp'] <= self.Q[
                'kp'] + self.db.project2nFaceTo3m[i]['kn'] * self.INodal[
                    'no'] * self.AminusT['op']
            localFluxNodalPrefetch = lambda i: self.I if i == 0 else (
                self.Q if i == 1 else None)
            generator.addFamily(f'{name_prefix}localFluxNodal',
                                simpleParameterSpace(4),
                                localFluxNodal,
                                localFluxNodalPrefetch,
                                target=target)
Beispiel #2
0
 def addNeighbor(self, generator, targets):
     for target in targets:
         name_prefix = generate_kernel_name_prefix(target)
         neighbourFlux = lambda h, j, i: self.Q['kp'] <= self.Q[
             'kp'] + self.db.rDivM[i][self.t('km')] * self.db.fP[h][self.t(
                 'mn')] * self.db.rT[j][self.t('nl')] * self.I[
                     'lq'] * self.AminusT['qp']
         neighbourFluxPrefetch = lambda h, j, i: self.I
         generator.addFamily(f'{name_prefix}neighboringFlux',
                             simpleParameterSpace(3, 4, 4),
                             neighbourFlux,
                             neighbourFluxPrefetch,
                             target=target)
Beispiel #3
0
    def addTime(self, generator, targets):
        for target in targets:
            name_prefix = generate_kernel_name_prefix(target)

            qShape = (self.numberOf3DBasisFunctions(),
                      self.numberOfQuantities())
            dQ0 = OptionalDimTensor('dQ(0)',
                                    self.Q.optName(),
                                    self.Q.optSize(),
                                    self.Q.optPos(),
                                    qShape,
                                    alignStride=True)
            power = Scalar('power')
            derivatives = [dQ0]
            generator.add(f'{name_prefix}derivativeTaylorExpansion(0)',
                          self.I['kp'] <= power * dQ0['kp'],
                          target=target)

            for i in range(1, self.order):
                derivativeSum = Add()
                if self.sourceMatrix():
                    derivativeSum += derivatives[-1]['kq'] * self.sourceMatrix(
                    )['qp']
                for j in range(3):
                    derivativeSum += self.db.kDivMT[j][self.t(
                        'kl')] * derivatives[-1]['lq'] * self.starMatrix(
                            j)['qp']

                derivativeSum = DeduceIndices(
                    self.Q['kp'].indices).visit(derivativeSum)
                derivativeSum = EquivalentSparsityPattern().visit(
                    derivativeSum)
                dQ = OptionalDimTensor('dQ({})'.format(i),
                                       self.Q.optName(),
                                       self.Q.optSize(),
                                       self.Q.optPos(),
                                       qShape,
                                       spp=derivativeSum.eqspp(),
                                       alignStride=True)

                generator.add(f'{name_prefix}derivative({i})',
                              dQ['kp'] <= derivativeSum,
                              target=target)
                generator.add(f'{name_prefix}derivativeTaylorExpansion({i})',
                              self.I['kp'] <= self.I['kp'] + power * dQ['kp'],
                              target=target)

                derivatives.append(dQ)
def addKernels(generator, aderdg, include_tensors, targets):
    maxDepth = 3

    numberOf3DBasisFunctions = aderdg.numberOf3DBasisFunctions()
    numberOf2DBasisFunctions = aderdg.numberOf2DBasisFunctions()
    numberOfQuantities = aderdg.numberOfQuantities()

    selectVelocitySpp = np.zeros((numberOfQuantities, 3))
    selectVelocitySpp[6:9, 0:3] = np.eye(3)
    selectVelocity = Tensor('selectVelocity', selectVelocitySpp.shape,
                            selectVelocitySpp, CSCMemoryLayout)

    faceDisplacement = OptionalDimTensor('faceDisplacement',
                                         aderdg.Q.optName(),
                                         aderdg.Q.optSize(),
                                         aderdg.Q.optPos(),
                                         (numberOf2DBasisFunctions, 3),
                                         alignStride=True)
    averageNormalDisplacement = OptionalDimTensor('averageNormalDisplacement',
                                                  aderdg.Q.optName(),
                                                  aderdg.Q.optSize(),
                                                  aderdg.Q.optPos(),
                                                  (numberOf2DBasisFunctions, ),
                                                  alignStride=True)

    include_tensors.add(averageNormalDisplacement)

    subTriangleDofs = [
        OptionalDimTensor('subTriangleDofs({})'.format(depth),
                          aderdg.Q.optName(),
                          aderdg.Q.optSize(),
                          aderdg.Q.optPos(), (4**depth, 3),
                          alignStride=True) for depth in range(maxDepth + 1)
    ]
    subTriangleProjection = [
        Tensor('subTriangleProjection({})'.format(depth),
               (4**depth, numberOf3DBasisFunctions),
               alignStride=True) for depth in range(maxDepth + 1)
    ]
    subTriangleProjectionFromFace = [
        Tensor('subTriangleProjectionFromFace({})'.format(depth),
               (4**depth, numberOf2DBasisFunctions),
               alignStride=True) for depth in range(maxDepth + 1)
    ]

    displacementRotationMatrix = Tensor('displacementRotationMatrix', (3, 3),
                                        alignStride=True)
    subTriangleDisplacement = lambda depth: subTriangleDofs[depth]['kp'] <= \
                                            subTriangleProjectionFromFace[depth]['kl'] * aderdg.db.MV2nTo2m['lm'] * faceDisplacement['mp']
    subTriangleVelocity = lambda depth: subTriangleDofs[depth][
        'kp'] <= subTriangleProjection[depth]['kl'] * aderdg.Q[
            'lq'] * selectVelocity['qp']

    generator.addFamily('subTriangleDisplacement',
                        simpleParameterSpace(maxDepth + 1),
                        subTriangleDisplacement)
    generator.addFamily('subTriangleVelocity',
                        simpleParameterSpace(maxDepth + 1),
                        subTriangleVelocity)

    rotatedFaceDisplacement = OptionalDimTensor('rotatedFaceDisplacement',
                                                aderdg.Q.optName(),
                                                aderdg.Q.optSize(),
                                                aderdg.Q.optPos(),
                                                (numberOf2DBasisFunctions, 3),
                                                alignStride=True)
    generator.add(
        'rotateFaceDisplacement', rotatedFaceDisplacement["mp"] <=
        faceDisplacement['mn'] * displacementRotationMatrix['pn'])

    addVelocity = lambda f: faceDisplacement['kp'] <= faceDisplacement['kp'] \
                            + aderdg.db.V3mTo2nFace[f]['kl'] * aderdg.I['lq'] * selectVelocity['qp']
    generator.addFamily('addVelocity', simpleParameterSpace(4), addVelocity)

    if 'gpu' in targets:
        name_prefix = generate_kernel_name_prefix(target='gpu')

        integratedVelocities = OptionalDimTensor('integratedVelocities',
                                                 aderdg.I.optName(),
                                                 aderdg.I.optSize(),
                                                 aderdg.I.optPos(),
                                                 (numberOf3DBasisFunctions, 3),
                                                 alignStride=True)

        addVelocity = lambda f: faceDisplacement['kp'] <= faceDisplacement['kp'] \
                                + aderdg.db.V3mTo2nFace[f]['kl'] * integratedVelocities['lp']

        generator.addFamily(f'{name_prefix}addVelocity',
                            simpleParameterSpace(4),
                            addVelocity,
                            target='gpu')
Beispiel #5
0
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)