Skip to content
Snippets Groups Projects
patchProbes.C 7.54 KiB
Newer Older
  • Learn to ignore specific revisions
  • Henry's avatar
    Henry committed
    /*---------------------------------------------------------------------------*\
      =========                 |
      \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
       \\    /   O peration     |
    
        \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
    
    Henry's avatar
    Henry committed
         \\/     M anipulation  |
    -------------------------------------------------------------------------------
    License
        This file is part of OpenFOAM.
    
        OpenFOAM is free software: you can redistribute it and/or modify it
        under the terms of the GNU General Public License as published by
        the Free Software Foundation, either version 3 of the License, or
        (at your option) any later version.
    
        OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
        ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
        FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
        for more details.
    
        You should have received a copy of the GNU General Public License
        along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
    
    \*---------------------------------------------------------------------------*/
    
    #include "patchProbes.H"
    #include "volFields.H"
    #include "IOmanip.H"
    #include "mappedPatchBase.H"
    #include "treeBoundBox.H"
    #include "treeDataFace.H"
    
    #include "addToRunTimeSelectionTable.H"
    
    
    Henry's avatar
    Henry committed
    
    // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
    
    namespace Foam
    {
        defineTypeNameAndDebug(patchProbes, 0);
    
    
        addToRunTimeSelectionTable
        (
            functionObject,
            patchProbes,
            dictionary
        );
    
    Henry's avatar
    Henry committed
    }
    
    // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
    
    void Foam::patchProbes::findElements(const fvMesh& mesh)
    {
        (void)mesh.tetBasePtIs();
    
        const polyBoundaryMesh& bm = mesh.boundaryMesh();
    
    
        label patchi = bm.findPatchID(patchName_);
    
    Henry's avatar
    Henry committed
    
    
    Henry's avatar
    Henry committed
        {
    
            FatalErrorInFunction
                << " Unknown patch name "
    
    Henry's avatar
    Henry committed
                << patchName_ << endl
                << exit(FatalError);
        }
    
         // All the info for nearest. Construct to miss
        List<mappedPatchBase::nearInfo> nearest(this->size());
    
    
        const polyPatch& pp = bm[patchi];
    
    Henry's avatar
    Henry committed
    
        if (pp.size() > 0)
        {
            labelList bndFaces(pp.size());
            forAll(bndFaces, i)
            {
                bndFaces[i] =  pp.start() + i;
            }
    
            treeBoundBox overallBb(pp.points());
            Random rndGen(123456);
            overallBb = overallBb.extend(rndGen, 1e-4);
            overallBb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
            overallBb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
    
            const indexedOctree<treeDataFace> boundaryTree
            (
                treeDataFace    // all information needed to search faces
                (
                    false,                      // do not cache bb
                    mesh,
                    bndFaces                    // patch faces only
                ),
                overallBb,                      // overall search domain
                8,                              // maxLevel
                10,                             // leafsize
                3.0                             // duplicity
            );
    
    
    
            forAll(probeLocations(), probei)
    
    Henry's avatar
    Henry committed
            {
    
                const point sample = probeLocations()[probei];
    
    Henry's avatar
    Henry committed
    
                scalar span = boundaryTree.bb().mag();
    
                pointIndexHit info = boundaryTree.findNearest
                (
                    sample,
                    Foam::sqr(span)
                );
    
                if (!info.hit())
                {
                    info = boundaryTree.findNearest
                    (
                        sample,
                        Foam::sqr(GREAT)
                    );
                }
    
    
                label facei = boundaryTree.shapes().faceLabels()[info.index()];
    
                const label patchi = bm.whichPatch(facei);
    
    Henry's avatar
    Henry committed
    
                if (isA<emptyPolyPatch>(bm[patchi]))
                {
    
    Henry's avatar
    Henry committed
                    << " The sample point: " << sample
                    << " belongs to " << patchi
                    << " which is an empty patch. This is not permitted. "
                    << " This sample will not be included "
                    << endl;
                }
                else
                {
    
                    const point& fc = mesh.faceCentres()[facei];
    
    Henry's avatar
    Henry committed
    
                    mappedPatchBase::nearInfo sampleInfo;
    
                    sampleInfo.first() = pointIndexHit
                    (
                        true,
                        fc,
    
    Henry's avatar
    Henry committed
                    );
    
                    sampleInfo.second().first() = magSqr(fc-sample);
                    sampleInfo.second().second() = Pstream::myProcNo();
    
    
                    nearest[probei]= sampleInfo;
    
    Henry's avatar
    Henry committed
                }
            }
        }
    
    
        // Find nearest.
        Pstream::listCombineGather(nearest, mappedPatchBase::nearestEqOp());
        Pstream::listCombineScatter(nearest);
    
        if (debug)
        {
    
            InfoInFunction << endl;
    
    Henry's avatar
    Henry committed
            forAll(nearest, sampleI)
            {
    
                label proci = nearest[sampleI].second().second();
    
    Henry's avatar
    Henry committed
                label localI = nearest[sampleI].first().index();
    
                Info<< "    " << sampleI << " coord:"<< operator[](sampleI)
    
                    << " found on processor:" << proci
    
    Henry's avatar
    Henry committed
                    << " in local cell/face:" << localI
                    << " with fc:" << nearest[sampleI].first().rawPoint() << endl;
            }
        }
    
    
        // Extract any local faces to sample
        elementList_.setSize(nearest.size(), -1);
    
        forAll(nearest, sampleI)
        {
            if (nearest[sampleI].second().second() == Pstream::myProcNo())
            {
                // Store the face to sample
                elementList_[sampleI] = nearest[sampleI].first().index();
            }
        }
    }
    
    
    // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
    
    
    Foam::patchProbes::patchProbes
    (
        const word& name,
        const Time& t,
        const dictionary& dict
    )
    :
        probes(name, t, dict)
    {
        // When constructing probes above it will have called the
        // probes::findElements (since the virtual mechanism not yet operating).
        // Not easy to workaround (apart from feeding through flag into constructor)
        // so clear out any cells found for now.
        elementList_.clear();
        faceList_.clear();
    
        read(dict);
    }
    
    
    
    Henry's avatar
    Henry committed
    Foam::patchProbes::patchProbes
    (
        const word& name,
        const objectRegistry& obr,
        const dictionary& dict,
        const bool loadFromFiles
    )
    :
    
    Henry's avatar
    Henry committed
    {
        // When constructing probes above it will have called the
        // probes::findElements (since the virtual mechanism not yet operating).
        // Not easy to workaround (apart from feeding through flag into constructor)
        // so clear out any cells found for now.
        elementList_.clear();
        faceList_.clear();
    
        read(dict);
    }
    
    
    // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
    
    Foam::patchProbes::~patchProbes()
    {}
    
    
    
    bool Foam::patchProbes::write(const bool postProcess)
    
    Henry's avatar
    Henry committed
    {
        if (this->size() && prepare())
        {
            sampleAndWrite(scalarFields_);
            sampleAndWrite(vectorFields_);
            sampleAndWrite(sphericalTensorFields_);
            sampleAndWrite(symmTensorFields_);
            sampleAndWrite(tensorFields_);
    
            sampleAndWriteSurfaceFields(surfaceScalarFields_);
            sampleAndWriteSurfaceFields(surfaceVectorFields_);
            sampleAndWriteSurfaceFields(surfaceSphericalTensorFields_);
            sampleAndWriteSurfaceFields(surfaceSymmTensorFields_);
            sampleAndWriteSurfaceFields(surfaceTensorFields_);
        }
    
    
    bool Foam::patchProbes::read(const dictionary& dict)
    
    Henry's avatar
    Henry committed
    {
        dict.lookup("patchName") >> patchName_;
    
    Henry's avatar
    Henry committed
    }
    
    
    // ************************************************************************* //