Пример #1
0
  def addTime(self, generator):
    qShape = (self.numberOf3DBasisFunctions(), self.numberOfQuantities())
    dQ = [OptionalDimTensor('dQ({})'.format(d), self.Q.optName(), self.Q.optSize(), self.Q.optPos(), qShape, alignStride=True) for d in range(self.order)]
    dQext = [OptionalDimTensor('dQext({})'.format(d), self.Q.optName(), self.Q.optSize(), self.Q.optPos(), self._qShapeExtended, alignStride=True) for d in range(self.order)]
    dQane = [OptionalDimTensor('dQane({})'.format(d), self.Q.optName(), self.Q.optSize(), self.Q.optPos(), self._qShapeAnelastic, alignStride=True) for d in range(self.order)]

    power = Scalar('power')

    derivativeTaylorExpansionEla = lambda d: (self.I['kp'] <= self.I['kp'] + power * dQ[d]['kp']) if d > 0 else (self.I['kp'] <= power * dQ[0]['kp'])
    derivativeTaylorExpansionAne = lambda d: (self.Iane['kpm'] <= self.Iane['kpm'] + power * dQane[d]['kpm']) if d > 0 else (self.Iane['kpm'] <= power * dQane[0]['kpm'])

    def derivative(kthDer):
      derivativeSum = Add()
      for j in range(3):
        derivativeSum += self.db.kDivMT[j][self.t('kl')] * dQ[kthDer-1]['lq'] * self.db.star[j]['qp']
      return derivativeSum

    generator.addFamily('derivative', parameterSpaceFromRanges(range(1,self.order)), lambda d: [
      dQext[d]['kp'] <= derivative(d),
      dQ[d]['kp'] <= dQext[d]['kq'] * self.selectEla['qp'] + dQane[d-1]['kqm'] * self.E['qmp'],
      dQane[d]['kpm'] <= self.w['m'] * dQext[d]['kq'] * self.selectAne['qp'] + dQane[d-1]['kpl'] * self.W['lm']
    ])
    generator.addFamily('derivativeTaylorExpansion', simpleParameterSpace(self.order), lambda d: [
      derivativeTaylorExpansionEla(d),
      derivativeTaylorExpansionAne(d)
    ])
    generator.addFamily('derivativeTaylorExpansionEla', simpleParameterSpace(self.order), derivativeTaylorExpansionEla)
Пример #2
0
  def addTime(self, generator):
    qShape = (self.numberOf3DBasisFunctions(), self.numberOfQuantities())
    dQ = [OptionalDimTensor('dQ({})'.format(d), self.Q.optName(), self.Q.optSize(), self.Q.optPos(), qShape, alignStride=True) for d in range(self.order)]
    dQext = [OptionalDimTensor('dQext({})'.format(d), self.Q.optName(), self.Q.optSize(), self.Q.optPos(), self._qShapeExtended, alignStride=True) for d in range(self.order)]
    dQane = [OptionalDimTensor('dQane({})'.format(d), self.Q.optName(), self.Q.optSize(), self.Q.optPos(), self._qShapeAnelastic, alignStride=True) for d in range(self.order)]

    power = Scalar('power')

    derivativeTaylorExpansionEla = lambda d: (self.I['kp'] <= self.I['kp'] + power * dQ[d]['kp']) if d > 0 else (self.I['kp'] <= power * dQ[0]['kp'])
    derivativeTaylorExpansionAne = lambda d: (self.Iane['kpm'] <= self.Iane['kpm'] + power * dQane[d]['kpm']) if d > 0 else (self.Iane['kpm'] <= power * dQane[0]['kpm'])

    def derivative(kthDer):
      derivativeSum = Add()
      for j in range(3):
        derivativeSum += self.db.kDivMT[j][self.t('kl')] * dQ[kthDer-1]['lq'] * self.db.star[j]['qp']
      return derivativeSum

    generator.addFamily('derivative', parameterSpaceFromRanges(range(1,self.order)), lambda d: [
      dQext[d]['kp'] <= derivative(d),
      dQ[d]['kp'] <= dQext[d]['kq'] * self.selectEla['qp'] + dQane[d-1]['kqm'] * self.E['qmp'],
      dQane[d]['kpm'] <= self.w['m'] * dQext[d]['kq'] * self.selectAne['qp'] + dQane[d-1]['kpl'] * self.W['lm']
    ])
    generator.addFamily('derivativeTaylorExpansion', simpleParameterSpace(self.order), lambda d: [
      derivativeTaylorExpansionEla(d),
      derivativeTaylorExpansionAne(d)
    ])
    generator.addFamily('derivativeTaylorExpansionEla', simpleParameterSpace(self.order), derivativeTaylorExpansionEla)
