Example #1
0
def viscositySolver(solver, rho, rhoU, rhoE, rhoa, rhoUa, rhoEa, DT):
    mesh = solver.mesh.symMesh

    def divideFields(rhoa, rhoUa, rhoEa, volumes):
        return rhoa / volumes, rhoUa[0] / volumes, rhoUa[1] / volumes, rhoUa[
            2] / volumes, rhoEa / volumes

    fields = Kernel(divideFields)(mesh.nInternalCells)(rhoa, rhoUa, rhoEa,
                                                       mesh.volumes)

    def getFaceData(DT, areas, deltas):
        return areas * DT / deltas

    DTF = Kernel(getFaceData)(mesh.nFaces)(DT, mesh.areas, mesh.deltas)

    inputs = fields + (rho, rhoU, rhoE, DTF, solver.dt)
    outputs = tuple([Zeros(x.shape) for x in fields])
    fields = ExternalFunctionOp('apply_adjoint_viscosity', inputs,
                                outputs).outputs

    def multiplyFields(phi1, phi2, phi3, phi4, phi5, volumes):
        rhoa = phi1 * volumes
        rhoUa = Tensor((3, ), [phi2 * volumes, phi3 * volumes, phi4 * volumes])
        rhoEa = phi5 * volumes
        return rhoa, rhoUa, rhoEa

    return Kernel(multiplyFields)(mesh.nInternalCells)(*(fields +
                                                         (mesh.volumes, )))
Example #2
0
def timeStepper(equation, initFields, solver):
    mesh = solver.mesh.symMesh
    alpha, beta, gamma = solver.timeStepCoeff
    nStages = alpha.shape[0]
    LHS = []
    fields = [initFields]
    n = len(fields[0])

    def update(*args, **kwargs):
        i = kwargs['i']
        currFields = [0] * n
        LHS, S, fields, dt = args[:n], args[n:2 * n], args[2 * n:-1], args[-1]
        dt = dt.scalar()
        for j in range(0, i + 1):
            for index in range(0, n):
                currFields[index] += alpha[i, j] * fields[j * n + index]
        for index in range(0, n):
            currFields[index] += -beta[i, i] * (LHS[index] - S[index]) * dt
        return tuple(currFields)

    for i in range(0, nStages):
        #solver.t = solver.t0 + gamma[i]*solver.dt
        LHS = equation(*fields[i])
        S = [x[0] for x in solver.sourceTerms]
        args = list(LHS) + S + sum(fields, []) + [solver.dt]
        currFields = Kernel(update)(mesh.nInternalCells)(*args, i=i)
        solver.stage += 1
        fields.append(list(currFields))
    return fields[-1]
Example #3
0
File: BCs.py Project: qiqi/adFVM
 def update(self, *args):
     if len(args) == 1:
         return args[0]
     U, T, p = args
     inputs = tuple([U, T, p] + [x[0] for x in self.inputs])
     outputs = (U[self.cellStartFace], T[self.cellStartFace],
                p[self.cellStartFace])
     return Kernel(self._update)(self.nFaces, outputs)(*inputs)
Example #4
0
File: BCs.py Project: qiqi/adFVM
    def __init__(self, phi, patchID):
        self.patchID = patchID
        self.dimensions = phi.dimensions
        self.solver = phi.solver
        self.mesh = phi.mesh
        self.patch = phi.boundary[patchID]

        mesh = self.mesh.symMesh
        patch = mesh.boundary[patchID]
        self.startFace, self.nFaces = patch['startFace'], patch['nFaces']
        self.cellStartFace = patch['cellStartFace']
        self.normals = mesh.normals[self.startFace]
        self.owner = mesh.owner
        # used by field writer
        self.keys = []
        self.inputs = []
        self._tensorUpdate = Kernel(self._update)
