From 9817cb318db0c8aa9ca09833ad8b1a108523bee5 Mon Sep 17 00:00:00 2001 From: andy Date: Thu, 11 Apr 2013 14:52:53 +0100 Subject: [PATCH] ENH: Added and abstracted out new AMI methods - direct, mapNearest and faceAreaWeight --- .../AMIMethod/AMIMethod/AMIMethod.C | 339 +++++++++++ .../AMIMethod/AMIMethod/AMIMethod.H | 268 +++++++++ .../AMIMethod/AMIMethod/AMIMethodI.H | 34 ++ .../AMIMethod/AMIMethod/AMIMethodNew.C | 79 +++ .../AMIMethod/directAMI/directAMI.C | 224 +++++++ .../AMIMethod/directAMI/directAMI.H | 144 +++++ .../faceAreaWeightAMI/faceAreaWeightAMI.C | 553 ++++++++++++++++++ .../faceAreaWeightAMI/faceAreaWeightAMI.H | 166 ++++++ .../AMIMethod/mapNearestAMI/mapNearestAMI.C | 343 +++++++++++ .../AMIMethod/mapNearestAMI/mapNearestAMI.H | 158 +++++ 10 files changed, 2308 insertions(+) create mode 100644 src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/AMIMethod/AMIMethod.C create mode 100644 src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/AMIMethod/AMIMethod.H create mode 100644 src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/AMIMethod/AMIMethodI.H create mode 100644 src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/AMIMethod/AMIMethodNew.C create mode 100644 src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/directAMI/directAMI.C create mode 100644 src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/directAMI/directAMI.H create mode 100644 src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/faceAreaWeightAMI/faceAreaWeightAMI.C create mode 100644 src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/faceAreaWeightAMI/faceAreaWeightAMI.H create mode 100644 src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/mapNearestAMI/mapNearestAMI.C create mode 100644 src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/mapNearestAMI/mapNearestAMI.H diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/AMIMethod/AMIMethod.C b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/AMIMethod/AMIMethod.C new file mode 100644 index 0000000000..03f6355870 --- /dev/null +++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIMethod/AMIMethod/AMIMethod.C @@ -0,0 +1,339 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation + \\/ 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 . + +\*---------------------------------------------------------------------------*/ + +#include "AMIMethod.H" +#include "meshTools.H" +#include "mapDistribute.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +template +void Foam::AMIMethod::checkPatches() const +{ + if (debug && (!srcPatch_.size() || !tgtPatch_.size())) + { + Pout<< "AMI: Patches not on processor: Source faces = " + << srcPatch_.size() << ", target faces = " << tgtPatch_.size() + << endl; + } + + + const scalar maxBoundsError = 0.05; + + // check bounds of source and target + boundBox bbSrc(srcPatch_.points(), srcPatch_.meshPoints(), true); + boundBox bbTgt(tgtPatch_.points(), tgtPatch_.meshPoints(), true); + + boundBox bbTgtInf(bbTgt); + bbTgtInf.inflate(maxBoundsError); + + if (!bbTgtInf.contains(bbSrc)) + { + WarningIn("AMIMethod::checkPatches()") + << "Source and target patch bounding boxes are not similar" << nl + << " source box span : " << bbSrc.span() << nl + << " target box span : " << bbTgt.span() << nl + << " source box : " << bbSrc << nl + << " target box : " << bbTgt << nl + << " inflated target box : " << bbTgtInf << endl; + } +} + + +template +bool Foam::AMIMethod::initialise +( + labelListList& srcAddress, + scalarListList& srcWeights, + labelListList& tgtAddress, + scalarListList& tgtWeights, + label& srcFaceI, + label& tgtFaceI +) +{ + // set initial sizes for weights and addressing - must be done even if + // returns false below + srcAddress.setSize(srcPatch_.size()); + srcWeights.setSize(srcPatch_.size()); + tgtAddress.setSize(tgtPatch_.size()); + tgtWeights.setSize(tgtPatch_.size()); + + // check that patch sizes are valid + if (!srcPatch_.size()) + { + return false; + } + else if (!tgtPatch_.size()) + { + WarningIn + ( + "void Foam::AMIMethod::initialise" + "(" + "label&, " + "label&" + ")" + ) + << srcPatch_.size() << " source faces but no target faces" << endl; + + return false; + } + + // reset the octree + resetTree(); + + // find initial face match using brute force/octree search + if ((srcFaceI == -1) || (tgtFaceI == -1)) + { + srcFaceI = 0; + tgtFaceI = 0; + bool foundFace = false; + forAll(srcPatch_, faceI) + { + tgtFaceI = findTargetFace(faceI); + if (tgtFaceI >= 0) + { + srcFaceI = faceI; + foundFace = true; + break; + } + } + + if (!foundFace) + { + FatalErrorIn + ( + "void Foam::AMIMethod::initialise" + "(" + "label&, " + "label&" + ")" + ) << "Unable to find initial target face" << abort(FatalError); + } + } + + if (debug) + { + Pout<< "AMI: initial target face = " << tgtFaceI << endl; + } + + return true; +} + + +template +void Foam::AMIMethod::writeIntersectionOBJ +( + const scalar area, + const face& f1, + const face& f2, + const pointField& f1Points, + const pointField& f2Points +) const +{ + static label count = 1; + + const pointField f1pts = f1.points(f1Points); + const pointField f2pts = f2.points(f2Points); + + Pout<< "Face intersection area (" << count << "):" << nl + << " f1 face = " << f1 << nl + << " f1 pts = " << f1pts << nl + << " f2 face = " << f2 << nl + << " f2 pts = " << f2pts << nl + << " area = " << area + << endl; + + OFstream os("areas" + name(count) + ".obj"); + + forAll(f1pts, i) + { + meshTools::writeOBJ(os, f1pts[i]); + } + os<< "l"; + forAll(f1pts, i) + { + os<< " " << i + 1; + } + os<< " 1" << endl; + + + forAll(f2pts, i) + { + meshTools::writeOBJ(os, f2pts[i]); + } + os<< "l"; + forAll(f2pts, i) + { + os<< " " << f1pts.size() + i + 1; + } + os<< " " << f1pts.size() + 1 << endl; + + count++; +} + + +template +void Foam::AMIMethod::resetTree() +{ + // Clear the old octree + treePtr_.clear(); + + treeBoundBox bb(tgtPatch_.points()); + bb.inflate(0.01); + + if (!treePtr_.valid()) + { + treePtr_.reset + ( + new indexedOctree + ( + treeType(false, tgtPatch_), + bb, // overall search domain + 8, // maxLevel + 10, // leaf size + 3.0 // duplicity + ) + ); + } +} + + +template +Foam::label Foam::AMIMethod::findTargetFace +( + const label srcFaceI +) const +{ + label targetFaceI = -1; + + const pointField& srcPts = srcPatch_.points(); + const face& srcFace = srcPatch_[srcFaceI]; + const point srcPt = srcFace.centre(srcPts); + const scalar srcFaceArea = srcMagSf_[srcFaceI]; + + pointIndexHit sample = treePtr_->findNearest(srcPt, 10.0*srcFaceArea); + + + if (debug) + { + Pout<< "Source point = " << srcPt << ", Sample point = " + << sample.hitPoint() << ", Sample index = " << sample.index() + << endl; + } + + if (sample.hit()) + { + targetFaceI = sample.index(); + } + + return targetFaceI; +} + + +template +void Foam::AMIMethod::appendNbrFaces +( + const label faceI, + const TargetPatch& patch, + const DynamicList