Пример #3
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)
Пример #4
0
def addKernels(generator, aderdg, include_tensors, matricesDir, dynamicRuptureMethod):
    easi_ident_map = np.stack([np.eye(aderdg.numberOfQuantities())] * aderdg.numberOf2DBasisFunctions(), axis=2)
    assert(easi_ident_map.shape ==
           (aderdg.numberOfQuantities(), aderdg.numberOfQuantities(), aderdg.numberOf2DBasisFunctions()))
    easi_ident_map = Tensor('easiIdentMap',
                            easi_ident_map.shape,
                            easi_ident_map,
                            alignStride=False)
    easi_boundary_constant = Tensor('easiBoundaryConstant',
                                    (aderdg.numberOfQuantities(), aderdg.numberOf2DBasisFunctions()),
                                    alignStride=False)
    easi_boundary_map = Tensor('easiBoundaryMap',
                               (aderdg.numberOfQuantities(), aderdg.numberOfQuantities(), aderdg.numberOf2DBasisFunctions(),),
                               alignStride=False)
    create_easi_boundary_ghost_cells = (
            aderdg.INodal['la'] <= easi_boundary_map['abl'] * aderdg.INodal['lb'] + easi_ident_map['abl'] * easi_boundary_constant['bl']
    )
    generator.add('createEasiBoundaryGhostCells', create_easi_boundary_ghost_cells)

    projectToNodalBoundary = lambda j: aderdg.INodal['kp'] <= aderdg.db.V3mTo2nFace[j]['km'] * aderdg.I['mp']

    generator.addFamily('projectToNodalBoundary',
                        simpleParameterSpace(4),
                        projectToNodalBoundary)

    projectToNodalBoundaryRotated = lambda j: aderdg.INodal['kp'] <= aderdg.db.V3mTo2nFace[j]['kl'] \
                                              * aderdg.I['lm'] \
                                              * aderdg.Tinv['pm']

    generator.addFamily('projectToNodalBoundaryRotated',
                        simpleParameterSpace(4),
                        projectToNodalBoundaryRotated)

    # To be used as Tinv in flux solver - this way we can save two rotations for
    # Dirichlet boundary, as ghost cell dofs are already rotated
    identity_rotation = np.double(aderdg.transformation_spp())
    identity_rotation[0:9, 0:9] = np.eye(9)
    identity_rotation = Tensor('identityT',
                               aderdg.transformation_spp().shape,
                               identity_rotation,
                               )
    include_tensors.add(identity_rotation)

    aderdg.INodalUpdate = OptionalDimTensor('INodalUpdate',
                                          aderdg.INodal.optName(),
                                          aderdg.INodal.optSize(),
                                          aderdg.INodal.optPos(),
                                          (aderdg.numberOf2DBasisFunctions(), aderdg.numberOfQuantities()),
                                          alignStride=True)

    factor = Scalar('factor')
    updateINodal = aderdg.INodal['kp'] <= aderdg.INodal['kp'] + factor * aderdg.INodalUpdate['kp']
    generator.add('updateINodal', updateINodal)
Пример #5
0
 def addNeighbor(self, generator):
     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('neighboringFlux', simpleParameterSpace(3, 4, 4),
                         neighbourFlux, neighbourFluxPrefetch)