Example #5
0
def computeSymmetrizedAdjointEnergy(solver, rhoa, rhoUa, rhoEa, rho, rhoU,
                                    rhoE):
    # optimize this function
    mesh = solver.mesh.symMesh

    def computeEnergy(rhoa, rhoUa, rhoEa, rho, rhoU, rhoE, volumes):
        U = rhoU / rho
        u1, u2, u3 = U[0], U[1], U[2]
        q2 = (u1 * u1 + u2 * u2 + u3 * u3)
        g = solver.gamma
        p = (rhoE - rho * q2 / 2) * (g - 1)
        H = g * p / (rho * (g - 1)) + q2 / 2
        A = Tensor((5, 5), [
            rho, rho * u1, rho * u2, rho * u3, rhoE, rho * u1,
            rho * u1 * u1 + p, rho * u1 * u2, rho * u1 * u3, rho * H * u1,
            rho * u2, rho * u2 * u1, rho * u2 * u2 + p, rho * u2 * u3,
            rho * H * u2, rho * u3, rho * u3 * u1, rho * u3 * u2,
            rho * u3 * u3 + p, rho * H * u3, rhoE, rho * H * u1, rho * H * u2,
            rho * H * u3, rho * H * H - g * p * p / (rho * (g - 1))
        ])
        # already divided by volumes
        # not divided by volumes
        rhoa = rhoa / volumes
        rhoUa = rhoUa / volumes
        rhoEa = rhoEa / volumes
        w = Tensor((5, ), [rhoa, rhoUa[0], rhoUa[1], rhoUa[2], rhoEa])

        l2norm = w.dot(A.tensordot(w))
        return (l2norm * volumes).sum()

    adjEnergy = Zeros((1, 1))
    adjEnergy = Kernel(computeEnergy)(mesh.nInternalCells,
                                      (adjEnergy, ))(rhoa, rhoUa, rhoEa, rho,
                                                     rhoU, rhoE, mesh.volumes)
    (adjEnergy, ) = ExternalFunctionOp('mpi_allreduce', (adjEnergy, ), (Zeros(
        (1, 1)), )).outputs
    return adjEnergy
