00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
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
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
00067
00068
00069
00070
00071
00072 const scalar projectLen = mag(mesh.bounds().max()-mesh.bounds().min());
00073
00074
00075 vector projectVec;
00076 if (projectMode_ == FIXEDNORMAL)
00077 {
00078 vector n = projectDir_/mag(projectDir_);
00079 projectVec = projectLen*n;
00080 }
00081
00082
00083
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
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
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
00154
00155
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
00169
00170 vectorField projectVecs(start.size(), projectVec);
00171
00172 if (projectMode_ == POINTNORMAL)
00173 {
00174 projectVecs = projectLen*patch().pointNormals();
00175 }
00176
00177
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
00214 forAll(displacement, i)
00215 {
00216 if (zonePtr && (zonePtr->whichPoint(meshPoints[i]) >= 0))
00217 {
00218
00219 displacement[i] = points0[meshPoints[i]] - localPoints[i];
00220 }
00221 else if (nearest[i].hit())
00222 {
00223
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
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
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",
00419 db().time().constant(),
00420 "triSurface",
00421 db().time(),
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
00445 vectorField displacement(currentDisplacement);
00446 calcProjection(displacement);
00447
00448
00449 vectorField offset = displacement-currentDisplacement;
00450
00451
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 }
00512
00513