Пример #6
0
def addKernels(generator, aderdg):
    maxDepth = 3

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

    displacement = OptionalDimTensor('displacement',
                                     aderdg.Q.optName(),
                                     aderdg.Q.optSize(),
                                     aderdg.Q.optPos(),
                                     (numberOf3DBasisFunctions, 3),
                                     alignStride=True)
    generator.add(
        'addVelocity', displacement['kp'] <=
        displacement['kp'] + aderdg.I['kq'] * selectVelocity['qp'])

    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)
    ]

    subTriangleDisplacement = lambda depth: subTriangleDofs[depth][
        'kp'] <= subTriangleProjection[depth]['kl'] * displacement['lp']
    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)
Пример #7
0
  def addNeighbor(self, generator):
    neighbourFluxExt = lambda h,j,i: self.Qext['kp'] <= self.Qext['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']
    neighbourFluxExtPrefetch = lambda h,j,i: self.I
    generator.addFamily('neighbourFluxExt', simpleParameterSpace(3,4,4), neighbourFluxExt, neighbourFluxExtPrefetch)

    generator.add('neighbour', [
      self.Qane['kpm'] <= self.Qane['kpm'] + self.w['m'] * self.Qext['kq'] * self.selectAne['qp'],
      self.Q['kp'] <= self.Q['kp'] + self.Qext['kq'] * self.selectEla['qp']
    ])
Пример #8
0
  def addNeighbor(self, generator):
    neighbourFluxExt = lambda h,j,i: self.Qext['kp'] <= self.Qext['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']
    neighbourFluxExtPrefetch = lambda h,j,i: self.I
    generator.addFamily('neighbourFluxExt', simpleParameterSpace(3,4,4), neighbourFluxExt, neighbourFluxExtPrefetch)

    generator.add('neighbour', [
      self.Qane['kpm'] <= self.Qane['kpm'] + self.w['m'] * self.Qext['kq'] * self.selectAne['qp'],
      self.Q['kp'] <= self.Q['kp'] + self.Qext['kq'] * self.selectEla['qp']
    ])
Пример #9
0
  def addLocal(self, generator):
    volumeSum = self.Q['kp']
    for i in range(3):
      volumeSum += self.db.kDivM[i][self.t('kl')] * self.I['lq'] * self.db.star[i]['qp']
    volume = (self.Q['kp'] <= volumeSum)
    generator.add('volume', volume)

    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('localFlux', simpleParameterSpace(4), localFlux, localFluxPrefetch)
Пример #10
0
def addKernels(generator, aderdg, matricesDir, dynamicRuptureMethod):
  if dynamicRuptureMethod == 'quadrature':
    numberOfPoints = (aderdg.order+1)**2
  elif dynamicRuptureMethod == 'cellaverage':
    numberOfPoints = int(4**math.ceil(math.log(aderdg.order*(aderdg.order+1)/2,4)))
  else:
    raise ValueError('Unknown dynamic rupture method.')

  clones = dict()

  # Load matrices
  db = parseJSONMatrixFile('{}/dr_{}_matrices_{}.json'.format(matricesDir, dynamicRuptureMethod, aderdg.order), clones, alignStride=aderdg.alignStride, transpose=aderdg.transpose)

  # Determine matrices
  # Note: This does only work because the flux does not depend on the mechanisms in the case of viscoelastic attenuation
  godShape = (aderdg.numberOfQuantities(), aderdg.numberOfQuantities())
  godunovMatrix = Tensor('godunovMatrix', godShape)
  fluxSolverShape = (aderdg.numberOfQuantities(), aderdg.numberOfExtendedQuantities())
  fluxSolver    = Tensor('fluxSolver', fluxSolverShape)
  
  gShape = (numberOfPoints, aderdg.numberOfQuantities())
  godunovState = OptionalDimTensor('godunovState', aderdg.Q.optName(), aderdg.Q.optSize(), aderdg.Q.optPos(), gShape, alignStride=True)

  generator.add('rotateGodunovStateLocal', godunovMatrix['qp'] <= aderdg.Tinv['kq'] * aderdg.QgodLocal['kp'])
  generator.add('rotateGodunovStateNeighbor', godunovMatrix['qp'] <= aderdg.Tinv['kq'] * aderdg.QgodNeighbor['kp'])

  fluxScale = Scalar('fluxScale')
  generator.add('rotateFluxMatrix', fluxSolver['qp'] <= fluxScale * aderdg.starMatrix(0)['qk'] * aderdg.T['pk'])

  def godunovStateGenerator(i,h):
    target = godunovState['kp']
    term = db.V3mTo2n[i,h][aderdg.t('kl')] * aderdg.Q['lq'] * godunovMatrix['qp']
    if h == 0:
      return target <= term
    return target <= target + term
  godunovStatePrefetch = lambda i,h: godunovState
  generator.addFamily('godunovState', simpleParameterSpace(4,4), godunovStateGenerator, godunovStatePrefetch)

  nodalFluxGenerator = lambda i,h: aderdg.extendedQTensor()['kp'] <= aderdg.extendedQTensor()['kp'] + db.V3mTo2nTWDivM[i,h][aderdg.t('kl')] * godunovState['lq'] * fluxSolver['qp']
  nodalFluxPrefetch = lambda i,h: aderdg.I
  generator.addFamily('nodalFlux', simpleParameterSpace(4,4), nodalFluxGenerator, nodalFluxPrefetch)