Example #6
0
def computeAdjointViscosity(solver, viscosityType, rho, rhoU, rhoE, scaling):
    g = solver.gamma
    mesh = solver.mesh.symMesh

    def _meshArgs(start=0):
        return [x[start] for x in mesh.getTensor()]

    def gradients(U, T, p, *mesh, **options):
        mesh = Mesh.container(mesh)
        neighbour = options.pop('neighbour', True)
        boundary = options.pop('boundary', False)

        if boundary:
            UF = U.extract(mesh.neighbour)
            pF = p.extract(mesh.neighbour)
            TF = T.extract(mesh.neighbour)
            cF = (g * TF * solver.R).sqrt()
        else:
            UF = interp.central(U, mesh)
            pF = interp.central(p, mesh)
            TLF, TRF = T.extract(mesh.owner), T.extract(mesh.neighbour)
            cLF, cRF = (g * TLF * solver.R).sqrt(), (g * TRF * solver.R).sqrt()
            cF = cRF * (1 - mesh.weights) + cLF * mesh.weights

        gradU = op.grad(UF, mesh, neighbour)
        divU = op.div(UF.dot(mesh.normals), mesh, neighbour)
        gradp = op.grad(pF, mesh, neighbour)
        gradc = op.grad(cF, mesh, neighbour)
        return gradU, divU, gradp, gradc

    computeGradients = Kernel(gradients)
    boundaryComputeGradients = Kernel(gradients)
    coupledComputeGradients = Kernel(gradients)

    U, T, p = Zeros((mesh.nCells, 3)), Zeros((mesh.nCells, 1)), Zeros(
        (mesh.nCells, 1))
    outputs = solver._primitive(mesh.nInternalCells, (U, T, p))(rho, rhoU,
                                                                rhoE)
    # boundary update
    outputs = solver.boundaryInit(*outputs)
    outputs = solver.boundary(*outputs)
    outputs = solver.boundaryEnd(*outputs)
    U, T, p = outputs

    meshArgs = _meshArgs()
    gradU, divU, gradp, gradc = Zeros((mesh.nInternalCells, 3, 3)), Zeros(
        (mesh.nInternalCells, 1)), Zeros((mesh.nInternalCells, 3)), Zeros(
            (mesh.nInternalCells, 3))
    outputs = computeGradients(mesh.nInternalFaces,
                               (gradU, divU, gradp, gradc))(U, T, p, *meshArgs)
    for patchID in solver.mesh.sortedPatches:
        startFace, nFaces = mesh.boundary[patchID]['startFace'], mesh.boundary[
            patchID]['nFaces']
        patchType = solver.mesh.boundary[patchID]['type']
        meshArgs = _meshArgs(startFace)
        if patchType in config.coupledPatches:
            outputs = coupledComputeGradients(nFaces, outputs)(U,
                                                               T,
                                                               p,
                                                               neighbour=False,
                                                               boundary=False,
                                                               *meshArgs)
            outputs[0].args[0].info += [[
                x.shape for x in solver.mesh.getTensor()
            ], patchID, solver.mesh.boundary[patchID]['startFace'],
                                        solver.mesh.boundary[patchID]['nFaces']
                                        ]
        else:
            outputs = boundaryComputeGradients(nFaces,
                                               outputs)(U,
                                                        T,
                                                        p,
                                                        neighbour=False,
                                                        boundary=True,
                                                        *meshArgs)
    meshArgs = _meshArgs(mesh.nLocalFaces)
    outputs = coupledComputeGradients(mesh.nRemoteCells,
                                      outputs)(U,
                                               T,
                                               p,
                                               neighbour=False,
                                               boundary=False,
                                               *meshArgs)
    gradU, divU, gradp, gradc = outputs

    def getMaxEigenvalue(U, T, p, gradU, divU, gradp, gradc):
        Uref, Tref, pref = solver.Uref, solver.Tref, solver.pref
        sg = np.sqrt(g)
        g1 = g - 1
        sg1 = np.sqrt(g1)
        sge = sg1 * sg

        rho, _, _ = solver.conservative(U, T, p)
        c = (g * p / rho).sqrt()
        gradrho = g * (gradp - c * p) / (c * c)
        b = c / sg
        a = sg1 * c / sg
        gradb = gradc / sg
        grada = gradc * sg1 / sg
        Z = Tensor((1, ), [ConstantOp(0.)])
        U1, U2, U3 = U[0], U[1], U[2]
        Us = U.magSqr()
        c2 = c * c
        B = Tensor((5, 5), [
            rho, rho, rho, rho, rho, rho, rho, rho, rho, rho, rho, rho, rho,
            rho, rho, rho, rho, rho, rho, rho, rho, rho, rho, rho, rho
        ])

        if viscosityType == 'abarbanel' or viscosityType == 'uniform':
            M1 = Tensor((5, 5), [
                divU, gradb[0], gradb[1], gradb[2], Z, gradb[0], divU, Z, Z,
                grada[0], gradb[1], Z, divU, Z, grada[1], gradb[2], Z, Z, divU,
                grada[2], Z, grada[0], grada[1], grada[2], divU
            ])
            tmp1 = b * gradrho / rho
            tmp2 = a * gradp / (2 * p)
            tmp3 = 2 * grada / g1

            M2 = Tensor((5, 5), [
                Z, tmp1[0], tmp1[1], tmp1[2], sg1 * divU / 2, Z, gradU[0, 0],
                gradU[0, 1], gradU[0, 2], tmp2[0], Z, gradU[1, 0], gradU[1, 1],
                gradU[1, 2], tmp2[1], Z, gradU[2, 0], gradU[2, 1], gradU[2, 2],
                tmp2[2], Z, tmp3[0], tmp3[1], tmp3[2], g1 * divU / 2
            ])
            M = M1 / 2 - M2
        elif viscosityType == 'turkel':
            M1 = Tensor((5, 5), [
                divU, gradc[0], gradc[1], gradc[2], Z, gradc[0], divU, Z, Z, Z,
                gradc[1], Z, divU, Z, Z, gradc[2], Z, Z, divU, Z, Z, Z, Z, Z,
                divU
            ])
            tmp1 = gradp / (rho * c)
            tmp2 = g1 * gradp / (2 * rho * c)
            tmp3 = gradp * pref / (2 * g * p * rho * Uref)
            tmp4 = (gradp - c * c * gradrho) * Uref / pref

            M2 = Tensor((5, 5), [
                g1 * divU / 2, tmp1[0], tmp1[1], tmp1[2], divU * pref /
                (2 * rho * c * Uref), tmp2[0], gradU[0, 0], gradU[0, 1],
                gradU[0, 2], tmp3[0], tmp2[1], gradU[1, 0], gradU[1, 1],
                gradU[1, 2], tmp3[1], tmp2[2], gradU[2, 0], gradU[2, 1],
                gradU[2,
                      2], tmp3[2], Z, tmp4[0], tmp4[1], tmp4[2], g1 * divU / 2
            ])
            M = M1 / 2 - M2
        #elif viscosityType == 'entropy_hughes':
        #    from .symmetrizations.entropy_hughes_gen_code import expression
        #    M1, M2 = expression(rho, U, p, gradrho, gradU, gradp, g, Z)
        #    M1 = Tensor((5,5), M1)
        #    M2 = Tensor((5,5), M2)
        #    M = -(M1 + M2)

        elif viscosityType == 'entropy_hughes':
            from .symmetrizations.entropy_barth_mathematica import expression_code
            M = expression_code(rho, U, p, gradrho, gradU, gradp, g, Z)

            M = [item for sublist in M for item in sublist]
            #X = [1., 1./Uref, 1./Uref, 1./Uref, 1/pref]
            #M = [item*X[i]*X[j] for i, sublist in enumerate(M) for j, item in enumerate(sublist)]
            M = Tensor((5, 5), M)

            u1, u2, u3 = U[0], U[1], U[2]
            q2 = (u1 * u1 + u2 * u2 + u3 * u3)
            H = g * p / (rho * (g - 1)) + q2 / 2
            rE = p / (g - 1) + 0.5 * rho * q2
            B = Tensor((5, 5), [
                rho, rho * u1, rho * u2, rho * u3, rE, rho * u1,
                rho * u1 * u1 + p, rho * u1 * u2, rho * u1 * u3, rho * H * u1,
                rho * u2, rho * u2 * u1, rho * u2 * u2 + p, rho * u2 * u3,
                rho * H * u2, rho * u3, rho * u3 * u1, rho * u3 * u2,
                rho * u3 * u3 + p, rho * H * u3, rE, rho * H * u1, rho * H *
                u2, rho * H * u3, rho * H * H - g * p * p / (rho * (g - 1))
            ])

        else:
            raise Exception('symmetrizer not recognized')

        #Ti = Tensor((5, 5), [rho/b, Z, Z, Z, Z,
        #                     rho*U1/b, rho, Z, Z, Z,
        #                     rho*U2/b, Z, rho, Z, Z,
        #                     rho*U3/b, Z, Z, rho, Z,
        #                     rho*(c2*2/(g1*g)+Us)/(2*b), rho*U1, rho*U2, rho*U3, c*rho/sge])
        #Ti = Ti.transpose()
        #X = np.diag([1, 1./Uref, 1./Uref, 1./Uref, 1/pref])
        #TiX = Ti.matmul(X)

        #Mc = TiX.transpose().matmul(M.matmul(TiX))
        Mc = M
        MS = (Mc + Mc.transpose()) / 2
        return MS, B

    def constant(M_2norm):
        return M_2norm + 1

    M_2norm = Zeros((mesh.nInternalCells, 1))
    if viscosityType == 'uniform':
        M_2norm = Kernel(constant)(mesh.nInternalCells)(M_2norm)
    else:
        MS = Zeros((mesh.nInternalCells, 5, 5))
        B = Zeros((mesh.nInternalCells, 5, 5))
        MS, B = Kernel(getMaxEigenvalue)(mesh.nInternalCells,
                                         (MS, B))(U, T, p, gradU, divU, gradp,
                                                  gradc)
        if viscosityType != 'entropy_hughes':
            (M_2norm, ) = ExternalFunctionOp('get_max_eigenvalue', (MS, ),
                                             (M_2norm, )).outputs
        else:
            (M_2norm, ) = ExternalFunctionOp('get_max_generalized_eigenvalue',
                                             (MS, B), (M_2norm, )).outputs

    def computeVolume(volumes):
        return volumes.sum()

    V = Zeros((1, 1))
    V = Kernel(computeVolume)(mesh.nInternalCells, (V, ))(mesh.volumes)
    (V, ) = ExternalFunctionOp('mpi_allreduce', (V, ), (Zeros(
        (1, 1)), )).outputs

    def computeNorm(M_2norm, volumes, V):
        V = V.scalar()
        N = (M_2norm * M_2norm * volumes / V).sum()
        return N

    N = Zeros((1, 1))
    N = Kernel(computeNorm)(mesh.nInternalCells, (N, ))(M_2norm, mesh.volumes,
                                                        V)
    (N, ) = ExternalFunctionOp('mpi_allreduce', (N, ), (Zeros(
        (1, 1)), )).outputs

    def scaleM(M_2norm, N, scaling):
        N, scaling = N.scalar(), scaling.scalar()
        return M_2norm * scaling / N.sqrt()

    M_2norm_out = Zeros((mesh.nCells, 1))
    M_2norm = Kernel(scaleM)(mesh.nInternalCells, (M_2norm_out, ))(M_2norm, N,
                                                                   scaling)

    (phi, ) = solver.boundaryInit(M_2norm)
    phi = CellField('M_2norm', None, (1, )).updateGhostCells(phi)
    (phi, ) = ExternalFunctionOp('mpi', (phi, ), (phi, )).outputs
    (phi, ) = solver.boundaryEnd(phi)
    M_2norm = phi

    def interpolate(M_2norm, *mesh):
        mesh = Mesh.container(mesh)
        M_2norm = interp.central(M_2norm, mesh)
        return M_2norm

    meshArgs = _meshArgs()
    DT = Zeros((mesh.nFaces, 1))
    DT = Kernel(interpolate)(mesh.nFaces, (DT, ))(M_2norm, *meshArgs)
    return M_2norm, DT
