Go to the documentation of this file.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 "displacementInterpolationFvMotionSolver.H"
00027 #include <OpenFOAM/addToRunTimeSelectionTable.H>
00028 #include <OpenFOAM/SortableList.H>
00029 #include <OpenFOAM/IOList.H>
00030 #include <OpenFOAM/Tuple2.H>
00031 #include <OpenFOAM/mapPolyMesh.H>
00032 #include <OpenFOAM/interpolateXY.H>
00033
00034
00035
00036 namespace Foam
00037 {
00038 defineTypeNameAndDebug(displacementInterpolationFvMotionSolver, 0);
00039
00040 addToRunTimeSelectionTable
00041 (
00042 fvMotionSolver,
00043 displacementInterpolationFvMotionSolver,
00044 dictionary
00045 );
00046
00047 template<>
00048 const word IOList<Tuple2<scalar, vector> >::typeName("scalarVectorTable");
00049 }
00050
00051
00052
00053
00054
00055
00056 Foam::displacementInterpolationFvMotionSolver::
00057 displacementInterpolationFvMotionSolver
00058 (
00059 const polyMesh& mesh,
00060 Istream& is
00061 )
00062 :
00063 displacementFvMotionSolver(mesh, is),
00064 dynamicMeshCoeffs_
00065 (
00066 IOdictionary
00067 (
00068 IOobject
00069 (
00070 "dynamicMeshDict",
00071 mesh.time().constant(),
00072 mesh,
00073 IOobject::MUST_READ,
00074 IOobject::NO_WRITE,
00075 false
00076 )
00077 ).subDict(typeName + "Coeffs")
00078 )
00079 {
00080
00081
00082
00083 List<Pair<word> > faceZoneToTable
00084 (
00085 dynamicMeshCoeffs_.lookup("interpolationTables")
00086 );
00087
00088 const faceZoneMesh& fZones = mesh.faceZones();
00089
00090 times_.setSize(fZones.size());
00091 displacements_.setSize(fZones.size());
00092
00093 forAll(faceZoneToTable, i)
00094 {
00095 const word& zoneName = faceZoneToTable[i][0];
00096 label zoneI = fZones.findZoneID(zoneName);
00097
00098 if (zoneI == -1)
00099 {
00100 FatalErrorIn
00101 (
00102 "displacementInterpolationFvMotionSolver::"
00103 "displacementInterpolationFvMotionSolver(const polyMesh&,"
00104 "Istream&)"
00105 ) << "Cannot find zone " << zoneName << endl
00106 << "Valid zones are " << mesh.faceZones().names()
00107 << exit(FatalError);
00108 }
00109
00110 const word& tableName = faceZoneToTable[i][1];
00111
00112 IOList<Tuple2<scalar, vector> > table
00113 (
00114 IOobject
00115 (
00116 tableName,
00117 mesh.time().constant(),
00118 "tables",
00119 mesh,
00120 IOobject::MUST_READ,
00121 IOobject::NO_WRITE,
00122 false
00123 )
00124 );
00125
00126
00127 times_[zoneI].setSize(table.size());
00128 displacements_[zoneI].setSize(table.size());
00129
00130 forAll(table, j)
00131 {
00132 times_[zoneI][j] = table[j].first();
00133 displacements_[zoneI][j] = table[j].second();
00134 }
00135 }
00136
00137
00138
00139
00140
00141
00142
00143 for (direction dir = 0; dir < vector::nComponents; dir++)
00144 {
00145
00146 SortableList<scalar> zoneCoordinates(2*faceZoneToTable.size());
00147
00148 forAll(faceZoneToTable, i)
00149 {
00150 const word& zoneName = faceZoneToTable[i][0];
00151 label zoneI = fZones.findZoneID(zoneName);
00152 const faceZone& fz = fZones[zoneI];
00153
00154 scalar minCoord = VGREAT;
00155 scalar maxCoord = -VGREAT;
00156
00157 forAll(fz().meshPoints(), localI)
00158 {
00159 label pointI = fz().meshPoints()[localI];
00160 const scalar coord = points0()[pointI][dir];
00161 minCoord = min(minCoord, coord);
00162 maxCoord = max(maxCoord, coord);
00163 }
00164
00165 zoneCoordinates[2*i] = returnReduce(minCoord, minOp<scalar>());
00166 zoneCoordinates[2*i+1] = returnReduce(maxCoord, maxOp<scalar>());
00167
00168 if (debug)
00169 {
00170 Pout<< "direction " << dir << " : "
00171 << "zone " << zoneName
00172 << " ranges from coordinate " << zoneCoordinates[2*i]
00173 << " to " << zoneCoordinates[2*i+1]
00174 << endl;
00175 }
00176 }
00177 zoneCoordinates.sort();
00178
00179
00180 zoneCoordinates[0] -= SMALL;
00181 zoneCoordinates[zoneCoordinates.size()-1] += SMALL;
00182
00183
00184 const scalarField meshCoords = points0().component(dir);
00185
00186 scalar minCoord = gMin(meshCoords);
00187 scalar maxCoord = gMax(meshCoords);
00188
00189 if (debug)
00190 {
00191 Pout<< "direction " << dir << " : "
00192 << "mesh ranges from coordinate " << minCoord << " to "
00193 << maxCoord << endl;
00194 }
00195
00196
00197
00198
00199
00200 labelList& rangeZone = rangeToZone_[dir];
00201 labelListList& rangePoints = rangeToPoints_[dir];
00202 List<scalarField>& rangeWeights = rangeToWeights_[dir];
00203
00204 scalarField rangeToCoord(zoneCoordinates.size());
00205 rangeZone.setSize(zoneCoordinates.size());
00206 label rangeI = 0;
00207
00208 if (minCoord < zoneCoordinates[0])
00209 {
00210 label sz = rangeZone.size();
00211 rangeToCoord.setSize(sz+1);
00212 rangeZone.setSize(sz+1);
00213 rangeToCoord[rangeI] = minCoord-SMALL;
00214 rangeZone[rangeI] = -1;
00215
00216 if (debug)
00217 {
00218 Pout<< "direction " << dir << " : "
00219 << "range " << rangeI << " at coordinate "
00220 << rangeToCoord[rangeI] << " from min of mesh "
00221 << rangeZone[rangeI] << endl;
00222 }
00223 rangeI = 1;
00224 }
00225 forAll(zoneCoordinates, i)
00226 {
00227 rangeToCoord[rangeI] = zoneCoordinates[i];
00228 rangeZone[rangeI] = zoneCoordinates.indices()[i]/2;
00229
00230 if (debug)
00231 {
00232 Pout<< "direction " << dir << " : "
00233 << "range " << rangeI << " at coordinate "
00234 << rangeToCoord[rangeI]
00235 << " from zone " << rangeZone[rangeI] << endl;
00236 }
00237 rangeI++;
00238 }
00239 if (maxCoord > zoneCoordinates[zoneCoordinates.size()-1])
00240 {
00241 label sz = rangeToCoord.size();
00242 rangeToCoord.setSize(sz+1);
00243 rangeZone.setSize(sz+1);
00244 rangeToCoord[sz] = maxCoord+SMALL;
00245 rangeZone[sz] = -1;
00246
00247 if (debug)
00248 {
00249 Pout<< "direction " << dir << " : "
00250 << "range " << rangeI << " at coordinate "
00251 << rangeToCoord[sz] << " from max of mesh "
00252 << rangeZone[sz] << endl;
00253 }
00254 }
00255
00256
00257
00258
00259
00260
00261 labelList nRangePoints(rangeToCoord.size(), 0);
00262
00263 forAll(meshCoords, pointI)
00264 {
00265 label rangeI = findLower(rangeToCoord, meshCoords[pointI]);
00266
00267 if (rangeI == -1 || rangeI == rangeToCoord.size()-1)
00268 {
00269 FatalErrorIn
00270 (
00271 "displacementInterpolationFvMotionSolver::"
00272 "displacementInterpolationFvMotionSolver"
00273 "(const polyMesh&, Istream&)"
00274 ) << "Did not find point " << points0()[pointI]
00275 << " coordinate " << meshCoords[pointI]
00276 << " in ranges " << rangeToCoord
00277 << abort(FatalError);
00278 }
00279 nRangePoints[rangeI]++;
00280 }
00281
00282 if (debug)
00283 {
00284 for (label rangeI = 0; rangeI < rangeToCoord.size()-1; rangeI++)
00285 {
00286
00287 Pout<< "direction " << dir << " : "
00288 << "range from " << rangeToCoord[rangeI]
00289 << " to " << rangeToCoord[rangeI+1]
00290 << " contains " << nRangePoints[rangeI]
00291 << " points." << endl;
00292 }
00293 }
00294
00295
00296 rangePoints.setSize(nRangePoints.size());
00297 rangeWeights.setSize(nRangePoints.size());
00298 forAll(rangePoints, rangeI)
00299 {
00300 rangePoints[rangeI].setSize(nRangePoints[rangeI]);
00301 rangeWeights[rangeI].setSize(nRangePoints[rangeI]);
00302 }
00303 nRangePoints = 0;
00304 forAll(meshCoords, pointI)
00305 {
00306 label rangeI = findLower(rangeToCoord, meshCoords[pointI]);
00307 label& nPoints = nRangePoints[rangeI];
00308 rangePoints[rangeI][nPoints] = pointI;
00309 rangeWeights[rangeI][nPoints] =
00310 (meshCoords[pointI]-rangeToCoord[rangeI])
00311 / (rangeToCoord[rangeI+1]-rangeToCoord[rangeI]);
00312 nPoints++;
00313 }
00314 }
00315 }
00316
00317
00318
00319
00320 Foam::displacementInterpolationFvMotionSolver::
00321 ~displacementInterpolationFvMotionSolver()
00322 {}
00323
00324
00325
00326
00327 Foam::tmp<Foam::pointField>
00328 Foam::displacementInterpolationFvMotionSolver::curPoints() const
00329 {
00330 if (mesh().nPoints() != points0().size())
00331 {
00332 FatalErrorIn
00333 (
00334 "displacementInterpolationFvMotionSolver::curPoints() const"
00335 ) << "The number of points in the mesh seems to have changed." << endl
00336 << "In constant/polyMesh there are " << points0().size()
00337 << " points; in the current mesh there are " << mesh().nPoints()
00338 << " points." << exit(FatalError);
00339 }
00340
00341 tmp<pointField> tcurPoints(new pointField(points0()));
00342 pointField& curPoints = tcurPoints();
00343
00344
00345 vectorField zoneDisp(displacements_.size(), vector::zero);
00346 forAll(zoneDisp, zoneI)
00347 {
00348 if (times_[zoneI].size())
00349 {
00350 zoneDisp[zoneI] = interpolateXY
00351 (
00352 mesh().time().value(),
00353 times_[zoneI],
00354 displacements_[zoneI]
00355 );
00356 }
00357 }
00358 if (debug)
00359 {
00360 Pout<< "Zone displacements:" << zoneDisp << endl;
00361 }
00362
00363
00364
00365 for (direction dir = 0; dir < vector::nComponents; dir++)
00366 {
00367 const labelList& rangeZone = rangeToZone_[dir];
00368 const labelListList& rangePoints = rangeToPoints_[dir];
00369 const List<scalarField>& rangeWeights = rangeToWeights_[dir];
00370
00371 for (label rangeI = 0; rangeI < rangeZone.size()-1; rangeI++)
00372 {
00373 const labelList& rPoints = rangePoints[rangeI];
00374 const scalarField& rWeights = rangeWeights[rangeI];
00375
00376
00377 label minZoneI = rangeZone[rangeI];
00378
00379
00380 scalar minDisp = (minZoneI == -1 ? 0.0 : zoneDisp[minZoneI][dir]);
00381 label maxZoneI = rangeZone[rangeI+1];
00382
00383
00384 scalar maxDisp = (maxZoneI == -1 ? 0.0 : zoneDisp[maxZoneI][dir]);
00385
00386 forAll(rPoints, i)
00387 {
00388 label pointI = rPoints[i];
00389 scalar w = rWeights[i];
00390
00391 curPoints[pointI][dir] += (1.0-w)*minDisp+w*maxDisp;
00392 }
00393 }
00394 }
00395 return tcurPoints;
00396 }
00397
00398
00399