void Foam::steadyStateControl::maxTypeResidual ( const word& fieldName, ITstream& data, scalar& firstRes, scalar& lastRes ) const { typedef GeometricField<Type, fvPatchField, volMesh> fieldType; if (mesh_.foundObject<fieldType>(fieldName)) { //fieldType& pointVelocity = const_cast<fieldType&>( // mesh_.objectRegistry::lookupObject<fieldType>( fieldName ) //); fieldType& field = const_cast<fieldType&>( mesh_.lookupObject<fieldType>( fieldName ) ); const List<SolverPerformance<Type> > sp(data); int sz = field.size(); reduce(sz, sumOp<int>()); Type nF = gSumCmptProd( field, field ) / static_cast<double>(sz); //Type finiR = sp.first().initialResidual(); //Type liniR = sp.last().initialResidual(); // scalar norm = mag(nF); for (direction cmpt=0; cmpt < nF.size(); cmpt++){ nF[cmpt] = sqrt( nF[cmpt] ); //finiR[cmpt] *= tmpNF; //liniR[cmpt] *= tmpNF; } nF = nF/norm; //finiR /= norm; //liniR /= norm; //firstRes = cmptMax(finiR); //lastRes = cmptMax(liniR); // firstRes = cmptMax( cmptMultiply(sp.first().initialResidual(), nF) ); lastRes = cmptMax( cmptMultiply(sp.last().initialResidual(), nF) ); //firstRes = cmptMax(sp.first().initialResidual()); //lastRes = cmptMax(sp.last().initialResidual()); } }
Foam::faceAreaPairGAMGAgglomeration::faceAreaPairGAMGAgglomeration ( const lduMesh& mesh, const scalarField& cellVolumes, const vectorField& faceAreas, const dictionary& controlDict ) : pairGAMGAgglomeration(mesh, controlDict) { // agglomerate(mesh, sqrt(mag(faceAreas))); agglomerate ( mesh, mag ( cmptMultiply ( faceAreas /sqrt(mag(faceAreas)), vector(1, 1.01, 1.02) // vector::one ) ) ); }
vector horizontalVelocityField::streamfunctionAt ( const point& p, const Time& t ) const { const vector unitNormal(0, -1, 0); const dimensionedScalar z("z", dimLength, p.z()); dimensionedScalar psi("psi", cmptMultiply(dimVelocity, dimLength), scalar(0)); if (z.value() <= z1.value()) { // psi is zero } else if (z.value() <= z2.value()) { psi = -0.5*u0*(z - z1 - (z2-z1)/M_PI*Foam::sin(M_PI*(z-z1)/(z2-z1))); } else { psi = -0.5*u0*(2*z - z2 - z1); } return unitNormal * psi.value(); }
bool Foam::SolverPerformance<Type>::checkConvergence ( const Type& Tolerance, const Type& RelTolerance ) { if (debug >= 2) { Info<< solverName_ << ": Iteration " << nIterations_ << " residual = " << finalResidual_ << endl; } if ( finalResidual_ < Tolerance || ( RelTolerance > small_*pTraits<Type>::one && finalResidual_ < cmptMultiply(RelTolerance, initialResidual_) ) ) { converged_ = true; } else { converged_ = false; } return converged_; }
Foam::tmp<Foam::Field<Type>> Foam::transformFvPatchField<Type>::gradientBoundaryCoeffs() const { return snGrad() - cmptMultiply(gradientInternalCoeffs(), this->patchInternalField()); }
Foam::faceAreaPairGAMGAgglomeration::faceAreaPairGAMGAgglomeration ( const lduMesh& mesh, const dictionary& controlDict ) : pairGAMGAgglomeration(mesh, controlDict) { const fvMesh& fvmesh = refCast<const fvMesh>(mesh); //agglomerate(mesh, sqrt(fvmesh.magSf().internalField())); agglomerate ( mesh, mag ( cmptMultiply ( fvmesh.Sf().internalField() /sqrt(fvmesh.magSf().internalField()), vector(1, 1.01, 1.02) //vector::one ) ) ); }
void Foam::directionalDiffusivity::correct() { const fvMesh& mesh = mSolver().mesh(); surfaceVectorField n = mesh.Sf()/mesh.magSf(); faceDiffusivity_ == (n & cmptMultiply(diffusivityVector_, n)); }
void Foam::displacementMotionSolver::updateMesh(const mapPolyMesh& mpm) { // pointMesh already updates pointFields motionSolver::updateMesh(mpm); // Map points0_. Bit special since we somehow have to come up with // a sensible points0 position for introduced points. // Find out scaling between points0 and current points // Get the new points either from the map or the mesh const pointgpuField& points = ( mpm.hasMotionPoints() ? mpm.preMotionPoints() : mesh().points() ); // Note: boundBox does reduce const vector span0 = boundBox(points0_).span(); const vector span = boundBox(points).span(); vector scaleFactors(cmptDivide(span0, span)); pointField newPoints0(mpm.pointMap().size()); forAll(newPoints0, pointI) { label oldPointI = mpm.pointMap()[pointI]; if (oldPointI >= 0) { label masterPointI = mpm.reversePointMap()[oldPointI]; if (masterPointI == pointI) { newPoints0[pointI] = points0_[oldPointI]; } else { // New point - assume motion is scaling newPoints0[pointI] = points0_[oldPointI] + cmptMultiply ( scaleFactors, points[pointI] - points[masterPointI] ); } } else { FatalErrorIn ( "displacementMotionSolver::updateMesh" "(const mapPolyMesh&)" ) << "Cannot determine co-ordinates of introduced vertices." << " New vertex " << pointI << " at co-ordinate " << points[pointI] << exit(FatalError); } }
Type projection ( const GeometricField<Type, fvPatchField, volMesh>& a, const GeometricField<Type, fvPatchField, volMesh>& b ) { return sum(cmptMultiply(a.internalField(), b.internalField())); }
tmp<Field<Type> > transformFaPatchField<Type>::valueBoundaryCoeffs ( const tmp<scalarField>& ) const { return *this - cmptMultiply ( valueInternalCoeffs(this->patch().weights()), this->patchInternalField() ); }
void implicitExtrapolationFvPatchField<Type>::updateCoeffs(){ Field<Type>& boundaryField = *this; // will be set from old time-step const Field<Type>& internalField = this->internalField(); const fvMesh& m = this->patch().boundaryMesh().mesh(); const scalarField& d1 = this->patch().deltaCoeffs(); const scalarField& d2 = secondDeltas; const scalarField d1_dividedBy_d2 = (1/d1)/d2; const Field<Type> oneField = Field<Type>(this->size(), pTraits<Type>::one); const labelList& faceCells = this->patch().faceCells(); internalCoeffsDiag = (1 + d1_dividedBy_d2 ) * oneField; forAll(boundaryField, i){ if(secondNormalCellIsOwner[i]){ internalCoeffsLower[i] = - d1_dividedBy_d2[i] * oneField[i]; internalCoeffsUpper[i] = 0 * oneField[i]; const label boundaryCell = faceCells[i]; const label secondCell = m.owner()[secondFaces()[i]]; boundaryField[i] = cmptMultiply(internalCoeffsDiag[i],internalField[boundaryCell]) + cmptMultiply(internalCoeffsLower[i],internalField[secondCell]); } else{ internalCoeffsLower[i] = 0 * oneField[i]; internalCoeffsUpper[i] = - d1_dividedBy_d2[i] * oneField[i]; const label boundaryCell = faceCells[i]; const label secondCell = m.neighbour()[secondFaces()[i]]; boundaryField[i] = cmptMultiply(internalCoeffsDiag[i],internalField[boundaryCell]) + cmptMultiply(internalCoeffsUpper[i],internalField[secondCell]); } } fvPatchField<Type>::updateCoeffs(); }
void Foam::processorBlockGAMGInterfaceField<Type>::updateInterfaceMatrix ( const Field<Type>& psiInternal, Field<Type>& result, const BlockLduMatrix<Type>&, const CoeffField<Type>& coeffs, const Pstream::commsTypes commsType, const bool switchToLhs ) const { Field<Type> pnf ( coeffs.size() ); if (coeffs.activeType() == blockCoeffBase::SCALAR) { pnf = coeffs.asScalar()* procInterface_.compressedReceive<Type>(commsType, this->size())(); } else if (coeffs.activeType() == blockCoeffBase::LINEAR) { pnf = cmptMultiply ( coeffs.asLinear(), procInterface_.compressedReceive<Type>(commsType, this->size())() ); } else if (coeffs.activeType() == blockCoeffBase::SQUARE) { pnf = coeffs.asSquare() & procInterface_.compressedReceive<Type>(commsType, this->size())(); } const unallocLabelList& faceCells = procInterface_.faceCells(); if (switchToLhs) { forAll(faceCells, elemI) { result[faceCells[elemI]] += pnf[elemI]; } } else {
void Foam::motionDirectionalDiffusivity::correct() { const fvMesh& mesh = mSolver().mesh(); static bool first = true; if (!first) { const volVectorField& cellMotionU = mesh.lookupObject<volVectorField>("cellMotionU"); volVectorField D ( IOobject ( "D", mesh.time().timeName(), mesh ), diffusivityVector_.y()*vector::one + (diffusivityVector_.x() - diffusivityVector_.y())*cellMotionU /(mag(cellMotionU) + dimensionedScalar("small", dimVelocity, SMALL)), zeroGradientFvPatchVectorField::typeName ); D.correctBoundaryConditions(); surfaceVectorField n = mesh.Sf()/mesh.magSf(); faceDiffusivity_ == (n & cmptMultiply(fvc::interpolate(D), n)); } else { first = false; const_cast<fvMotionSolver&>(mSolver()).solve(); correct(); } }
typename Foam::SolverPerformance<Type> Foam::PCICG<Type, DType, LUType>::solve(Field<Type>& psi) const { word preconditionerName(this->controlDict_.lookup("preconditioner")); // --- Setup class containing solver performance data SolverPerformance<Type> solverPerf ( preconditionerName + typeName, this->fieldName_ ); label nCells = psi.size(); Type* __restrict__ psiPtr = psi.begin(); Field<Type> pA(nCells); Type* __restrict__ pAPtr = pA.begin(); Field<Type> wA(nCells); Type* __restrict__ wAPtr = wA.begin(); Type wArA = solverPerf.great_*pTraits<Type>::one; Type wArAold = wArA; // --- Calculate A.psi this->matrix_.Amul(wA, psi); // --- Calculate initial residual field Field<Type> rA(this->matrix_.source() - wA); Type* __restrict__ rAPtr = rA.begin(); // --- Calculate normalisation factor Type normFactor = this->normFactor(psi, wA, pA); if (LduMatrix<Type, DType, LUType>::debug >= 2) { Info<< " Normalisation factor = " << normFactor << endl; } // --- Calculate normalised residual norm solverPerf.initialResidual() = cmptDivide(gSumCmptMag(rA), normFactor); solverPerf.finalResidual() = solverPerf.initialResidual(); // --- Check convergence, solve if not converged if ( this->minIter_ > 0 || !solverPerf.checkConvergence(this->tolerance_, this->relTol_) ) { // --- Select and construct the preconditioner autoPtr<typename LduMatrix<Type, DType, LUType>::preconditioner> preconPtr = LduMatrix<Type, DType, LUType>::preconditioner::New ( *this, this->controlDict_ ); // --- Solver iteration do { // --- Store previous wArA wArAold = wArA; // --- Precondition residual preconPtr->precondition(wA, rA); // --- Update search directions: wArA = gSumCmptProd(wA, rA); if (solverPerf.nIterations() == 0) { for (label cell=0; cell<nCells; cell++) { pAPtr[cell] = wAPtr[cell]; } } else { Type beta = cmptDivide ( wArA, stabilise(wArAold, solverPerf.vsmall_) ); for (label cell=0; cell<nCells; cell++) { pAPtr[cell] = wAPtr[cell] + cmptMultiply(beta, pAPtr[cell]); } } // --- Update preconditioned residual this->matrix_.Amul(wA, pA); Type wApA = gSumCmptProd(wA, pA); // --- Test for singularity if ( solverPerf.checkSingularity ( cmptDivide(cmptMag(wApA), normFactor) ) ) { break; } // --- Update solution and residual: Type alpha = cmptDivide ( wArA, stabilise(wApA, solverPerf.vsmall_) ); for (label cell=0; cell<nCells; cell++) { psiPtr[cell] += cmptMultiply(alpha, pAPtr[cell]); rAPtr[cell] -= cmptMultiply(alpha, wAPtr[cell]); } solverPerf.finalResidual() = cmptDivide(gSumCmptMag(rA), normFactor); } while ( ( solverPerf.nIterations()++ < this->maxIter_ && !solverPerf.checkConvergence(this->tolerance_, this->relTol_) ) || solverPerf.nIterations() < this->minIter_ ); } return solverPerf; }
void Foam::directionalDiffusivity::correct() { const surfaceVectorField n(mesh().Sf()/mesh().magSf()); faceDiffusivity_ == (n & cmptMultiply(diffusivityVector_, n)); }
void Foam::displacementSBRStressFvMotionSolver::updateMesh ( const mapPolyMesh& mpm ) { fvMotionSolver::updateMesh(mpm); // Map points0_ // Map points0_. Bit special since we somehow have to come up with // a sensible points0 position for introduced points. // Find out scaling between points0 and current points // Get the new points either from the map or the mesh const pointField& points = ( mpm.hasMotionPoints() ? mpm.preMotionPoints() : fvMesh_.points() ); // Note: boundBox does reduce const boundBox bb0(points0_, true); const vector span0(bb0.max()-bb0.min()); const boundBox bb(points, true); const vector span(bb.max()-bb.min()); vector scaleFactors(cmptDivide(span0, span)); pointField newPoints0(mpm.pointMap().size()); forAll(newPoints0, pointI) { label oldPointI = mpm.pointMap()[pointI]; if (oldPointI >= 0) { label masterPointI = mpm.reversePointMap()[oldPointI]; if (masterPointI == pointI) { newPoints0[pointI] = points0_[oldPointI]; } else { // New point. Assume motion is scaling. newPoints0[pointI] = points0_[oldPointI] + cmptMultiply ( scaleFactors, points[pointI]-points[masterPointI] ); } } else { FatalErrorIn ( "displacementSBRStressFvMotionSolver::updateMesh" "(const mapPolyMesh& mpm)" ) << "Cannot work out coordinates of introduced vertices." << " New vertex " << pointI << " at coordinate " << points[pointI] << exit(FatalError); } }
void Foam::searchableSurfaceCollection::findNearest ( const pointField& samples, scalarField& minDistSqr, List<pointIndexHit>& nearestInfo, labelList& nearestSurf ) const { // Initialise nearestInfo.setSize(samples.size()); nearestInfo = pointIndexHit(); nearestSurf.setSize(samples.size()); nearestSurf = -1; List<pointIndexHit> hitInfo(samples.size()); const scalarField localMinDistSqr(samples.size(), GREAT); forAll(subGeom_, surfI) { subGeom_[surfI].findNearest ( cmptDivide // Transform then divide ( transform_[surfI].localPosition(samples), scale_[surfI] ), localMinDistSqr, hitInfo ); forAll(hitInfo, pointI) { if (hitInfo[pointI].hit()) { // Rework back into global coordinate sys. Multiply then // transform point globalPt = transform_[surfI].globalPosition ( cmptMultiply ( hitInfo[pointI].rawPoint(), scale_[surfI] ) ); scalar distSqr = magSqr(globalPt - samples[pointI]); if (distSqr < minDistSqr[pointI]) { minDistSqr[pointI] = distSqr; nearestInfo[pointI].setPoint(globalPt); nearestInfo[pointI].setHit(); nearestInfo[pointI].setIndex ( hitInfo[pointI].index() + indexOffset_[surfI] ); nearestSurf[pointI] = surfI; } } } }
int main(int argc, char *argv[]) { # include "setRootCase.H" # include "createTime.H" // Get times list instantList Times = runTime.times(); const label startTime = 1; const label endTime = Times.size(); const label nSnapshots = Times.size() - 1; Info << "Number of snapshots: " << nSnapshots << endl; // Create a list of snapshots PtrList<volVectorField> fields(nSnapshots); runTime.setTime(Times[startTime], startTime); # include "createMesh.H" IOdictionary PODsolverDict ( IOobject ( "PODsolverDict", runTime.system(), mesh, IOobject::MUST_READ, IOobject::NO_WRITE ) ); scalar accuracy = readScalar ( PODsolverDict.subDict("scalarTransportCoeffs").lookup("accuracy") ); Info << "Seeking accuracy: " << accuracy << endl; word fieldName ( PODsolverDict.subDict("scalarTransportCoeffs").lookup("velocity") ); label snapI = 0; labelList timeIndices(nSnapshots); for (label i = startTime; i < endTime; i++) { runTime.setTime(Times[i], i); Info<< "Time = " << runTime.timeName() << endl; mesh.readUpdate(); Info<< " Reading " << fieldName << endl; fields.set ( snapI, new volVectorField ( IOobject ( fieldName, runTime.timeName(), mesh, IOobject::MUST_READ ), mesh ) ); // Rename the field fields[snapI].rename(fieldName + name(i)); timeIndices[snapI] = i; snapI++; Info<< endl; } timeIndices.setSize(snapI); vectorPODOrthoNormalBase eb(fields, accuracy); const RectangularMatrix<vector>& coeffs = eb.interpolationCoeffs(); // Check all snapshots forAll (fields, fieldI) { runTime.setTime(Times[timeIndices[fieldI]], timeIndices[fieldI]); volVectorField reconstruct ( IOobject ( fieldName + "PODreconstruct", runTime.timeName(), mesh, IOobject::NO_READ ), mesh, dimensionedVector ( "zero", fields[fieldI].dimensions(), vector::zero ) ); for (label baseI = 0; baseI < eb.baseSize(); baseI++) { reconstruct += cmptMultiply ( eb.orthoField(baseI), coeffs[fieldI][baseI] ); } scalar sumFieldError = sumMag ( reconstruct.internalField() - fields[fieldI].internalField() ); scalar measure = sumMag(fields[fieldI].internalField()) + SMALL; Info<< "Field error: absolute = " << sumFieldError << " relative = " << sumFieldError/measure << " measure = " << measure << endl; reconstruct.write(); }