Пример #11
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)
Пример #12
0
  def addLocal(self, generator):
    volumeSum = Add()
    for i in range(3):
      volumeSum += self.db.kDivM[i][self.t('kl')] * self.I['lq'] * self.db.star[i]['qp']
    volumeExt = (self.Qext['kp'] <= volumeSum)
    generator.add('volumeExt', volumeExt)

    localFluxExt = lambda i: self.Qext['kp'] <= self.Qext['kp'] + self.db.rDivM[i][self.t('km')] * self.db.fMrT[i][self.t('ml')] * self.I['lq'] * self.AplusT['qp']
    localFluxExtPrefetch = lambda i: self.I if i == 0 else (self.Q if i == 1 else None)
    generator.addFamily('localFluxExt', simpleParameterSpace(4), localFluxExt, localFluxExtPrefetch)

    generator.add('local', [
      self.Qane['kpm'] <= self.Qane['kpm'] + self.w['m'] * self.Qext['kq'] * self.selectAne['qp'] + self.Iane['kpl'] * self.W['lm'],
      self.Q['kp'] <= self.Q['kp'] + self.Qext['kq'] * self.selectEla['qp'] + self.Iane['kqm'] * self.E['qmp']
    ])
Пример #13
0
  def addLocal(self, generator):
    volumeSum = Add()
    for i in range(3):
      volumeSum += self.db.kDivM[i][self.t('kl')] * self.I['lq'] * self.db.star[i]['qp']
    volumeExt = (self.Qext['kp'] <= volumeSum)
    generator.add('volumeExt', volumeExt)

    localFluxExt = lambda i: self.Qext['kp'] <= self.Qext['kp'] + self.db.rDivM[i][self.t('km')] * self.db.fMrT[i][self.t('ml')] * self.I['lq'] * self.AplusT['qp']
    localFluxExtPrefetch = lambda i: self.I if i == 0 else (self.Q if i == 1 else None)
    generator.addFamily('localFluxExt', simpleParameterSpace(4), localFluxExt, localFluxExtPrefetch)

    generator.add('local', [
      self.Qane['kpm'] <= self.Qane['kpm'] + self.w['m'] * self.Qext['kq'] * self.selectAne['qp'] + self.Iane['kpl'] * self.W['lm'],
      self.Q['kp'] <= self.Q['kp'] + self.Qext['kq'] * self.selectEla['qp'] + self.Iane['kqm'] * self.E['qmp']
    ])
