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 "motionSmoother.H"
00027 #include <meshTools/meshTools.H>
00028 #include <OpenFOAM/processorPointPatchFields.H>
00029 #include <OpenFOAM/globalPointPatchFields.H>
00030 #include <OpenFOAM/pointConstraint.H>
00031 #include <OpenFOAM/syncTools.H>
00032
00033
00034
00035 template<class Type>
00036 void Foam::motionSmoother::checkConstraints
00037 (
00038 GeometricField<Type, pointPatchField, pointMesh>& pf
00039 )
00040 {
00041 typedef GeometricField<Type, pointPatchField, pointMesh> FldType;
00042
00043 const polyMesh& mesh = pf.mesh();
00044
00045 const polyBoundaryMesh& bm = mesh.boundaryMesh();
00046
00047
00048
00049 label nPatchPatchPoints = 0;
00050
00051 forAll(bm, patchi)
00052 {
00053 if(!isA<emptyPolyPatch>(bm[patchi]))
00054 {
00055 nPatchPatchPoints += bm[patchi].boundaryPoints().size();
00056 }
00057 }
00058
00059
00060 typename FldType::GeometricBoundaryField& bFld = pf.boundaryField();
00061
00062
00063
00064
00065 forAllReverse(bFld, patchi)
00066 {
00067 bFld[patchi].initEvaluate(Pstream::blocking);
00068 }
00069
00070 forAllReverse(bFld, patchi)
00071 {
00072 bFld[patchi].evaluate(Pstream::blocking);
00073 }
00074
00075
00076
00077
00078 Field<Type> boundaryPointValues(nPatchPatchPoints);
00079 nPatchPatchPoints = 0;
00080
00081 forAll(bm, patchi)
00082 {
00083 if(!isA<emptyPolyPatch>(bm[patchi]))
00084 {
00085 const labelList& bp = bm[patchi].boundaryPoints();
00086 const labelList& meshPoints = bm[patchi].meshPoints();
00087
00088 forAll(bp, pointi)
00089 {
00090 label ppp = meshPoints[bp[pointi]];
00091 boundaryPointValues[nPatchPatchPoints++] = pf[ppp];
00092 }
00093 }
00094 }
00095
00096
00097
00098
00099 bFld.evaluate();
00100
00101
00102
00103
00104 nPatchPatchPoints = 0;
00105
00106 forAll(bm, patchi)
00107 {
00108 if(!isA<emptyPolyPatch>(bm[patchi]))
00109 {
00110 const labelList& bp = bm[patchi].boundaryPoints();
00111 const labelList& meshPoints = bm[patchi].meshPoints();
00112
00113 forAll(bp, pointi)
00114 {
00115 label ppp = meshPoints[bp[pointi]];
00116
00117 const Type& savedVal = boundaryPointValues[nPatchPatchPoints++];
00118
00119 if (savedVal != pf[ppp])
00120 {
00121 FatalErrorIn
00122 (
00123 "motionSmoother::checkConstraints"
00124 "(GeometricField<Type, pointPatchField, pointMesh>&)"
00125 ) << "Patch fields are not consistent on mesh point "
00126 << ppp << " coordinate " << mesh.points()[ppp]
00127 << " at patch " << bm[patchi].name() << '.'
00128 << endl
00129 << "Reverse evaluation gives value " << savedVal
00130 << " , forward evaluation gives value " << pf[ppp]
00131 << abort(FatalError);
00132 }
00133 }
00134 }
00135 }
00136 }
00137
00138
00139 template<class Type>
00140 void Foam::motionSmoother::applyCornerConstraints
00141 (
00142 GeometricField<Type, pointPatchField, pointMesh>& pf
00143 ) const
00144 {
00145 forAll(patchPatchPointConstraintPoints_, pointi)
00146 {
00147 pf[patchPatchPointConstraintPoints_[pointi]] = transform
00148 (
00149 patchPatchPointConstraintTensors_[pointi],
00150 pf[patchPatchPointConstraintPoints_[pointi]]
00151 );
00152 }
00153 }
00154
00155
00156
00157 template <class Type>
00158 Foam::tmp<Foam::GeometricField<Type, Foam::pointPatchField, Foam::pointMesh> >
00159 Foam::motionSmoother::avg
00160 (
00161 const GeometricField<Type, pointPatchField, pointMesh>& fld,
00162 const scalarField& edgeWeight,
00163 const bool separation
00164 ) const
00165 {
00166 tmp<GeometricField<Type, pointPatchField, pointMesh> > tres
00167 (
00168 new GeometricField<Type, pointPatchField, pointMesh>
00169 (
00170 IOobject
00171 (
00172 "avg("+fld.name()+')',
00173 fld.time().timeName(),
00174 fld.db(),
00175 IOobject::NO_READ,
00176 IOobject::NO_WRITE
00177 ),
00178 fld.mesh(),
00179 dimensioned<Type>("zero", fld.dimensions(), pTraits<Type>::zero)
00180 )
00181 );
00182 GeometricField<Type, pointPatchField, pointMesh>& res = tres();
00183
00184 const polyMesh& mesh = fld.mesh()();
00185
00186
00187
00188
00189
00190
00191
00192
00193 scalarField sumWeight(mesh.nPoints(), 0.0);
00194
00195 const edgeList& edges = mesh.edges();
00196
00197 forAll(edges, edgeI)
00198 {
00199 if (isMasterEdge_.get(edgeI) == 1)
00200 {
00201 const edge& e = edges[edgeI];
00202 const scalar w = edgeWeight[edgeI];
00203
00204 res[e[0]] += w*fld[e[1]];
00205 sumWeight[e[0]] += w;
00206
00207 res[e[1]] += w*fld[e[0]];
00208 sumWeight[e[1]] += w;
00209 }
00210 }
00211
00212
00213
00214
00215
00216 syncTools::syncPointList
00217 (
00218 mesh,
00219 res,
00220 plusEqOp<Type>(),
00221 pTraits<Type>::zero,
00222 separation
00223 );
00224
00225 syncTools::syncPointList
00226 (
00227 mesh,
00228 sumWeight,
00229 plusEqOp<scalar>(),
00230 scalar(0),
00231 false
00232 );
00233
00234
00235
00236
00237
00238 forAll(res, pointI)
00239 {
00240 if (mag(sumWeight[pointI]) < VSMALL)
00241 {
00242
00243 res[pointI] = fld[pointI];
00244 }
00245 else
00246 {
00247 res[pointI] /= sumWeight[pointI];
00248 }
00249 }
00250
00251 res.correctBoundaryConditions();
00252 applyCornerConstraints(res);
00253
00254 return tres;
00255 }
00256
00257
00258
00259 template <class Type>
00260 void Foam::motionSmoother::smooth
00261 (
00262 const GeometricField<Type, pointPatchField, pointMesh>& fld,
00263 const scalarField& edgeWeight,
00264 const bool separation,
00265 GeometricField<Type, pointPatchField, pointMesh>& newFld
00266 ) const
00267 {
00268 tmp<pointVectorField> tavgFld = avg
00269 (
00270 fld,
00271 edgeWeight,
00272 separation
00273 );
00274 const pointVectorField& avgFld = tavgFld();
00275
00276 forAll(fld, pointI)
00277 {
00278 if (isInternalPoint(pointI))
00279 {
00280 newFld[pointI] = 0.5*fld[pointI] + 0.5*avgFld[pointI];
00281 }
00282 }
00283
00284 newFld.correctBoundaryConditions();
00285 applyCornerConstraints(newFld);
00286 }
00287
00288
00289
00290 template<class Type, class CombineOp>
00291 void Foam::motionSmoother::testSyncField
00292 (
00293 const Field<Type>& fld,
00294 const CombineOp& cop,
00295 const Type& zero,
00296 const bool separation,
00297 const scalar maxMag
00298 ) const
00299 {
00300 if (debug)
00301 {
00302 Pout<< "testSyncField : testing synchronisation of Field<Type>."
00303 << endl;
00304 }
00305
00306 Field<Type> syncedFld(fld);
00307
00308 syncTools::syncPointList
00309 (
00310 mesh_,
00311 syncedFld,
00312 cop,
00313 zero,
00314 separation
00315 );
00316
00317 forAll(syncedFld, i)
00318 {
00319 if (mag(syncedFld[i] - fld[i]) > maxMag)
00320 {
00321 FatalErrorIn
00322 (
00323 "motionSmoother::testSyncField"
00324 "(const Field<Type>&, const CombineOp&"
00325 ", const Type&, const bool)"
00326 ) << "On element " << i << " value:" << fld[i]
00327 << " synchronised value:" << syncedFld[i]
00328 << abort(FatalError);
00329 }
00330 }
00331 }
00332
00333
00334