Example #7
0
    Uc = Field('U', 2 * X + X**3 * Y**2, (1, ))
    gradUc = gradOld(centralOld(Uc, mesh), ghost=True)
    gradUc.field = gradUc.field.reshape((mesh.nCells, 1, 3))
    Xf, Yf = mesh.faceCentres[:, [0]], mesh.faceCentres[:, [1]]
    Ur = 2 * Xf + Xf**3 * Yf**2

    U = Variable((mesh.symMesh.nCells, 1))
    gradU = Variable((mesh.symMesh.nCells, 1, 3))

    def interpolate(U, gradU, *meshArgs):
        mesh = Mesh.container(meshArgs)
        return secondOrder(U, gradU, mesh, 0)

    Uf = Zeros((mesh.symMesh.nFaces, 1))
    meshArgs = mesh.symMesh.getTensor()
    Uf = Kernel(interpolate)(mesh.symMesh.nFaces, (Uf, ))(U, gradU, *meshArgs)
    meshArgs = mesh.symMesh.getTensor() + mesh.symMesh.getScalar()
    func = Function('second_order', [U, gradU] + meshArgs, (Uf, ))

    Function.compile(init=False, compiler_args=config.get_compiler_args())
    Function.initialize(0, mesh)

    meshArgs = mesh.getTensor() + mesh.getScalar()
    Uf = func(Uc.field, gradUc.field, *meshArgs)
    assert relative_error(Uf, Ur) < thres


def test_central():
    case = '../cases/convection'
    mesh = Mesh.create(case)
    Field.setMesh(mesh)