Пример #14
0
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')
Пример #15
0
def addKernels(generator, aderdg, matricesDir, dynamicRuptureMethod):
    if dynamicRuptureMethod == 'quadrature':
        numberOfPoints = (aderdg.order + 1)**2
    elif dynamicRuptureMethod == 'cellaverage':
        numberOfPoints = int(4**math.ceil(
            math.log(aderdg.order * (aderdg.order + 1) / 2, 4)))
    else:
        raise ValueError('Unknown dynamic rupture method.')

    clones = dict()

    # Load matrices
    db = parseJSONMatrixFile('{}/dr_{}_matrices_{}.json'.format(
        matricesDir, dynamicRuptureMethod, aderdg.order),
                             clones,
                             alignStride=aderdg.alignStride,
                             transpose=aderdg.transpose)
    db.update(
        parseJSONMatrixFile('{}/resample_{}.json'.format(
            matricesDir, aderdg.order)))

    # Determine matrices
    # Note: This does only work because the flux does not depend on the mechanisms in the case of viscoelastic attenuation
    trans_inv_spp_T = aderdg.transformation_inv_spp().transpose()
    TinvT = Tensor('TinvT', trans_inv_spp_T.shape, spp=trans_inv_spp_T)
    flux_solver_spp = aderdg.flux_solver_spp()
    fluxSolver = Tensor('fluxSolver',
                        flux_solver_spp.shape,
                        spp=flux_solver_spp)

    gShape = (numberOfPoints, aderdg.numberOfQuantities())
    QInterpolated = OptionalDimTensor('QInterpolated',
                                      aderdg.Q.optName(),
                                      aderdg.Q.optSize(),
                                      aderdg.Q.optPos(),
                                      gShape,
                                      alignStride=True)

    generator.add('transposeTinv', TinvT['ij'] <= aderdg.Tinv['ji'])

    fluxScale = Scalar('fluxScale')
    generator.add(
        'rotateFluxMatrix', fluxSolver['qp'] <=
        fluxScale * aderdg.starMatrix(0)['qk'] * aderdg.T['pk'])

    def interpolateQGenerator(i, h):
        return QInterpolated['kp'] <= db.V3mTo2n[i, h][aderdg.t(
            'kl')] * aderdg.Q['lq'] * TinvT['qp']

    interpolateQPrefetch = lambda i, h: QInterpolated
    generator.addFamily('evaluateAndRotateQAtInterpolationPoints',
                        simpleParameterSpace(4, 4), interpolateQGenerator,
                        interpolateQPrefetch)

    nodalFluxGenerator = lambda i, h: aderdg.extendedQTensor()[
        'kp'] <= aderdg.extendedQTensor()['kp'] + db.V3mTo2nTWDivM[i, h][
            aderdg.t('kl')] * QInterpolated['lq'] * fluxSolver['qp']
    nodalFluxPrefetch = lambda i, h: aderdg.I
    generator.addFamily('nodalFlux', simpleParameterSpace(4, 4),
                        nodalFluxGenerator, nodalFluxPrefetch)

    return {db.resample}
