FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

surfaceDisplacementPointPatchVectorField.C

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2007 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 \*---------------------------------------------------------------------------*/
00025 
00026 #include "surfaceDisplacementPointPatchVectorField.H"
00027 #include <OpenFOAM/addToRunTimeSelectionTable.H>
00028 #include <OpenFOAM/Time.H>
00029 #include <OpenFOAM/transformField.H>
00030 #include <finiteVolume/fvMesh.H>
00031 #include <fvMotionSolvers/displacementLaplacianFvMotionSolver.H>
00032 
00033 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00034 
00035 namespace Foam
00036 {
00037 
00038 
00039 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
00040 
00041 template<>
00042 const char*
00043 NamedEnum<surfaceDisplacementPointPatchVectorField::projectMode, 3>::
00044 names[] =
00045 {
00046     "nearest",
00047     "pointNormal",
00048     "fixedNormal"
00049 };
00050 
00051 const NamedEnum<surfaceDisplacementPointPatchVectorField::projectMode, 3>
00052     surfaceDisplacementPointPatchVectorField::projectModeNames_;
00053 
00054 
00055 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
00056 
00057 void surfaceDisplacementPointPatchVectorField::calcProjection
00058 (
00059     vectorField& displacement
00060 ) const
00061 {
00062     const polyMesh& mesh = patch().boundaryMesh().mesh()();
00063     const pointField& localPoints = patch().localPoints();
00064     const labelList& meshPoints = patch().meshPoints();
00065 
00066     //const scalar deltaT = mesh.time().deltaT().value();
00067 
00068     // Construct large enough vector in direction of projectDir so
00069     // we're guaranteed to hit something.
00070 
00071     //- Per point projection vector:
00072     const scalar projectLen = mag(mesh.bounds().max()-mesh.bounds().min());
00073 
00074     // For case of fixed projection vector:
00075     vector projectVec;
00076     if (projectMode_ == FIXEDNORMAL)
00077     {
00078         vector n = projectDir_/mag(projectDir_);
00079         projectVec = projectLen*n;
00080     }
00081 
00082 
00083     // Get fixed points (bit of a hack)
00084     const pointZone* zonePtr = NULL;
00085 
00086     if (frozenPointsZone_.size() > 0)
00087     {
00088         const pointZoneMesh& pZones = mesh.pointZones();
00089 
00090         zonePtr = &pZones[pZones.findZoneID(frozenPointsZone_)];
00091 
00092         Pout<< "surfaceDisplacementPointPatchVectorField : Fixing all "
00093             << zonePtr->size() << " points in pointZone " << zonePtr->name()
00094             << endl;
00095     }
00096 
00097     // Get the starting locations from the motionSolver
00098     const pointField& points0 = mesh.lookupObject<displacementFvMotionSolver>
00099     (
00100         "dynamicMeshDict"
00101     ).points0();
00102 
00103 
00104     pointField start(meshPoints.size());
00105     forAll(start, i)
00106     {
00107         start[i] = points0[meshPoints[i]] + displacement[i];
00108     }
00109 
00110     label nNotProjected = 0;
00111 
00112     if (projectMode_ == NEAREST)
00113     {
00114         List<pointIndexHit> nearest;
00115         labelList hitSurfaces;
00116         surfaces().findNearest
00117         (
00118             start,
00119             scalarField(start.size(), sqr(projectLen)),
00120             hitSurfaces,
00121             nearest
00122         );
00123 
00124         forAll(nearest, i)
00125         {
00126             if (zonePtr && (zonePtr->whichPoint(meshPoints[i]) >= 0))
00127             {
00128                 // Fixed point. Reset to point0 location.
00129                 displacement[i] = points0[meshPoints[i]] - localPoints[i];
00130             }
00131             else if (nearest[i].hit())
00132             {
00133                 displacement[i] =
00134                     nearest[i].hitPoint()
00135                   - points0[meshPoints[i]];
00136             }
00137             else
00138             {
00139                 nNotProjected++;
00140 
00141                 if (debug)
00142                 {
00143                     Pout<< "    point:" << meshPoints[i]
00144                         << " coord:" << localPoints[i]
00145                         << "  did not find any surface within " << projectLen
00146                         << endl;
00147                 }
00148             }
00149         }
00150     }
00151     else
00152     {
00153         // Do tests on all points. Combine later on.
00154 
00155         // 1. Check if already on surface
00156         List<pointIndexHit> nearest;
00157         {
00158             labelList nearestSurface;
00159             surfaces().findNearest
00160             (
00161                 start,
00162                 scalarField(start.size(), sqr(SMALL)),
00163                 nearestSurface,
00164                 nearest
00165             );
00166         }
00167 
00168         // 2. intersection. (combined later on with information from nearest
00169         // above)
00170         vectorField projectVecs(start.size(), projectVec);
00171 
00172         if (projectMode_ == POINTNORMAL)
00173         {
00174             projectVecs = projectLen*patch().pointNormals();
00175         }
00176 
00177         // Knock out any wedge component
00178         scalarField offset(start.size(), 0.0);
00179         if (wedgePlane_ >= 0 && wedgePlane_ <= vector::nComponents)
00180         {
00181             forAll(offset, i)
00182             {
00183                 offset[i] = start[i][wedgePlane_];
00184                 start[i][wedgePlane_] = 0;
00185                 projectVecs[i][wedgePlane_] = 0;
00186             }
00187         }
00188 
00189         List<pointIndexHit> rightHit;
00190         {
00191             labelList rightSurf;
00192             surfaces().findAnyIntersection
00193             (
00194                 start,
00195                 start+projectVecs,
00196                 rightSurf,
00197                 rightHit
00198             );
00199         }
00200         
00201         List<pointIndexHit> leftHit;
00202         {
00203             labelList leftSurf;
00204             surfaces().findAnyIntersection
00205             (
00206                 start,
00207                 start-projectVecs,
00208                 leftSurf,
00209                 leftHit
00210             );
00211         }
00212 
00213         // 3. Choose either -fixed, nearest, right, left.
00214         forAll(displacement, i)
00215         {
00216             if (zonePtr && (zonePtr->whichPoint(meshPoints[i]) >= 0))
00217             {
00218                 // Fixed point. Reset to point0 location.
00219                 displacement[i] = points0[meshPoints[i]] - localPoints[i];
00220             }
00221             else if (nearest[i].hit())
00222             {
00223                 // Found nearest.
00224                 displacement[i] =
00225                     nearest[i].hitPoint()
00226                   - points0[meshPoints[i]];
00227             }
00228             else
00229             {
00230                 pointIndexHit interPt;
00231 
00232                 if (rightHit[i].hit())
00233                 {
00234                     if (leftHit[i].hit())
00235                     {
00236                         if
00237                         (
00238                             magSqr(rightHit[i].hitPoint()-start[i])
00239                           < magSqr(leftHit[i].hitPoint()-start[i])
00240                         )
00241                         {
00242                             interPt = rightHit[i];
00243                         }
00244                         else
00245                         {
00246                             interPt = leftHit[i];
00247                         }
00248                     }
00249                     else
00250                     {
00251                         interPt = rightHit[i];
00252                     }
00253                 }
00254                 else
00255                 {
00256                     if (leftHit[i].hit())
00257                     {
00258                         interPt = leftHit[i];
00259                     }
00260                 }
00261 
00262 
00263                 if (interPt.hit())
00264                 {
00265                     if (wedgePlane_ >= 0 && wedgePlane_ <= vector::nComponents)
00266                     {
00267                         interPt.rawPoint()[wedgePlane_] += offset[i];
00268                     }
00269                     displacement[i] = interPt.rawPoint()-points0[meshPoints[i]];
00270                 }
00271                 else
00272                 {
00273                     nNotProjected++;
00274 
00275                     if (debug)
00276                     {
00277                         Pout<< "    point:" << meshPoints[i]
00278                             << " coord:" << localPoints[i]
00279                             << "  did not find any intersection between"
00280                             << " ray from " << start[i]-projectVecs[i]
00281                             << " to " << start[i]+projectVecs[i] << endl;
00282                     }
00283                 }
00284             }
00285         }
00286     }
00287 
00288     reduce(nNotProjected, sumOp<label>());
00289 
00290     if (nNotProjected > 0)
00291     {
00292         Info<< "surfaceDisplacement :"
00293             << " on patch " << patch().name()
00294             << " did not project " << nNotProjected
00295             << " out of " << returnReduce(localPoints.size(), sumOp<label>())
00296             << " points." << endl;
00297     }
00298 }
00299 
00300 
00301 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00302 
00303 surfaceDisplacementPointPatchVectorField::
00304 surfaceDisplacementPointPatchVectorField
00305 (
00306     const pointPatch& p,
00307     const DimensionedField<vector, pointMesh>& iF
00308 )
00309 :
00310     fixedValuePointPatchVectorField(p, iF),
00311     velocity_(vector::zero),
00312     projectMode_(NEAREST),
00313     projectDir_(vector::zero),
00314     wedgePlane_(-1)
00315 {}
00316 
00317 
00318 surfaceDisplacementPointPatchVectorField::
00319 surfaceDisplacementPointPatchVectorField
00320 (
00321     const pointPatch& p,
00322     const DimensionedField<vector, pointMesh>& iF,
00323     const dictionary& dict
00324 )
00325 :
00326     fixedValuePointPatchVectorField(p, iF, dict),
00327     velocity_(dict.lookup("velocity")),
00328     surfacesDict_(dict.subDict("geometry")),
00329     projectMode_(projectModeNames_.read(dict.lookup("projectMode"))),
00330     projectDir_(dict.lookup("projectDirection")),
00331     wedgePlane_(dict.lookupOrDefault("wedgePlane", -1)),
00332     frozenPointsZone_(dict.lookupOrDefault("frozenPointsZone", word::null))
00333 {
00334     if (velocity_.x() < 0 || velocity_.y() < 0 || velocity_.z() < 0)
00335     {
00336         FatalErrorIn
00337         (
00338             "surfaceDisplacementPointPatchVectorField::\n"
00339             "surfaceDisplacementPointPatchVectorField\n"
00340             "(\n"
00341             "    const pointPatch& p,\n"
00342             "    const DimensionedField<vector, pointMesh>& iF,\n"
00343             "    const dictionary& dict\n"
00344             ")\n"
00345         )   << "All components of velocity have to be positive : "
00346             << velocity_ << nl
00347             << "Set velocity components to a great value if no clipping"
00348             << " necessary." << exit(FatalError);
00349     }
00350 }
00351 
00352 
00353 surfaceDisplacementPointPatchVectorField::
00354 surfaceDisplacementPointPatchVectorField
00355 (
00356     const surfaceDisplacementPointPatchVectorField& ppf,
00357     const pointPatch& p,
00358     const DimensionedField<vector, pointMesh>& iF,
00359     const pointPatchFieldMapper& mapper
00360 )
00361 :
00362     fixedValuePointPatchVectorField(ppf, p, iF, mapper),
00363     velocity_(ppf.velocity_),
00364     surfacesDict_(ppf.surfacesDict_),
00365     projectMode_(ppf.projectMode_),
00366     projectDir_(ppf.projectDir_),
00367     wedgePlane_(ppf.wedgePlane_),
00368     frozenPointsZone_(ppf.frozenPointsZone_)
00369 {}
00370 
00371 
00372 surfaceDisplacementPointPatchVectorField::
00373 surfaceDisplacementPointPatchVectorField
00374 (
00375     const surfaceDisplacementPointPatchVectorField& ppf
00376 )
00377 :
00378     fixedValuePointPatchVectorField(ppf),
00379     velocity_(ppf.velocity_),
00380     surfacesDict_(ppf.surfacesDict_),
00381     projectMode_(ppf.projectMode_),
00382     projectDir_(ppf.projectDir_),
00383     wedgePlane_(ppf.wedgePlane_),
00384     frozenPointsZone_(ppf.frozenPointsZone_)
00385 {}
00386 
00387 
00388 surfaceDisplacementPointPatchVectorField::
00389 surfaceDisplacementPointPatchVectorField
00390 (
00391     const surfaceDisplacementPointPatchVectorField& ppf,
00392     const DimensionedField<vector, pointMesh>& iF
00393 )
00394 :
00395     fixedValuePointPatchVectorField(ppf, iF),
00396     velocity_(ppf.velocity_),
00397     surfacesDict_(ppf.surfacesDict_),
00398     projectMode_(ppf.projectMode_),
00399     projectDir_(ppf.projectDir_),
00400     wedgePlane_(ppf.wedgePlane_),
00401     frozenPointsZone_(ppf.frozenPointsZone_)
00402 {}
00403 
00404 
00405 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00406 
00407 const searchableSurfaces&
00408 surfaceDisplacementPointPatchVectorField::surfaces() const
00409 {
00410     if (surfacesPtr_.empty())
00411     {
00412         surfacesPtr_.reset
00413         (
00414             new searchableSurfaces
00415             (
00416                 IOobject
00417                 (
00418                     "abc",                              // dummy name
00419                     db().time().constant(),             // directory
00420                     "triSurface",                       // instance
00421                     db().time(),                        // registry
00422                     IOobject::MUST_READ,
00423                     IOobject::NO_WRITE
00424                 ),
00425                 surfacesDict_
00426             )
00427         );
00428     }
00429     return surfacesPtr_();
00430 }
00431 
00432 
00433 void surfaceDisplacementPointPatchVectorField::updateCoeffs()
00434 {
00435     if (this->updated())
00436     {
00437         return;
00438     }
00439 
00440     const polyMesh& mesh = patch().boundaryMesh().mesh()();
00441 
00442     vectorField currentDisplacement = this->patchInternalField();
00443 
00444     // Calculate intersections with surface w.r.t points0.
00445     vectorField displacement(currentDisplacement);
00446     calcProjection(displacement);
00447 
00448     // offset wrt current displacement
00449     vectorField offset = displacement-currentDisplacement;
00450 
00451     // Clip offset to maximum displacement possible: velocity*timestep
00452 
00453     const scalar deltaT = mesh.time().deltaT().value();
00454     const vector clipVelocity = velocity_*deltaT;
00455 
00456     forAll(displacement, i)
00457     {
00458         vector& d = offset[i];
00459 
00460         for (direction cmpt = 0; cmpt < vector::nComponents; cmpt++)
00461         {
00462             if (d[cmpt] < 0)
00463             {
00464                 d[cmpt] = max(d[cmpt], -clipVelocity[cmpt]);
00465             }
00466             else
00467             {
00468                 d[cmpt] = min(d[cmpt], clipVelocity[cmpt]);
00469             }
00470         }
00471     }
00472 
00473     this->operator==(currentDisplacement+offset);
00474 
00475     fixedValuePointPatchVectorField::updateCoeffs();
00476 }
00477 
00478 
00479 void surfaceDisplacementPointPatchVectorField::write(Ostream& os) const
00480 {
00481     fixedValuePointPatchVectorField::write(os);
00482     os.writeKeyword("velocity") << velocity_
00483         << token::END_STATEMENT << nl;
00484     os.writeKeyword("geometry") << surfacesDict_
00485         << token::END_STATEMENT << nl;
00486     os.writeKeyword("projectMode") << projectModeNames_[projectMode_]
00487         << token::END_STATEMENT << nl;
00488     os.writeKeyword("projectDirection") << projectDir_
00489         << token::END_STATEMENT << nl;
00490     os.writeKeyword("wedgePlane") << wedgePlane_
00491         << token::END_STATEMENT << nl;
00492     if (frozenPointsZone_ != word::null)
00493     {
00494         os.writeKeyword("frozenPointsZone") << frozenPointsZone_
00495             << token::END_STATEMENT << nl;
00496     }
00497 }
00498 
00499 
00500 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00501 
00502 makePointPatchTypeField
00503 (
00504     fixedValuePointPatchVectorField,
00505     surfaceDisplacementPointPatchVectorField
00506 );
00507 
00508 
00509 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00510 
00511 } // End namespace Foam
00512 
00513 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines