Exemplo n.º 1
0
Foam::tmp<Foam::Field<Type>> Foam::levelSetAverage
(
    const fvPatch& patch,
    const scalarField& levelF,
    const scalarField& levelP,
    const Field<Type>& positiveF,
    const Field<Type>& positiveP,
    const Field<Type>& negativeF,
    const Field<Type>& negativeP
)
{
    typedef typename outerProduct<Type, vector>::type sumType;

    tmp<Field<Type>> tResult(new Field<Type>(patch.size(), Zero));
    Field<Type>& result = tResult.ref();

    forAll(result, fI)
    {
        const face& f = patch.patch().localFaces()[fI];

        vector a = vector::zero;
        sumType r = Zero;

        for(label eI = 0; eI < f.size(); ++ eI)
        {
            const edge e = f.faceEdge(eI);

            const FixedList<point, 3>
                tri =
                {
                    patch.patch().faceCentres()[fI],
                    patch.patch().localPoints()[e[0]],
                    patch.patch().localPoints()[e[1]]
                };
            const FixedList<scalar, 3>
                level =
                {
                    levelF[fI],
                    levelP[e[0]],
                    levelP[e[1]]
                };
            const cut::areaIntegrateOp<Type>
                positive = FixedList<Type, 3>
                ({
                    positiveF[fI],
                    positiveP[e[0]],
                    positiveP[e[1]]
                });
            const cut::areaIntegrateOp<Type>
                negative = FixedList<Type, 3>
                ({
                    negativeF[fI],
                    negativeP[e[0]],
                    negativeP[e[1]]
                });

            a += cut::areaOp()(tri);

            r += triCut(tri, level, positive, negative);
        }

        result[fI] = a/magSqr(a) & r;
    }

    return tResult;
}
Foam::Tuple2<Foam::scalar, Foam::point>
Foam::sweptFaceAreaWeightAMI<SourcePatch, TargetPatch>::interArea
(
    const label srcFacei,
    const label tgtFacei
) const
{
    const label debugTgtFace =
        (- 1 - debug) % this->tgtPatch_.size() == tgtFacei
      ? (- 1 - debug) / this->tgtPatch_.size() + 1 : 0;
    const bool debugPrint = debug > 0 || debugTgtFace > 0;
    const bool debugWrite = debug > 1 || debugTgtFace > 1;

    if (debugPrint)
    {
        Info<< "Inter area between source face #" << srcFacei
            << " and target face #" << tgtFacei << (debugWrite ? "\n" : ": ");
    }

    // Patch data
    const pointField& srcPoints = this->srcPatch_.localPoints();
    const pointField& tgtPoints = this->tgtPatch_.localPoints();
    const vectorField& srcPointNormals = this->srcPatch_.pointNormals();

    // Faces
    const face& srcFace = this->srcPatch_.localFaces()[srcFacei];
    const face& tgtFace = this->tgtPatch_.localFaces()[tgtFacei];

    // Write out the faces
    if (debugWrite)
    {
        writeFaceOBJ(srcFace, srcPoints, "source");
        writeFaceOBJ(tgtFace, tgtPoints, "target");
    }
    if (debugTgtFace)
    {
        writeFaceOBJ(tgtFace, tgtPoints, "target" + name(tgtFacei));
    }

    // Triangulate the faces
    const faceAreaIntersect::triangulationMode triMode = this->triMode_;
    faceList srcFaceTris, tgtFaceTris;
    faceAreaIntersect::triangulate(srcFace, srcPoints, triMode, srcFaceTris);
    faceAreaIntersect::triangulate(tgtFace, tgtPoints, triMode, tgtFaceTris);

    // Area sum
    scalar areaMag = Zero;

    // Loop the target triangles
    forAllConstIter(faceList, tgtFaceTris, tgtIter)
    {
        const FixedList<point, 3>
            tgtTri =
            {
                tgtPoints[(*tgtIter)[0]],
                tgtPoints[(*tgtIter)[this->reverseTarget_ ? 2 : 1]],
                tgtPoints[(*tgtIter)[this->reverseTarget_ ? 1 : 2]]
            };

        // Loop the source triangles
        forAllConstIter(faceList, srcFaceTris, srcIter)
        {
            FixedList<point, 4>
                srcTri =
                {
                    srcPoints[(*srcIter)[0]],
                    srcPoints[(*srcIter)[1]],
                    srcPoints[(*srcIter)[2]],
                    vector::zero
                };
            FixedList<point, 4>
                srcNrm =
                {
                    srcPointNormals[(*srcIter)[0]],
                    srcPointNormals[(*srcIter)[1]],
                    srcPointNormals[(*srcIter)[2]],
                    vector::zero
                };

            // Get the source projection modified for any reverse intersections
            const label srcN = getSourceProjection(srcTri, srcNrm, tgtTri);
            if (srcN <= 0)
            {
                continue;
            }

            // Write the source projection
            if (debugWrite)
            {
                writeProjectionOBJ(srcN, srcTri, srcNrm);
            }

            // Create the initial cut triangle list
            cutTriList<8> cutTris;
            cutTris.append(tgtTri);

            // Write the initial triangle
            if (debugWrite)
            {
                writeCutTrisVTK(cutTris, "tris0");
            }

            // Do all but one of the cuts
            for
            (
                label i = 0;
                i < srcN - 1 && (debugWrite || cutTris.size());
                ++ i
            )
            {
                // Do the cut
                const plane cutPlane =
                    getCutPlane
                    (
                        srcTri[i],
                        srcTri[i+1],
                        srcNrm[i],
                        srcNrm[i+1],
                        tgtTri
                    );

                cutTriList<8> cutTrisTmp;

                for (label j = 0; j < cutTris.size(); ++j)
                {
                    triCut
                    (
                        cutTris[j],
                        cutPlane,
                        cut::noOp(),
                        cut::appendOp<cutTriList<8>>(cutTrisTmp)
                    );
                }
                Swap(cutTris, cutTrisTmp);

                // Write the triangles resulting from the cut
                if (debugWrite)
                {
                    writeCutTrisVTK(cutTris, "tris" + name(i + 1));
                }
            }

            // Do the last cut
            const plane cutPlane =
                getCutPlane
                (
                    srcTri[srcN - 1],
                    srcTri[0],
                    srcNrm[srcN - 1],
                    srcNrm[0],
                    tgtTri
                );
            cutTriList<8> cutTrisTmp;
            for (label i = 0; i < cutTris.size(); ++ i)
            {
                // Sum the area of the cut triangle
                areaMag +=
                    mag
                    (
                        triCut
                        (
                            cutTris[i],
                            cutPlane,
                            cut::noOp(),
                            cut::areaOp()
                        )
                    );
                // Store the cut triangle if it is needed for output
                if (debugWrite || debugTgtFace)
                {
                    triCut
                    (
                        cutTris[i],
                        cutPlane,
                        cut::noOp(),
                        cut::appendOp<cutTriList<8>>(cutTrisTmp)
                    );
                }
            }
            Swap(cutTris, cutTrisTmp);

            // Write the triangles resulting from the cuts
            if (debugTgtFace && cutTris.size())
            {
                static label writeCutTrisVTKIndex = 0;
                writeCutTrisVTK
                (
                    cutTris,
                    "target" + name(tgtFacei) + "_"
                  + "tris" + name(writeCutTrisVTKIndex ++)
                );
            }
            if (debugWrite)
            {
                writeCutTrisVTK(cutTris, "tris" + name(srcN));

                Info << "view triangles then press ENTER to continue ...";
                getchar();
            }
        }
    }