Пример #16
0
def addKernels(generator, aderdg, include_tensors, matricesDir, dynamicRuptureMethod):
    easi_ident_map = np.stack([np.eye(aderdg.numberOfQuantities())] * aderdg.numberOf2DBasisFunctions(), axis=2)
    assert(easi_ident_map.shape ==
           (aderdg.numberOfQuantities(), aderdg.numberOfQuantities(), aderdg.numberOf2DBasisFunctions()))
    easi_ident_map = Tensor('easiIdentMap',
                            easi_ident_map.shape,
                            easi_ident_map,
                            alignStride=False)
    easi_boundary_constant = Tensor('easiBoundaryConstant',
                                    (aderdg.numberOfQuantities(), aderdg.numberOf2DBasisFunctions()),
                                    alignStride=False)
    easi_boundary_map = Tensor('easiBoundaryMap',
                               (aderdg.numberOfQuantities(), aderdg.numberOfQuantities(), aderdg.numberOf2DBasisFunctions(),),
                               alignStride=False)
    create_easi_boundary_ghost_cells = (
            aderdg.INodal['la'] <= easi_boundary_map['abl'] * aderdg.INodal['lb'] + easi_ident_map['abl'] * easi_boundary_constant['bl']
    )
    generator.add('createEasiBoundaryGhostCells', create_easi_boundary_ghost_cells)

    projectToNodalBoundary = lambda j: aderdg.INodal['kp'] <= aderdg.db.V3mTo2nFace[j]['km'] * aderdg.I['mp']

    generator.addFamily('projectToNodalBoundary',
                        simpleParameterSpace(4),
                        projectToNodalBoundary)

    projectToNodalBoundaryRotated = lambda j: aderdg.INodal['kp'] <= aderdg.db.V3mTo2nFace[j]['kl'] \
                                              * aderdg.I['lm'] \
                                              * aderdg.Tinv['pm']

    generator.addFamily('projectToNodalBoundaryRotated',
                        simpleParameterSpace(4),
                        projectToNodalBoundaryRotated)

    # To be used as Tinv in flux solver - this way we can save two rotations for
    # Dirichlet boundary, as ghost cell dofs are already rotated
    identity_rotation = np.double(aderdg.transformation_spp())
    identity_rotation[0:9, 0:9] = np.eye(9)
    identity_rotation = Tensor('identityT',
                               aderdg.transformation_spp().shape,
                               identity_rotation,
                               )
    include_tensors.add(identity_rotation)

    project2nFaceTo3m = tensor_collection_from_constant_expression(
        base_name='project2nFaceTo3m',
        expressions=lambda i: aderdg.db.rDivM[i]['jk'] * aderdg.db.V2nTo2m['kl'],
        group_indices=range(4),
        target_indices='jl')

    aderdg.db.update(project2nFaceTo3m)

    selectZDisplacementFromQuantities = np.zeros(aderdg.numberOfQuantities())
    selectZDisplacementFromQuantities[8] = 1
    selectZDisplacementFromQuantities= Tensor('selectZDisplacementFromQuantities',
                                              selectZDisplacementFromQuantities.shape,
                                              selectZDisplacementFromQuantities,
                                              )

    selectZDisplacementFromDisplacements = np.zeros(3)
    selectZDisplacementFromDisplacements[2] = 1
    selectZDisplacementFromDisplacements = Tensor('selectZDisplacementFromDisplacements',
                                                  selectZDisplacementFromDisplacements.shape,
                                                  selectZDisplacementFromDisplacements,
                                                  )

    aderdg.INodalDisplacement = OptionalDimTensor('INodalDisplacement',
                                                aderdg.Q.optName(),
                                                aderdg.Q.optSize(),
                                                aderdg.Q.optPos(),
                                                (aderdg.numberOf2DBasisFunctions(),),
                                                alignStride=True)

    displacement = OptionalDimTensor('displacement',
                                     aderdg.Q.optName(),
                                     aderdg.Q.optSize(),
                                     aderdg.Q.optPos(),
                                     (aderdg.numberOf3DBasisFunctions(), 3),
                                     alignStride=True)

    dt = Scalar('dt')
    displacementAvgNodal = lambda side: aderdg.INodalDisplacement['i'] <= \
                                        aderdg.db.V3mTo2nFace[side]['ij'] * aderdg.I['jk'] * selectZDisplacementFromQuantities['k'] \
                                        + dt * aderdg.db.V3mTo2nFace[side]['ij'] * displacement['jk'] * selectZDisplacementFromDisplacements['k']

    generator.addFamily('displacementAvgNodal',
                        simpleParameterSpace(4),
                        displacementAvgNodal)

    aderdg.INodalUpdate = OptionalDimTensor('INodalUpdate',
                                          aderdg.INodal.optName(),
                                          aderdg.INodal.optSize(),
                                          aderdg.INodal.optPos(),
                                          (aderdg.numberOf2DBasisFunctions(), aderdg.numberOfQuantities()),
                                          alignStride=True)

    factor = Scalar('factor')
    updateINodal = aderdg.INodal['kp'] <= aderdg.INodal['kp'] + factor * aderdg.INodalUpdate['kp']
    generator.add('updateINodal', updateINodal)