Foam::Map<Foam::label> Foam::refinementIterator::setRefinement ( const List<refineCell>& refCells ) { Map<label> addedCells(2*refCells.size()); Time& runTime = const_cast<Time&>(mesh_.time()); label nRefCells = refCells.size(); label oldRefCells = -1; // Operate on copy. List<refineCell> currentRefCells(refCells); bool stop = false; do { if (writeMesh_) { // Need different times to write meshes. runTime++; } polyTopoChange meshMod(mesh_); if (debug) { Pout<< "refinementIterator : refining " << currentRefCells.size() << " cells." << endl; } // Determine cut pattern. cellCuts cuts(mesh_, cellWalker_, currentRefCells); label nCuts = cuts.nLoops(); reduce(nCuts, sumOp<label>()); if (nCuts == 0) { if (debug) { Pout<< "refinementIterator : exiting iteration since no valid" << " loops found for " << currentRefCells.size() << " cells" << endl; fileName cutsFile("failedCuts_" + runTime.timeName() + ".obj"); Pout<< "Writing cuts for time " << runTime.timeName() << " to " << cutsFile << endl; OFstream cutsStream(cutsFile); labelList refCells(currentRefCells.size()); forAll(currentRefCells, i) { refCells[i] = currentRefCells[i].cellNo(); } meshTools::writeOBJ ( cutsStream, mesh().cells(), mesh().faces(), mesh().points(), refCells ); } break; } if (debug) { fileName cutsFile("cuts_" + runTime.timeName() + ".obj"); Pout<< "Writing cuts for time " << runTime.timeName() << " to " << cutsFile << endl; OFstream cutsStream(cutsFile); cuts.writeOBJ(cutsStream); } // Insert mesh refinement into polyTopoChange. meshRefiner_.setRefinement(cuts, meshMod); // // Do all changes // autoPtr<mapPolyMesh> morphMap = meshMod.changeMesh ( mesh_, false ); // Move mesh (since morphing does not do this) if (morphMap().hasMotionPoints()) { mesh_.movePoints(morphMap().preMotionPoints()); } // Update stored refinement pattern meshRefiner_.updateMesh(morphMap()); // Write resulting mesh if (writeMesh_) { if (debug) { Pout<< "Writing refined polyMesh to time " << runTime.timeName() << endl; } mesh_.write(); } // Update currentRefCells for new cell numbers. Use helper function // in meshCutter class. updateLabels ( morphMap->reverseCellMap(), currentRefCells ); // Update addedCells for new cell numbers updateLabels ( morphMap->reverseCellMap(), addedCells ); // Get all added cells from cellCutter (already in new numbering // from meshRefiner.updateMesh call) and add to global list of added const Map<label>& addedNow = meshRefiner_.addedCells(); for ( Map<label>::const_iterator iter = addedNow.begin(); iter != addedNow.end(); ++iter ) { if (!addedCells.insert(iter.key(), iter())) { FatalErrorIn("refinementIterator") << "Master cell " << iter.key() << " already has been refined" << endl << "Added cell:" << iter() << abort(FatalError); } } // Get failed refinement in new cell numbering and reconstruct input // to the meshRefiner. Is done by removing all refined cells from // current list of cells to refine. // Update refCells for new cell numbers. updateLabels ( morphMap->reverseCellMap(), currentRefCells ); // Pack refCells acc. to refined status nRefCells = 0; forAll(currentRefCells, refI) { const refineCell& refCell = currentRefCells[refI]; if (!addedNow.found(refCell.cellNo())) { if (nRefCells != refI) { currentRefCells[nRefCells++] = refineCell ( refCell.cellNo(), refCell.direction() ); } } } oldRefCells = currentRefCells.size(); currentRefCells.setSize(nRefCells); if (debug) { Pout<< endl; } // Stop only if all finished or all can't refine any further. stop = (nRefCells == 0) || (nRefCells == oldRefCells); reduce(stop, andOp<bool>()); } while (!stop); if (nRefCells == oldRefCells) { WarningIn("refinementIterator") << "stopped refining." << "Did not manage to refine a single cell" << endl << "Wanted :" << oldRefCells << endl; } return addedCells; }
// Coming from startEdgeI cross the edge to the other face // across to the next cut edge. bool Foam::cuttingPlane::walkCell ( const primitiveMesh& mesh, const UList<label>& edgePoint, const label cellI, const label startEdgeI, DynamicList<label>& faceVerts ) { label faceI = -1; label edgeI = startEdgeI; label nIter = 0; faceVerts.clear(); do { faceVerts.append(edgePoint[edgeI]); // Cross edge to other face faceI = meshTools::otherFace(mesh, cellI, faceI, edgeI); // Find next cut edge on face. const labelList& fEdges = mesh.faceEdges()[faceI]; label nextEdgeI = -1; //Note: here is where we should check for whether there are more // than 2 intersections with the face (warped/non-convex face). // If so should e.g. decompose the cells on both faces and redo // the calculation. forAll(fEdges, i) { label edge2I = fEdges[i]; if (edge2I != edgeI && edgePoint[edge2I] != -1) { nextEdgeI = edge2I; break; } } if (nextEdgeI == -1) { // Did not find another cut edge on faceI. Do what? WarningIn("Foam::cuttingPlane::walkCell") << "Did not find closed walk along surface of cell " << cellI << " starting from edge " << startEdgeI << " in " << nIter << " iterations." << nl << "Collected cutPoints so far:" << faceVerts << endl; return false; } edgeI = nextEdgeI; nIter++; if (nIter > 1000) { WarningIn("Foam::cuttingPlane::walkCell") << "Did not find closed walk along surface of cell " << cellI << " starting from edge " << startEdgeI << " in " << nIter << " iterations." << nl << "Collected cutPoints so far:" << faceVerts << endl; return false; } } while (edgeI != startEdgeI);
Foam:: dissolMotionPointPatchVectorField:: dissolMotionPointPatchVectorField ( const pointPatch& p, const DimensionedField<vector, pointMesh>& iF, const dictionary& dict ) : fixedValuePointPatchField<vector>(p, iF) { if(debug) { Info << "dissolMotionPointPatchVectorField constructor 2"<<endl; } if (dict.found("value")) { this->operator== ( vectorField("value", dict, p.size()) ); } else { WarningIn( "dissolMotionPointPatchVectorField constructor 2" "(" "const pointPatch& p," "const DimensionedField<vector, pointMesh>& iF," "const dictionary& dict" ")" ) << "No value defined for " << this->internalField().name() << " on " << this->patch().name() << endl; } if (!dict.readIfPresent<scalar>("rlxTol", rlxTol)) { rlxTol = 1.0e-6; WarningIn ( "dissolMotionPointPatchVectorField constructor 2" "(" "const fvPatch& p," "const DimensionedField<Type, volMesh>& iF," "const dictionary& dict" ")" ) << "No value defined for rlxTol" << " on " << this->patch().name() << " therefore using " << rlxTol << endl; } if (!dict.readIfPresent<int>("q_norm_recalc", q_norm_recalc)) { q_norm_recalc = 1; WarningIn ( "dissolMotionPointPatchVectorField constructor 2" "(" "const fvPatch& p," "const DimensionedField<Type, volMesh>& iF," "const dictionary& dict" ")" ) << "No value defined for q_norm_recalc" << " on " << this->patch().name() << " therefore using " << q_norm_recalc << endl; } if (!dict.readIfPresent<scalar>("k_1", k_1)) { k_1 = 1.0; WarningIn ( "dissolMotionPointPatchVectorField constructor 2" "(" "const fvPatch& p," "const DimensionedField<Type, volMesh>& iF," "const dictionary& dict" ")" ) << "No value defined for k_1" << " on " << this->patch().name() << " therefore using " << k_1 << endl; } if (!dict.readIfPresent<scalar>("k_2", k_2)) { k_2 = 1.0; WarningIn ( "dissolMotionPointPatchVectorField constructor 2" "(" "const fvPatch& p," "const DimensionedField<Type, volMesh>& iF," "const dictionary& dict" ")" ) << "No value defined for k_2" << " on " << this->patch().name() << " therefore using " << k_2 << endl; } if (!dict.readIfPresent<int>("q_2", q_2)) { q_2 = 1; WarningIn ( "dissolMotionPointPatchVectorField constructor 2" "(" "const fvPatch& p," "const DimensionedField<Type, volMesh>& iF," "const dictionary& dict" ")" ) << "No value defined for q_2" << " on " << this->patch().name() << " therefore using " << q_2 << endl; } if (!dict.readIfPresent<int>("q_norm_recalc_edge", q_norm_recalc_edge)) { q_norm_recalc_edge = 1; WarningIn ( "dissolMotionPointPatchVectorField constructor 2" "(" "const fvPatch& p," "const DimensionedField<Type, volMesh>& iF," "const dictionary& dict" ")" ) << "No value defined for q_norm_recalc_edge" << " on " << this->patch().name() << " therefore using " << q_norm_recalc_edge << endl; } if (!dict.readIfPresent<scalar>("k_1edge", k_1edge)) { k_1edge = 1.0; WarningIn ( "dissolMotionPointPatchVectorField constructor 2" "(" "const fvPatch& p," "const DimensionedField<Type, volMesh>& iF," "const dictionary& dict" ")" ) << "No value defined for k_1edge" << " on " << this->patch().name() << " therefore using " << k_1edge << endl; } if (!dict.readIfPresent<scalar>("k_2edge", k_2edge)) { k_2edge = 1.0; WarningIn ( "dissolMotionPointPatchVectorField constructor 2" "(" "const fvPatch& p," "const DimensionedField<Type, volMesh>& iF," "const dictionary& dict" ")" ) << "No value defined for k_2edge" << " on " << this->patch().name() << " therefore using " << k_2edge << endl; } if (!dict.readIfPresent<int>("q_2edge", q_2edge)) { q_2edge = 1; WarningIn ( "dissolMotionPointPatchVectorField constructor 2" "(" "const fvPatch& p," "const DimensionedField<Type, volMesh>& iF," "const dictionary& dict" ")" ) << "No value defined for q_2edge" << " on " << this->patch().name() << " therefore using " << q_2edge << endl; } if (!dict.readIfPresent<bool>("pinnedPoint", pinnedPoint)) { pinnedPoint = false; WarningIn ( "dissolMotionPointPatchVectorField constructor 2" "(" "const fvPatch& p," "const DimensionedField<scalar, volMesh>& iF," "const dictionary& dict" ")" ) << "No value defined for pinnedPoint" << " on " << this->patch().name() << " therefore using false" << endl; } if(debug) { Info << "dissolMotionPointPatchVectorField constructor 2 " "calc_weights_surface"<<nl; } calc_weights_surface(); if(debug) { Info << "dissolMotionPointPatchVectorField constructor 2 " "make_lists_and_normals"<<nl; } make_lists_and_normals(); /* for(int i=0; i<5; i++) { Info<<i<<" "<<surfWeights[i]<<" "<<pinnedPointsNorm[i]<<nl; } std::exit(0); */ }
// Remove a dirctory and its contents bool Foam::rmDir(const fileName& directory) { if (POSIX::debug) { Info<< "rmDir(const fileName&) : " << "removing directory " << directory << endl; } // Pointers to the directory entries DIR *source; struct dirent *list; // Attempt to open directory and set the structure pointer if ((source = ::opendir(directory.c_str())) == NULL) { WarningIn("rmDir(const fileName&)") << "cannot open directory " << directory << endl; return false; } else { // Read and parse all the entries in the directory while ((list = ::readdir(source)) != NULL) { fileName fName(list->d_name); if (fName != "." && fName != "..") { fileName path = directory/fName; if (path.type() == fileName::DIRECTORY) { if (!rmDir(path)) { WarningIn("rmDir(const fileName&)") << "failed to remove directory " << fName << " while removing directory " << directory << endl; ::closedir(source); return false; } } else { if (!rm(path)) { WarningIn("rmDir(const fileName&)") << "failed to remove file " << fName << " while removing directory " << directory << endl; ::closedir(source); return false; } } } } if (!rm(directory)) { WarningIn("rmDir(const fileName&)") << "failed to remove directory " << directory << endl; ::closedir(source); return false; } ::closedir(source); return true; } }
void Foam::inclinedFilmNusseltInletVelocityFvPatchVectorField::updateCoeffs() { if (updated()) { return; } const label patchI = patch().index(); // retrieve the film region from the database const regionModels::regionModel& region = db().time().lookupObject<regionModels::regionModel> ( "surfaceFilmProperties" ); const regionModels::surfaceFilmModels::kinematicSingleLayer& film = dynamic_cast < const regionModels::surfaceFilmModels::kinematicSingleLayer& >(region); // calculate the vector tangential to the patch // note: normal pointing into the domain const vectorField n(-patch().nf()); // TODO: currently re-evaluating the entire gTan field to return this patch const scalarField gTan(film.gTan()().boundaryField()[patchI] & n); if (patch().size() && (max(mag(gTan)) < SMALL)) { WarningIn ( "void Foam::inclinedFilmNusseltInletVelocityFvPatchVectorField::" "updateCoeffs()" ) << "Tangential gravity component is zero. This boundary condition " << "is designed to operate on patches inclined with respect to " << "gravity" << endl; } const volVectorField& nHat = film.nHat(); const vectorField nHatp(nHat.boundaryField()[patchI].patchInternalField()); vectorField nTan(nHatp ^ n); nTan /= mag(nTan) + ROOTVSMALL; // calculate distance in patch tangential direction const vectorField& Cf = patch().Cf(); scalarField d(nTan & Cf); // calculate the wavy film height const scalar t = db().time().timeOutputValue(); const scalar GMean = GammaMean_->value(t); const scalar a = a_->value(t); const scalar omega = omega_->value(t); const scalarField G(GMean + a*sin(omega*constant::mathematical::twoPi*d)); const volScalarField& mu = film.mu(); const scalarField mup(mu.boundaryField()[patchI].patchInternalField()); const volScalarField& rho = film.rho(); const scalarField rhop(rho.boundaryField()[patchI].patchInternalField()); const scalarField Re(max(G, scalar(0.0))/mup); operator==(n*pow(gTan*mup/(3.0*rhop), 0.333)*pow(Re, 0.666)); fixedValueFvPatchVectorField::updateCoeffs(); }
bool Foam::polyMesh::checkFaceOrthogonality ( const vectorField& fAreas, const vectorField& cellCtrs, const bool report, const bool detailedReport, labelHashSet* setPtr ) const { if (debug) { Info<< "bool polyMesh::checkFaceOrthogonality(" << "const bool, labelHashSet*) const: " << "checking mesh non-orthogonality" << endl; } const labelList& own = faceOwner(); const labelList& nei = faceNeighbour(); // Calculate orthogonality for all internal and coupled boundary faces // (1 for uncoupled boundary faces) tmp<scalarField> tortho = polyMeshTools::faceOrthogonality ( *this, fAreas, cellCtrs ); const scalarField& ortho = tortho(); // Severe nonorthogonality threshold const scalar severeNonorthogonalityThreshold = ::cos(degToRad(primitiveMesh::nonOrthThreshold_)); scalar minDDotS = GREAT; scalar sumDDotS = 0.0; label nSummed = 0; label severeNonOrth = 0; label errorNonOrth = 0; // Statistics only for internal and masters of coupled faces PackedBoolList isMasterFace(syncTools::getInternalOrMasterFaces(*this)); forAll(ortho, faceI) { if (ortho[faceI] < severeNonorthogonalityThreshold) { if (ortho[faceI] > SMALL) { if (setPtr) { setPtr->insert(faceI); } severeNonOrth++; } else { // Error : non-ortho too large if (setPtr) { setPtr->insert(faceI); } if (detailedReport && errorNonOrth == 0) { // Non-orthogonality greater than 90 deg WarningIn ( "polyMesh::checkFaceOrthogonality" "(const pointField&, const bool) const" ) << "Severe non-orthogonality for face " << faceI << " between cells " << own[faceI] << " and " << nei[faceI] << ": Angle = " << radToDeg(::acos(min(1.0, max(-1.0, ortho[faceI])))) << " deg." << endl; } errorNonOrth++; } } if (isMasterFace[faceI]) { minDDotS = min(minDDotS, ortho[faceI]); sumDDotS += ortho[faceI]; nSummed++; } } reduce(minDDotS, minOp<scalar>()); reduce(sumDDotS, sumOp<scalar>()); reduce(nSummed, sumOp<label>()); reduce(severeNonOrth, sumOp<label>()); reduce(errorNonOrth, sumOp<label>()); if (debug || report) { if (nSummed > 0) { if (debug || report) { Info<< " Mesh non-orthogonality Max: " << radToDeg(::acos(min(1.0, max(-1.0, minDDotS)))) << " average: " << radToDeg(::acos(min(1.0, max(-1.0, sumDDotS/nSummed)))) << endl; } } if (severeNonOrth > 0) { Info<< " *Number of severely non-orthogonal (> " << primitiveMesh::nonOrthThreshold_ << " degrees) faces: " << severeNonOrth << "." << endl; } } if (errorNonOrth > 0) { if (debug || report) { Info<< " ***Number of non-orthogonality errors: " << errorNonOrth << "." << endl; } return true; } else { if (debug || report) { Info<< " Non-orthogonality check OK." << endl; } return false; } }
// Return components following the IOobject requirements // // behaviour // input IOobject(instance, local, name) // ----- ------ // "foo" ("", "", "foo") // "foo/bar" ("foo", "", "bar") // "/XXX/bar" ("/XXX", "", "bar") // "foo/bar/" ERROR - no name // "foo/xxx/bar" ("foo", "xxx", "bar") // "foo/xxx/yyy/bar" ("foo", "xxx/yyy", "bar") bool Foam::IOobject::IOobject::fileNameComponents ( const fileName& path, fileName& instance, fileName& local, word& name ) { instance.clear(); local.clear(); name.clear(); // called with directory if (isDir(path)) { WarningIn("IOobject::fileNameComponents(const fileName&, ...)") << " called with directory: " << path << "\n"; return false; } string::size_type first = path.find('/'); if (first == string::npos) { // no '/' found - no instance or local // check afterwards name.string::operator=(path); } else if (first == 0) { // Leading '/'. Absolute fileName string::size_type last = path.rfind('/'); instance = path.substr(0, last); // check afterwards name.string::operator=(path.substr(last+1)); } else { instance = path.substr(0, first); string::size_type last = path.rfind('/'); if (last > first) { // with local local = path.substr(first+1, last-first-1); } // check afterwards name.string::operator=(path.substr(last+1)); } // check for valid (and stripped) name, regardless of the debug level if (name.empty() || string::stripInvalid<word>(name)) { WarningIn("IOobject::fileNameComponents(const fileName&, ...)") << "has invalid word for name: \"" << name << "\"\nwhile processing path: " << path << "\n"; return false; } return true; }
Foam::scalarVelocityProduct::scalarVelocityProduct ( const word& name, const objectRegistry& obr, const dictionary& dict, const bool loadFromFiles ) : name_(name), obr_(obr), active_(true), UName_("U"), scalarFields_(dict.lookup("scalarFields")), USNames_(scalarFields_.size()), writeFields_(false) { // Check if the available mesh is an fvMesh, otherwise deactivate if (!isA<fvMesh>(obr_)) { active_ = false; WarningIn ( "scalarVelocityProduct::scalarVelocityProduct" "(" "const word&, " "const objectRegistry&, " "const dictionary&, " "const bool" ")" ) << "No fvMesh available, deactivating " << name_ << nl << endl; } read(dict); if (active_) { const fvMesh& mesh = refCast<const fvMesh>(obr_); const volVectorField& U = mesh.lookupObject<volVectorField>(UName_); const dimensionSet& UDim = U.dimensions(); forAll (scalarFields_, i) { const volScalarField& S = mesh.lookupObject<volScalarField>(scalarFields_[i]); const dimensionSet& SDim = S.dimensions(); volVectorField* USproductPtr ( new volVectorField ( IOobject ( USNames_[i], mesh.time().timeName(), mesh, IOobject::NO_READ, IOobject::NO_WRITE ), mesh, dimensionedVector ( USNames_[i]+"Dim", UDim*SDim, vector::zero ) ) ); mesh.objectRegistry::store(USproductPtr); } } }
Foam::polyMesh::polyMesh(const IOobject& io) : objectRegistry(io), primitiveMesh(), allPoints_ ( IOobject ( "points", time().findInstance(meshDir(), "points"), meshSubDir, *this, IOobject::MUST_READ, IOobject::NO_WRITE ) ), // To be re-sliced later. HJ, 19/oct/2008 points_(allPoints_, allPoints_.size()), allFaces_ ( IOobject ( "faces", time().findInstance(meshDir(), "faces"), meshSubDir, *this, IOobject::MUST_READ, IOobject::NO_WRITE ) ), // To be re-sliced later. HJ, 19/oct/2008 faces_(allFaces_, allFaces_.size()), owner_ ( IOobject ( "owner", time().findInstance(meshDir(), "faces"), meshSubDir, *this, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE ) ), neighbour_ ( IOobject ( "neighbour", time().findInstance(meshDir(), "faces"), meshSubDir, *this, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE ) ), clearedPrimitives_(false), boundary_ ( IOobject ( "boundary", time().findInstance(meshDir(), "boundary"), meshSubDir, *this, IOobject::MUST_READ, IOobject::NO_WRITE ), *this ), bounds_(allPoints_), geometricD_(Vector<label>::zero), solutionD_(Vector<label>::zero), pointZones_ ( IOobject ( "pointZones", time().findInstance ( meshDir(), "pointZones", IOobject::READ_IF_PRESENT ), meshSubDir, *this, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE ), *this ), faceZones_ ( IOobject ( "faceZones", time().findInstance ( meshDir(), "faceZones", IOobject::READ_IF_PRESENT ), meshSubDir, *this, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE ), *this ), cellZones_ ( IOobject ( "cellZones", time().findInstance ( meshDir(), "cellZones", IOobject::READ_IF_PRESENT ), meshSubDir, *this, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE ), *this ), globalMeshDataPtr_(NULL), moving_(false), changing_(false), curMotionTimeIndex_(time().timeIndex()), oldAllPointsPtr_(NULL), oldPointsPtr_(NULL) { if (exists(owner_.objectPath())) { initMesh(); } else { cellIOList cLst ( IOobject ( "cells", // Find the cells file on the basis of the faces file // HJ, 8/Jul/2009 // time().findInstance(meshDir(), "cells"), time().findInstance(meshDir(), "faces"), meshSubDir, *this, IOobject::MUST_READ, IOobject::NO_WRITE ) ); // Set the primitive mesh initMesh(cLst); owner_.write(); neighbour_.write(); } // Calculate topology for the patches (processor-processor comms etc.) boundary_.updateMesh(); // Calculate the geometry for the patches (transformation tensors etc.) boundary_.calcGeometry(); // Warn if global empty mesh (constructs globalData!) if (globalData().nTotalPoints() == 0) { WarningIn("polyMesh(const IOobject&)") << "no points in mesh" << endl; } if (globalData().nTotalCells() == 0) { WarningIn("polyMesh(const IOobject&)") << "no cells in mesh" << endl; } }
int main(int argc, char *argv[]) { argList::addOption("file","fileName","specify the input file"); argList::addOption("fileIn","fileName","similar to file option"); argList::addOption("field","fieldName","specify the output file"); argList::addOption("fileOut","fileName","specify the output file"); argList::addOption("folder","constant","specify the folder"); argList::addOption("offset","0","add offset to interpolated value"); Foam::argList args(argc,argv); word matrixFile = "default"; word nameField = "default"; if (args.optionFound("file")) { matrixFile = args.option("file"); } else if (args.optionFound("fileIn")) { WarningIn("setFieldsFromXY.C") << "option fileIn deprecated, use option -file instead" << nl << endl; matrixFile = args.option("fileIn"); } else { FatalErrorIn("setFieldsFromXY.C") << "no input file specified, use option -file" << exit(FatalError); } if (args.optionFound("field")) { nameField = args.option("field"); } else if (args.optionFound("fileOut")) { WarningIn("setFieldsFromXY.C") << "option fileOut deprecated, use option -field instead" << nl << endl; nameField = args.option("fileOut"); } else { FatalErrorIn("setFieldsFromXY.C") << "no field specified, use option -field" << exit(FatalError); } scalar offset = args.optionLookupOrDefault<scalar>("offset",0.); #include "createTime.H" #include "createMesh.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // //- read inputFile permeability matrix IFstream inputFileStream(matrixFile); RectangularMatrix<scalar> inputFile(inputFileStream()); word fileDir = "constant"; if (args.optionFound("folder")) { fileDir = args.option("folder"); } volScalarField outputFile ( IOobject ( nameField, fileDir, mesh, IOobject::MUST_READ, IOobject::AUTO_WRITE ), mesh ); forAll(outputFile,celli) { label id1=-1; label id2=-1; label id3=-1; scalar dist1 = VGREAT; scalar dist2 = VGREAT; scalar dist3 = VGREAT; for(label i=0;i<inputFile.m();i++) { scalar dist = Foam::sqrt(pow(inputFile[i][0]-mesh.C()[celli].x(),2)+pow(inputFile[i][1]-mesh.C()[celli].y(),2)); if ( dist < dist1) { //Info << "1 *** " << dist << " " << dist1 << " " << dist2 << " " << dist3 << endl; id3 = id2; dist3 = dist2; id2 = id1; dist2 = dist1; id1 = i; dist1 = dist; } else if ( dist < dist2) { // Info << "2 *** " << dist << " " << dist1 << " " << dist2 << " " << dist3 << endl; id3 = id2; dist3 = dist2; id2 = i; dist2 = dist; } else if ( dist < dist3) { // Info << "3 *** " << dist << " " << dist1 << " " << dist2 << " " << dist3 << endl; id3 = i; dist3 = dist; } } if ( (id1 == -1) || (id2 == -1) || (id3 == -1)) { Info << nl << "Error : three point are not found for interpolation" << nl << id1 << " / " << id2 << " / " << id3 << endl; } outputFile[celli] = ( dist1*inputFile[id1][2] + dist2*inputFile[id2][2] + dist3*inputFile[id3][2] ) / (dist1+dist2+dist3) + offset; }
bool #else void #endif Foam::expressionField::write() { Dbug << "write()" << endl; if(active_) { Info << "Creating expression field " << name_ << " ..." << flush; FieldValueExpressionDriver &driver=driver_(); bool oldDimsetDebug=dimensionSet::debug; dimensionSet::debug=false; driver.clearVariables(); driver.parse(expression_); dimensionSet::debug=oldDimsetDebug; Info << " type:" << driver.getResultType() << endl; if(driver.resultIsTyp<volVectorField>()) { storeField( driver.getResult<volVectorField>() ); } else if(driver.resultIsTyp<volScalarField>()) { storeField( driver.getResult<volScalarField>() ); } else if(driver.resultIsTyp<volTensorField>()) { storeField( driver.getResult<volTensorField>() ); } else if(driver.resultIsTyp<volSymmTensorField>()) { storeField( driver.getResult<volSymmTensorField>() ); } else if(driver.resultIsTyp<volSphericalTensorField>()) { storeField( driver.getResult<volSphericalTensorField>() ); } else if(driver.resultIsTyp<surfaceVectorField>()) { storeField( driver.getResult<surfaceVectorField>() ); } else if(driver.resultIsTyp<surfaceScalarField>()) { storeField( driver.getResult<surfaceScalarField>() ); } else if(driver.resultIsTyp<surfaceTensorField>()) { storeField( driver.getResult<surfaceTensorField>() ); } else if(driver.resultIsTyp<surfaceSymmTensorField>()) { storeField( driver.getResult<surfaceSymmTensorField>() ); } else if(driver.resultIsTyp<surfaceSphericalTensorField>()) { storeField( driver.getResult<surfaceSphericalTensorField>() ); } else if(driver.resultIsTyp<pointVectorField>()) { storeField( driver.getResult<pointVectorField>() ); } else if(driver.resultIsTyp<pointScalarField>()) { storeField( driver.getResult<pointScalarField>() ); } else if(driver.resultIsTyp<pointTensorField>()) { storeField( driver.getResult<pointTensorField>() ); } else if(driver.resultIsTyp<pointSymmTensorField>()) { storeField( driver.getResult<pointSymmTensorField>() ); } else if(driver.resultIsTyp<pointSphericalTensorField>()) { storeField( driver.getResult<pointSphericalTensorField>() ); } else { WarningIn("Foam::expressionField::execute()") << "Expression '" << expression_ << "' evaluated to an unsupported type " << driver.typ() << endl; } } driver_->tryWrite(); Dbug << "write() - end" << endl; #ifdef FOAM_IOFILTER_WRITE_NEEDS_BOOL return true; #endif }
Foam::polyMesh::polyMesh(const IOobject& io) : objectRegistry(io), primitiveMesh(), points_ ( IOobject ( "points", time().findInstance(meshDir(), "points"), meshSubDir, *this, IOobject::MUST_READ, IOobject::NO_WRITE ) ), faces_ ( IOobject ( "faces", time().findInstance(meshDir(), "faces"), meshSubDir, *this, IOobject::MUST_READ, IOobject::NO_WRITE ) ), owner_ ( IOobject ( "owner", faces_.instance(), meshSubDir, *this, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE ) ), neighbour_ ( IOobject ( "neighbour", faces_.instance(), meshSubDir, *this, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE ) ), clearedPrimitives_(false), boundary_ ( IOobject ( "boundary", time().findInstance(meshDir(), "boundary"), meshSubDir, *this, IOobject::MUST_READ, IOobject::NO_WRITE ), *this ), bounds_(points_), comm_(UPstream::worldComm), geometricD_(Vector<label>::zero), solutionD_(Vector<label>::zero), tetBasePtIsPtr_(NULL), cellTreePtr_(NULL), pointZones_ ( IOobject ( "pointZones", time().findInstance ( meshDir(), "pointZones", IOobject::READ_IF_PRESENT ), meshSubDir, *this, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE ), *this ), faceZones_ ( IOobject ( "faceZones", time().findInstance ( meshDir(), "faceZones", IOobject::READ_IF_PRESENT ), meshSubDir, *this, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE ), *this ), cellZones_ ( IOobject ( "cellZones", time().findInstance ( meshDir(), "cellZones", IOobject::READ_IF_PRESENT ), meshSubDir, *this, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE ), *this ), globalMeshDataPtr_(NULL), moving_(false), topoChanging_(false), curMotionTimeIndex_(time().timeIndex()), oldPointsPtr_(NULL) { if (exists(owner_.objectPath())) { initMesh(); } else { cellCompactIOList cLst ( IOobject ( "cells", time().findInstance(meshDir(), "cells"), meshSubDir, *this, IOobject::MUST_READ, IOobject::NO_WRITE ) ); // Set the primitive mesh initMesh(cLst); owner_.write(); neighbour_.write(); } // Calculate topology for the patches (processor-processor comms etc.) boundary_.updateMesh(); // Calculate the geometry for the patches (transformation tensors etc.) boundary_.calcGeometry(); // Warn if global empty mesh if (returnReduce(nPoints(), sumOp<label>()) == 0) { WarningIn("polyMesh(const IOobject&)") << "no points in mesh" << endl; } if (returnReduce(nCells(), sumOp<label>()) == 0) { WarningIn("polyMesh(const IOobject&)") << "no cells in mesh" << endl; } // Initialise demand-driven data calcDirections(); }
void Foam::SmootherBoundary::analyseDict(dictionary &snapDict) { _featureAngle = readScalar(snapDict.lookup("featureAngle")); _minEdgeForFeature = readLabel(snapDict.lookup("minEdgeForFeature")); _minFeatureEdgeLength = readScalar(snapDict.lookup("minFeatureEdgeLength")); _writeFeatures = readBool(snapDict.lookup("writeFeatures")); Info<< " snapControls:" << nl << " - Feature angle : " << _featureAngle << nl << " - Min edges for features : " << _minEdgeForFeature << nl << " - Min feature edge length : " << _minFeatureEdgeLength << nl; const polyBoundaryMesh& bM = _polyMesh->boundaryMesh(); const label NbPolyPatchs = bM.size(); _triSurfList.resize(NbPolyPatchs, 0); _triSurfSearchList.resize(NbPolyPatchs, 0); _surfFeatList.resize(NbPolyPatchs, 0); _extEdgMeshList.resize(NbPolyPatchs, 0); _bndUseIntEdges.resize(NbPolyPatchs, true); _bndIsSnaped.resize(NbPolyPatchs, true); _bndLayers.resize(NbPolyPatchs); if (snapDict.found("boundaries")) { Info<< " - Boundary specifications : " << nl; const dictionary& bndDict = snapDict.subDict("boundaries"); wordList bndDefined = bndDict.toc(); forAll(bndDefined, patchI) { Info<< " - " << bndDefined[patchI] << nl; const dictionary& patchDic = bndDict.subDict(bndDefined[patchI]); if (patchDic.found("triSurface")) { word file = patchDic.lookup("triSurface"); bool exist = false; for(label patchJ = 0; patchJ < NbPolyPatchs && !exist; ++patchJ) { exist = bM[patchJ].name() == bndDefined[patchI]; if (exist) { Info<< " - Snaping surface : " << file << nl; _bndIsSnaped[patchJ] = false; IOobject surfFile ( file, _polyMesh->time().constant(), "triSurface", _polyMesh->time(), IOobject::MUST_READ, IOobject::NO_WRITE ); triSurface* bnd = new triSurface(surfFile.filePath()); addTriFace(patchJ, bnd); if (patchDic.found("internalFeatureEdges")) { _bndUseIntEdges[patchJ] = readBool ( patchDic.lookup("internalFeatureEdges") ); Info<< " - Use internal edges : " << _bndUseIntEdges[patchJ] << nl; } else { _bndUseIntEdges[patchJ] = false; } if (patchDic.found("boundaryLayer")) { _bndLayers[patchJ] = SmootherBoundaryLayer ( patchDic.subDict("boundaryLayer") ); } } } if (!exist) { WarningIn("Foam::MeshSmoother::analyseDict()") << "Patch " << bndDefined[patchI] << " definied in smootherDict is not existing in " << "polyMesh, existing patch in polyMesh ares: " << bM.names() << nl; } } }
// Call scotch with options from dictionary. Foam::label Foam::ptscotchDecomp::decompose ( const fileName& meshPath, const List<int>& adjncy, const List<int>& xadj, const scalarField& cWeights, List<int>& finalDecomp ) const { if (debug) { Pout<< "ptscotchDecomp : entering with xadj:" << xadj.size() << endl; } // Dump graph if (decompositionDict_.found("ptscotchCoeffs")) { const dictionary& scotchCoeffs = decompositionDict_.subDict("ptscotchCoeffs"); if (scotchCoeffs.lookupOrDefault("writeGraph", false)) { OFstream str ( meshPath + "_" + Foam::name(Pstream::myProcNo()) + ".dgr" ); Pout<< "Dumping Scotch graph file to " << str.name() << endl << "Use this in combination with dgpart." << endl; globalIndex globalCells(xadj.size()-1); // Distributed graph file (.grf) label version = 2; str << version << nl; // Number of files (procglbnbr) str << Pstream::nProcs(); // My file number (procloc) str << ' ' << Pstream::myProcNo() << nl; // Total number of vertices (vertglbnbr) str << globalCells.size(); // Total number of connections (edgeglbnbr) str << ' ' << returnReduce(xadj[xadj.size()-1], sumOp<label>()) << nl; // Local number of vertices (vertlocnbr) str << xadj.size()-1; // Local number of connections (edgelocnbr) str << ' ' << xadj[xadj.size()-1] << nl; // Numbering starts from 0 label baseval = 0; // 100*hasVertlabels+10*hasEdgeWeights+1*hasVertWeighs str << baseval << ' ' << "000" << nl; for (label cellI = 0; cellI < xadj.size()-1; cellI++) { label start = xadj[cellI]; label end = xadj[cellI+1]; str << end-start; for (label i = start; i < end; i++) { str << ' ' << adjncy[i]; } str << nl; } } } // Strategy // ~~~~~~~~ // Default. SCOTCH_Strat stradat; check(SCOTCH_stratInit(&stradat), "SCOTCH_stratInit"); if (decompositionDict_.found("scotchCoeffs")) { const dictionary& scotchCoeffs = decompositionDict_.subDict("scotchCoeffs"); string strategy; if (scotchCoeffs.readIfPresent("strategy", strategy)) { if (debug) { Info<< "ptscotchDecomp : Using strategy " << strategy << endl; } SCOTCH_stratDgraphMap(&stradat, strategy.c_str()); //fprintf(stdout, "S\tStrat="); //SCOTCH_stratSave(&stradat, stdout); //fprintf(stdout, "\n"); } } // Graph // ~~~~~ List<int> velotab; // Check for externally provided cellweights and if so initialise weights scalar minWeights = gMin(cWeights); if (!cWeights.empty()) { if (minWeights <= 0) { WarningIn ( "ptscotchDecomp::decompose(..)" ) << "Illegal minimum weight " << minWeights << endl; } if (cWeights.size() != xadj.size()-1) { FatalErrorIn ( "ptscotchDecomp::decompose(..)" ) << "Number of cell weights " << cWeights.size() << " does not equal number of cells " << xadj.size()-1 << exit(FatalError); } } scalar velotabSum = gSum(cWeights)/minWeights; scalar rangeScale(1.0); if (Pstream::master()) { if (velotabSum > scalar(INT_MAX - 1)) { // 0.9 factor of safety to avoid floating point round-off in // rangeScale tipping the subsequent sum over the integer limit. rangeScale = 0.9*scalar(INT_MAX - 1)/velotabSum; WarningIn ( "ptscotchDecomp::decompose(...)" ) << "Sum of weights has overflowed integer: " << velotabSum << ", compressing weight scale by a factor of " << rangeScale << endl; } } Pstream::scatter(rangeScale); if (!cWeights.empty()) { // Convert to integers. velotab.setSize(cWeights.size()); forAll(velotab, i) { velotab[i] = int((cWeights[i]/minWeights - 1)*rangeScale) + 1; }
int main(int argc, char *argv[]) { Foam::timeSelector::addOptions(false); Foam::argList::validArgs.append("expressionDict"); # include "addRegionOption.H" argList::validOptions.insert("noDimensionChecking",""); argList::validOptions.insert("foreignMeshesThatFollowTime", "<list of mesh names>"); # include "setRootCase.H" printSwakVersion(); IFstream theFile(args.args()[1]); dictionary theExpressions(theFile); wordList foreignMeshesThatFollowTime(0); if (!args.options().found("time") && !args.options().found("latestTime")) { FatalErrorIn("main()") << args.executable() << ": time/latestTime option is required" << endl << exit(FatalError); } if(args.options().found("noDimensionChecking")) { dimensionSet::debug=0; } if(args.options().found("foreignMeshesThatFollowTime")) { string followMeshes( args.options()["foreignMeshesThatFollowTime"] ); IStringStream followStream("("+followMeshes+")"); foreignMeshesThatFollowTime=wordList(followStream); } # include "createTime.H" Foam::instantList timeDirs = Foam::timeSelector::select0(runTime, args); # include "createNamedMesh.H" forAllConstIter(IDLList<entry>, theExpressions, iter) { const dictionary &dict=iter().dict(); CommonValueExpressionDriver::readForeignMeshInfo(dict); } forAll(timeDirs, timeI) { runTime.setTime(timeDirs[timeI], timeI); Foam::Info << "\nTime = " << runTime.timeName() << Foam::endl; mesh.readUpdate(); forAll(foreignMeshesThatFollowTime,i) { const word &name=foreignMeshesThatFollowTime[i]; if(MeshesRepository::getRepository().hasMesh(name)) { Info << "Setting mesh " << name << " to current Time" << endl; MeshesRepository::getRepository().setTime( name, runTime.value() ); } else { FatalErrorIn(args.executable()) << "No mesh with name " << name << " declared. " << nl << "Can't follow current time" << endl << exit(FatalError); } } forAllConstIter(IDLList<entry>, theExpressions, iter) { Info << iter().keyword() << " : " << flush; const dictionary &dict=iter().dict(); autoPtr<CommonValueExpressionDriver> driver= CommonValueExpressionDriver::New(dict,mesh); wordList accumulations(dict.lookup("accumulations")); driver->setSearchBehaviour( true, true, true // search on disc ); driver->clearVariables(); driver->parse(string(dict.lookup("expression"))); word rType=driver->CommonValueExpressionDriver::getResultType(); if(rType==pTraits<scalar>::typeName) { writeData<scalar>(driver(),accumulations); } else if(rType==pTraits<vector>::typeName) { writeData<vector>(driver(),accumulations); } else if(rType==pTraits<tensor>::typeName) { writeData<tensor>(driver(),accumulations); } else if(rType==pTraits<symmTensor>::typeName) { writeData<symmTensor>(driver(),accumulations); } else if(rType==pTraits<sphericalTensor>::typeName) { writeData<sphericalTensor>(driver(),accumulations); } else { WarningIn(args.executable()) << "Don't know how to handle type " << rType << endl; } Info << endl; }
bool triSurface::readAC(const fileName& ACfileName) { IFstream ACfile(ACfileName); if (!ACfile.good()) { FatalErrorIn("triSurface::readAC(const fileName&)") << "Cannot read file " << ACfileName << exit(FatalError); } string line; ACfile.getLine(line); string version = line.substr(4); if (version != "b") { WarningIn("bool triSurface::readAC(const fileName& ACfileName)") << "When reading AC3D file " << ACfileName << " read header " << line << " with version " << version << endl << "Only tested reading with version 'b'." << " This might give problems" << endl; } string cmd; string args; if (!readUpto("OBJECT", ACfile, args) || (args != "world")) { FatalErrorIn("bool triSurface::readAC(const fileName& ACfileName)") << "Cannot find \"OBJECT world\" in file " << ACfileName << exit(FatalError); } // Number of kids = patches readUpto("kids", ACfile, args, ""); label nPatches = parseInt(args); // Storage for patches and unmerged points and faces DynamicList<point> points; DynamicList<labelledTri> faces; geometricSurfacePatchList patches(nPatches); // Start of vertices for object/patch label patchStartVert = 0; for (label patchI = 0; patchI < nPatches; patchI++) { readUpto("OBJECT", ACfile, args, " while reading patch " + patchI); // Object global values string patchName = string("patch") + name(patchI); label nVerts = 0; tensor rot(I); vector loc(0, 0, 0); // Read all info for current patch while (ACfile.good()) { // Read line and get first word. If end of file break since // patch should always end with 'kids' command ?not sure. if (!readCmd(ACfile, cmd, args)) { FatalErrorIn("triSurface::readAC(const fileName&)") << "Did not read up to \"kids 0\" while reading patch " << patchI << " from file " << ACfileName << exit(FatalError); } if (cmd == "name") { IStringStream nameStream(args); nameStream >> patchName; } else if (cmd == "rot") { // rot %f %f %f %f %f %f %f %f %f IStringStream lineStream(args); lineStream >> rot.xx() >> rot.xy() >> rot.xz() >> rot.yx() >> rot.yy() >> rot.yz() >> rot.zx() >> rot.zy() >> rot.zz(); WarningIn("triSurface::readAC(const fileName&)") << "rot (rotation tensor) command not implemented" << "Line:" << cmd << ' ' << args << endl << "while reading patch " << patchI << endl; }
bool Foam::polyMesh::checkFaceSkewness ( const pointField& points, const vectorField& fCtrs, const vectorField& fAreas, const vectorField& cellCtrs, const bool report, const bool detailedReport, labelHashSet* setPtr ) const { if (debug) { Info<< "bool polyMesh::checkFaceSkewnesss(" << "const bool, labelHashSet*) const: " << "checking face skewness" << endl; } const labelList& own = faceOwner(); const labelList& nei = faceNeighbour(); // Warn if the skew correction vector is more than skewWarning times // larger than the face area vector tmp<scalarField> tskew = polyMeshTools::faceSkewness ( *this, points, fCtrs, fAreas, cellCtrs ); const scalarField& skew = tskew(); scalar maxSkew = max(skew); label nWarnSkew = 0; // Statistics only for all faces except slave coupled faces PackedBoolList isMasterFace(syncTools::getMasterFaces(*this)); forAll(skew, faceI) { // Check if the skewness vector is greater than the PN vector. // This does not cause trouble but is a good indication of a poor mesh. if (skew[faceI] > skewThreshold_) { if (setPtr) { setPtr->insert(faceI); } if (detailedReport && nWarnSkew == 0) { // Non-orthogonality greater than 90 deg if (isInternalFace(faceI)) { WarningIn ( "polyMesh::checkFaceSkewnesss" "(const pointField&, const bool) const" ) << "Severe skewness " << skew[faceI] << " for face " << faceI << " between cells " << own[faceI] << " and " << nei[faceI]; } else { WarningIn ( "polyMesh::checkFaceSkewnesss" "(const pointField&, const bool) const" ) << "Severe skewness " << skew[faceI] << " for boundary face " << faceI << " on cell " << own[faceI]; } } if (isMasterFace[faceI]) { nWarnSkew++; } } } reduce(maxSkew, maxOp<scalar>()); reduce(nWarnSkew, sumOp<label>()); if (nWarnSkew > 0) { if (debug || report) { Info<< " ***Max skewness = " << maxSkew << ", " << nWarnSkew << " highly skew faces detected" " which may impair the quality of the results" << endl; } return true; } else { if (debug || report) { Info<< " Max skewness = " << maxSkew << " OK." << endl; } return false; } }
const Foam::Tuple2<Foam::scalar, Type>& Foam::interpolationTable<Type>::operator[](const label i) const { label ii = i; label n = this->size(); if (n <= 1) { ii = 0; } else if (ii < 0) { switch (boundsHandling_) { case interpolationTable::ERROR: { FatalErrorIn ( "Foam::interpolationTable<Type>::operator[]" "(const label) const" ) << "index (" << ii << ") underflow" << nl << exit(FatalError); break; } case interpolationTable::WARN: { WarningIn ( "Foam::interpolationTable<Type>::operator[]" "(const label) const" ) << "index (" << ii << ") underflow" << nl << " Continuing with the first entry" << endl; // fall-through to 'CLAMP' } case interpolationTable::CLAMP: { ii = 0; break; } case interpolationTable::REPEAT: { while (ii < 0) { ii += n; } break; } } } else if (ii >= n) { switch (boundsHandling_) { case interpolationTable::ERROR: { FatalErrorIn ( "Foam::interpolationTable<Type>::operator[]" "(const label) const" ) << "index (" << ii << ") overflow" << nl << exit(FatalError); break; } case interpolationTable::WARN: { WarningIn ( "Foam::interpolationTable<Type>::operator[]" "(const label) const" ) << "index (" << ii << ") overflow" << nl << " Continuing with the last entry" << endl; // fall-through to 'CLAMP' } case interpolationTable::CLAMP: { ii = n - 1; break; } case interpolationTable::REPEAT: { while (ii >= n) { ii -= n; } break; } } } return List<Tuple2<scalar, Type> >::operator[](ii); }
void Foam::setsToFaceZone::applyToSet ( const topoSetSource::setAction action, topoSet& set ) const { if (!isA<faceZoneSet>(set)) { WarningIn ( "setsToFaceZone::applyToSet(const topoSetSource::setAction" ", topoSet" ) << "Operation only allowed on a faceZoneSet." << endl; } else { faceZoneSet& fzSet = refCast<faceZoneSet>(set); if ((action == topoSetSource::NEW) || (action == topoSetSource::ADD)) { Info<< " Adding all faces from faceSet " << faceSetName_ << " ..." << endl; // Load the sets faceSet fSet(mesh_, faceSetName_); cellSet cSet(mesh_, cellSetName_); // Start off from copy DynamicList<label> newAddressing(fzSet.addressing()); DynamicList<bool> newFlipMap(fzSet.flipMap()); forAllConstIter(faceSet, fSet, iter) { label faceI = iter.key(); if (!fzSet.found(faceI)) { bool flip = false; label own = mesh_.faceOwner()[faceI]; bool ownFound = cSet.found(own); if (mesh_.isInternalFace(faceI)) { label nei = mesh_.faceNeighbour()[faceI]; bool neiFound = cSet.found(nei); if (ownFound && !neiFound) { flip = false; } else if (!ownFound && neiFound) { flip = true; } else { WarningIn ( "setsToFaceZone::applyToSet" "(const topoSetSource::setAction, topoSet)" ) << "One of owner or neighbour of internal face " << faceI << " should be in cellSet " << cSet.name() << " to be able to determine orientation." << endl << "Face:" << faceI << " own:" << own << " OwnInCellSet:" << ownFound << " nei:" << nei << " NeiInCellSet:" << neiFound << endl; } } else { flip = !ownFound; } newAddressing.append(faceI); newFlipMap.append(flip); } } fzSet.addressing().transfer(newAddressing); fzSet.flipMap().transfer(newFlipMap); fzSet.updateSet(); }
Type Foam::interpolationTable<Type>::operator()(const scalar value) const { label n = this->size(); if (n <= 1) { return List<Tuple2<scalar, Type> >::operator[](0).second(); } scalar minLimit = List<Tuple2<scalar, Type> >::operator[](0).first(); scalar maxLimit = List<Tuple2<scalar, Type> >::operator[](n-1).first(); scalar lookupValue = value; if (lookupValue < minLimit) { switch (boundsHandling_) { case interpolationTable::ERROR: { FatalErrorIn ( "Foam::interpolationTable<Type>::operator[]" "(const scalar) const" ) << "value (" << lookupValue << ") underflow" << nl << exit(FatalError); break; } case interpolationTable::WARN: { WarningIn ( "Foam::interpolationTable<Type>::operator[]" "(const scalar) const" ) << "value (" << lookupValue << ") underflow" << nl << " Continuing with the first entry" << endl; // fall-through to 'CLAMP' } case interpolationTable::CLAMP: { return List<Tuple2<scalar, Type> >::operator[](0).second(); break; } case interpolationTable::REPEAT: { // adjust lookupValue to >= minLimit scalar span = maxLimit-minLimit; lookupValue = fmod(lookupValue-minLimit, span) + minLimit; break; } } } else if (lookupValue >= maxLimit) { switch (boundsHandling_) { case interpolationTable::ERROR: { FatalErrorIn ( "Foam::interpolationTable<Type>::operator[]" "(const label) const" ) << "value (" << lookupValue << ") overflow" << nl << exit(FatalError); break; } case interpolationTable::WARN: { WarningIn ( "Foam::interpolationTable<Type>::operator[]" "(const label) const" ) << "value (" << lookupValue << ") overflow" << nl << " Continuing with the last entry" << endl; // fall-through to 'CLAMP' } case interpolationTable::CLAMP: { return List<Tuple2<scalar, Type> >::operator[](n-1).second(); break; } case interpolationTable::REPEAT: { // adjust lookupValue <= maxLimit scalar span = maxLimit-minLimit; lookupValue = fmod(lookupValue-minLimit, span) + minLimit; break; } } } label lo = 0; label hi = 0; // look for the correct range for (label i = 0; i < n; ++i) { if (lookupValue >= List<Tuple2<scalar, Type> >::operator[](i).first()) { lo = hi = i; } else { hi = i; break; } } if (lo == hi) { // we are at the end of the table - or there is only a single entry return List<Tuple2<scalar, Type> >::operator[](hi).second(); } else if (hi == 0) { // this treatment should should only occur under these conditions: // -> the 'REPEAT' treatment // -> (0 <= value <= minLimit) // -> minLimit > 0 // Use the value at maxLimit as the value for value=0 lo = n - 1; return ( List<Tuple2<scalar, Type> >::operator[](lo).second() + ( List<Tuple2<scalar, Type> >::operator[](hi).second() - List<Tuple2<scalar, Type> >::operator[](lo).second() ) *(lookupValue / minLimit) ); } else { // normal interpolation return ( List<Tuple2<scalar, Type> >::operator[](lo).second() + ( List<Tuple2<scalar, Type> >::operator[](hi).second() - List<Tuple2<scalar, Type> >::operator[](lo).second() ) *( lookupValue - List<Tuple2<scalar, Type> >::operator[](lo).first() ) /( List<Tuple2<scalar, Type> >::operator[](hi).first() - List<Tuple2<scalar, Type> >::operator[](lo).first() ) ); } }
Foam::danckwertsFvPatchScalarField:: danckwertsFvPatchScalarField ( const fvPatch& p, const DimensionedField<scalar, volMesh>& iF, const dictionary& dict ) : mixedFvPatchScalarField(p, iF) { if(debug) { Info << "danckwertsFvPatchField<Type>::danckwertsFvPatchField 2" << endl; } if (dict.found("value")) { fvPatchScalarField::operator= ( scalarField("value", dict, p.size()) ); } else { fvPatchScalarField::operator=(this->refValue()); WarningIn( "!!!nonLinearFvPatchField<Type>::nonLinearFvPatchField" "(" "const fvPatch& p," "const DimensionedField<Type, volMesh>& iF," "const dictionary& dict" ")" ) << "No value defined for " << this->internalField().name() << " on " << this->patch().name() << " therefore using " << this->refValue() << endl; } if(debug) { Info << "danckwertsFvPatchField<Type>::danckwertsFvPatchField 2 " "value set" << endl; } if (dict.found("refValue")) this->refValue() = scalarField("refValue", dict, p.size()); else { if (dict.found("value")) { // make sure that refValue has a sensible value for the "update" below this->refValue() = scalarField(this->patchInternalField()); } else{ this->refValue() = pTraits<scalar>::zero; } } if(debug) { Info << "danckwertsFvPatchField<Type>::danckwertsFvPatchField 2 " "refValue set" << endl; } if (dict.found("refGradient")) { this->refGrad() = scalarField("refGradient", dict, p.size()); } else { this->refGrad() = pTraits<scalar>::zero; } if(debug) { Info << "danckwertsFvPatchField<Type>::danckwertsFvPatchField 2 " "refGrad set" << endl; } if (dict.found("valueFraction")) { this->valueFraction() = Field<scalar>("valueFraction", dict, p.size()); } else { this->valueFraction() = 1; } if(debug) { Info << "danckwertsFvPatchField<Type>::danckwertsFvPatchField 2 " "valueFraction set" << endl; } if (!this->updated()) { this->mixedFvPatchScalarField::updateCoeffs(); } /* scalarField::operator= ( this->valueFraction()*this->refValue() + (1.0 - this->valueFraction())* ( this->patchInternalField() + this->refGrad()/this->patch().deltaCoeffs() ) ); */ if(debug) { Info << "danckwertsFvPatchField<Type>::danckwertsFvPatchField 2 " "operator" << endl; } fvPatchScalarField::evaluate(); }
// Call scotch with options from dictionary. Foam::label Foam::ptscotchDecomp::decompose ( const fileName& meshPath, const List<int>& adjncy, const List<int>& xadj, const scalarField& cWeights, List<int>& finalDecomp ) const { if (debug) { Pout<< "ptscotchDecomp : entering with xadj:" << xadj.size() << endl; } // Dump graph if (decompositionDict_.found("ptscotchCoeffs")) { const dictionary& scotchCoeffs = decompositionDict_.subDict("ptscotchCoeffs"); if (scotchCoeffs.lookupOrDefault("writeGraph", false)) { OFstream str ( meshPath + "_" + Foam::name(Pstream::myProcNo()) + ".dgr" ); Pout<< "Dumping Scotch graph file to " << str.name() << endl << "Use this in combination with dgpart." << endl; globalIndex globalCells(xadj.size()-1); // Distributed graph file (.grf) label version = 2; str << version << nl; // Number of files (procglbnbr) str << Pstream::nProcs(); // My file number (procloc) str << ' ' << Pstream::myProcNo() << nl; // Total number of vertices (vertglbnbr) str << globalCells.size(); // Total number of connections (edgeglbnbr) str << ' ' << returnReduce(xadj[xadj.size()-1], sumOp<label>()) << nl; // Local number of vertices (vertlocnbr) str << xadj.size()-1; // Local number of connections (edgelocnbr) str << ' ' << xadj[xadj.size()-1] << nl; // Numbering starts from 0 label baseval = 0; // 100*hasVertlabels+10*hasEdgeWeights+1*hasVertWeighs str << baseval << ' ' << "000" << nl; for (label cellI = 0; cellI < xadj.size()-1; cellI++) { label start = xadj[cellI]; label end = xadj[cellI+1]; str << end-start; for (label i = start; i < end; i++) { str << ' ' << adjncy[i]; } str << nl; } } } // Strategy // ~~~~~~~~ // Default. SCOTCH_Strat stradat; check(SCOTCH_stratInit(&stradat), "SCOTCH_stratInit"); if (decompositionDict_.found("scotchCoeffs")) { const dictionary& scotchCoeffs = decompositionDict_.subDict("scotchCoeffs"); string strategy; if (scotchCoeffs.readIfPresent("strategy", strategy)) { if (debug) { Info<< "ptscotchDecomp : Using strategy " << strategy << endl; } SCOTCH_stratDgraphMap(&stradat, strategy.c_str()); //fprintf(stdout, "S\tStrat="); //SCOTCH_stratSave(&stradat, stdout); //fprintf(stdout, "\n"); } } // Graph // ~~~~~ List<int> velotab; // Check for externally provided cellweights and if so initialise weights scalar minWeights = gMin(cWeights); if (cWeights.size() > 0) { if (minWeights <= 0) { WarningIn ( "ptscotchDecomp::decompose(..)" ) << "Illegal minimum weight " << minWeights << endl; } if (cWeights.size() != xadj.size()-1) { FatalErrorIn ( "ptscotchDecomp::decompose(..)" ) << "Number of cell weights " << cWeights.size() << " does not equal number of cells " << xadj.size()-1 << exit(FatalError); } // Convert to integers. velotab.setSize(cWeights.size()); forAll(velotab, i) { velotab[i] = int(cWeights[i]/minWeights); } } if (debug) { Pout<< "SCOTCH_dgraphInit" << endl; } SCOTCH_Dgraph grafdat; check(SCOTCH_dgraphInit(&grafdat, MPI_COMM_WORLD), "SCOTCH_dgraphInit"); if (debug) { Pout<< "SCOTCH_dgraphBuild with:" << nl << "xadj.size()-1 : " << xadj.size()-1 << nl << "xadj : " << long(xadj.begin()) << nl << "velotab : " << long(velotab.begin()) << nl << "adjncy.size() : " << adjncy.size() << nl << "adjncy : " << long(adjncy.begin()) << nl << endl; } check ( SCOTCH_dgraphBuild ( &grafdat, // grafdat 0, // baseval, c-style numbering xadj.size()-1, // vertlocnbr, nCells xadj.size()-1, // vertlocmax const_cast<SCOTCH_Num*>(xadj.begin()), // vertloctab, start index per cell into // adjncy const_cast<SCOTCH_Num*>(&xadj[1]),// vendloctab, end index ,, const_cast<SCOTCH_Num*>(velotab.begin()),// veloloctab, vtx weights NULL, // vlblloctab adjncy.size(), // edgelocnbr, number of arcs adjncy.size(), // edgelocsiz const_cast<SCOTCH_Num*>(adjncy.begin()), // edgeloctab NULL, // edgegsttab NULL // edlotab, edge weights ), "SCOTCH_dgraphBuild" ); if (debug) { Pout<< "SCOTCH_dgraphCheck" << endl; } check(SCOTCH_dgraphCheck(&grafdat), "SCOTCH_dgraphCheck"); // Architecture // ~~~~~~~~~~~~ // (fully connected network topology since using switch) if (debug) { Pout<< "SCOTCH_archInit" << endl; } SCOTCH_Arch archdat; check(SCOTCH_archInit(&archdat), "SCOTCH_archInit"); List<label> processorWeights; if (decompositionDict_.found("scotchCoeffs")) { const dictionary& scotchCoeffs = decompositionDict_.subDict("scotchCoeffs"); scotchCoeffs.readIfPresent("processorWeights", processorWeights); } if (processorWeights.size()) { if (debug) { Info<< "ptscotchDecomp : Using procesor weights " << processorWeights << endl; } check ( SCOTCH_archCmpltw(&archdat, nProcessors_, processorWeights.begin()), "SCOTCH_archCmpltw" ); } else { if (debug) { Pout<< "SCOTCH_archCmplt" << endl; } check ( SCOTCH_archCmplt(&archdat, nProcessors_), "SCOTCH_archCmplt" ); } //SCOTCH_Mapping mapdat; //SCOTCH_dgraphMapInit(&grafdat, &mapdat, &archdat, NULL); //SCOTCH_dgraphMapCompute(&grafdat, &mapdat, &stradat); /*Perform mapping*/ //SCOTCHdgraphMapExit(&grafdat, &mapdat); // Hack:switch off fpu error trapping # ifdef LINUX_GNUC int oldExcepts = fedisableexcept ( FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW ); # endif if (debug) { Pout<< "SCOTCH_dgraphMap" << endl; } finalDecomp.setSize(xadj.size()-1); finalDecomp = 0; check ( SCOTCH_dgraphMap ( &grafdat, &archdat, &stradat, // const SCOTCH_Strat * finalDecomp.begin() // parttab ), "SCOTCH_graphMap" ); # ifdef LINUX_GNUC feenableexcept(oldExcepts); # endif //finalDecomp.setSize(xadj.size()-1); //check //( // SCOTCH_dgraphPart // ( // &grafdat, // nProcessors_, // partnbr // &stradat, // const SCOTCH_Strat * // finalDecomp.begin() // parttab // ), // "SCOTCH_graphPart" //); if (debug) { Pout<< "SCOTCH_dgraphExit" << endl; } // Release storage for graph SCOTCH_dgraphExit(&grafdat); // Release storage for strategy SCOTCH_stratExit(&stradat); // Release storage for network topology SCOTCH_archExit(&archdat); return 0; }
// Call scotch with options from dictionary. Foam::label Foam::scotchDecomp::decompose ( const List<int>& adjncy, const List<int>& xadj, const scalarField& cWeights, List<int>& finalDecomp ) { // Dump graph if (decompositionDict_.found("scotchCoeffs")) { const dictionary& scotchCoeffs = decompositionDict_.subDict("scotchCoeffs"); if (scotchCoeffs.found("writeGraph")) { Switch writeGraph(scotchCoeffs.lookup("writeGraph")); if (writeGraph) { OFstream str(mesh_.time().path() / mesh_.name() + ".grf"); Info<< "Dumping Scotch graph file to " << str.name() << endl << "Use this in combination with gpart." << endl; label version = 0; str << version << nl; // Numer of vertices str << xadj.size()-1 << ' ' << adjncy.size() << nl; // Numbering starts from 0 label baseval = 0; // Has weights? label hasEdgeWeights = 0; label hasVertexWeights = 0; label numericflag = 10*hasEdgeWeights+hasVertexWeights; str << baseval << ' ' << numericflag << nl; for (label cellI = 0; cellI < xadj.size()-1; cellI++) { label start = xadj[cellI]; label end = xadj[cellI+1]; str << end-start; for (label i = start; i < end; i++) { str << ' ' << adjncy[i]; } str << nl; } } } } // Strategy // ~~~~~~~~ // Default. SCOTCH_Strat stradat; check(SCOTCH_stratInit(&stradat), "SCOTCH_stratInit"); if (decompositionDict_.found("scotchCoeffs")) { const dictionary& scotchCoeffs = decompositionDict_.subDict("scotchCoeffs"); string strategy; if (scotchCoeffs.readIfPresent("strategy", strategy)) { if (debug) { Info<< "scotchDecomp : Using strategy " << strategy << endl; } SCOTCH_stratGraphMap(&stradat, strategy.c_str()); //fprintf(stdout, "S\tStrat="); //SCOTCH_stratSave(&stradat, stdout); //fprintf(stdout, "\n"); } } // Graph // ~~~~~ List<int> velotab; // Check for externally provided cellweights and if so initialise weights scalar minWeights = gMin(cWeights); if (cWeights.size() > 0) { if (minWeights <= 0) { WarningIn ( "scotchDecomp::decompose" "(const pointField&, const scalarField&)" ) << "Illegal minimum weight " << minWeights << endl; } if (cWeights.size() != xadj.size()-1) { FatalErrorIn ( "scotchDecomp::decompose" "(const pointField&, const scalarField&)" ) << "Number of cell weights " << cWeights.size() << " does not equal number of cells " << xadj.size()-1 << exit(FatalError); } // Convert to integers. velotab.setSize(cWeights.size()); forAll(velotab, i) { velotab[i] = int(cWeights[i]/minWeights); } } SCOTCH_Graph grafdat; check(SCOTCH_graphInit(&grafdat), "SCOTCH_graphInit"); check ( SCOTCH_graphBuild ( &grafdat, 0, // baseval, c-style numbering xadj.size()-1, // vertnbr, nCells xadj.begin(), // verttab, start index per cell into adjncy &xadj[1], // vendtab, end index ,, velotab.begin(), // velotab, vertex weights NULL, // vlbltab adjncy.size(), // edgenbr, number of arcs adjncy.begin(), // edgetab NULL // edlotab, edge weights ), "SCOTCH_graphBuild" ); check(SCOTCH_graphCheck(&grafdat), "SCOTCH_graphCheck"); // Architecture // ~~~~~~~~~~~~ // (fully connected network topology since using switch) SCOTCH_Arch archdat; check(SCOTCH_archInit(&archdat), "SCOTCH_archInit"); List<label> processorWeights; if (decompositionDict_.found("scotchCoeffs")) { const dictionary& scotchCoeffs = decompositionDict_.subDict("scotchCoeffs"); scotchCoeffs.readIfPresent("processorWeights", processorWeights); } if (processorWeights.size()) { if (debug) { Info<< "scotchDecomp : Using procesor weights " << processorWeights << endl; } check ( SCOTCH_archCmpltw(&archdat, nProcessors_, processorWeights.begin()), "SCOTCH_archCmpltw" ); } else { check ( SCOTCH_archCmplt(&archdat, nProcessors_), "SCOTCH_archCmplt" ); } //SCOTCH_Mapping mapdat; //SCOTCH_graphMapInit(&grafdat, &mapdat, &archdat, NULL); //SCOTCH_graphMapCompute(&grafdat, &mapdat, &stradat); /* Perform mapping */ //SCOTCH_graphMapExit(&grafdat, &mapdat); // Hack:switch off fpu error trapping # ifdef LINUX_GNUC int oldExcepts = fedisableexcept ( FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW ); # endif finalDecomp.setSize(xadj.size()-1); finalDecomp = 0; check ( SCOTCH_graphMap ( &grafdat, &archdat, &stradat, // const SCOTCH_Strat * finalDecomp.begin() // parttab ), "SCOTCH_graphMap" ); # ifdef LINUX_GNUC feenableexcept(oldExcepts); # endif //finalDecomp.setSize(xadj.size()-1); //check //( // SCOTCH_graphPart // ( // &grafdat, // nProcessors_, // partnbr // &stradat, // const SCOTCH_Strat * // finalDecomp.begin() // parttab // ), // "SCOTCH_graphPart" //); // Release storage for graph SCOTCH_graphExit(&grafdat); // Release storage for strategy SCOTCH_stratExit(&stradat); // Release storage for network topology SCOTCH_archExit(&archdat); return 0; }
Foam::polyBoundaryMesh::polyBoundaryMesh ( const IOobject& io, const polyMesh& mesh ) : polyPatchList(), regIOobject(io), mesh_(mesh) { if ( readOpt() == IOobject::MUST_READ || readOpt() == IOobject::MUST_READ_IF_MODIFIED ) { if (readOpt() == IOobject::MUST_READ_IF_MODIFIED) { WarningIn ( "polyBoundaryMesh::polyBoundaryMesh\n" "(\n" " const IOobject&,\n" " const polyMesh&\n" ")" ) << "Specified IOobject::MUST_READ_IF_MODIFIED but class" << " does not support automatic rereading." << endl; } polyPatchList& patches = *this; // Read polyPatchList Istream& is = readStream(typeName); PtrList<entry> patchEntries(is); patches.setSize(patchEntries.size()); forAll(patches, patchI) { patches.set ( patchI, polyPatch::New ( patchEntries[patchI].keyword(), patchEntries[patchI].dict(), patchI, *this ) ); } // Check state of IOstream is.check ( "polyBoundaryMesh::polyBoundaryMesh" "(const IOobject&, const polyMesh&)" ); close(); }
Foam::polyMesh::readUpdateState Foam::polyMesh::readUpdate() { if (debug) { Info<< "polyMesh::readUpdateState polyMesh::readUpdate() : " << "Updating mesh based on saved data." << endl; } // Find the point and cell instance fileName pointsInst(time().findInstance(meshDir(), "points")); fileName facesInst(time().findInstance(meshDir(), "faces")); if (debug) { Info<< "Faces instance: old = " << facesInstance() << " new = " << facesInst << nl << "Points instance: old = " << pointsInstance() << " new = " << pointsInst << endl; } if (facesInst != facesInstance()) { // Topological change if (debug) { Info<< "Topological change" << endl; } clearOut(); // Set instance to new instance. Note that points instance can differ // from from faces instance. setInstance(facesInst); points_.instance() = pointsInst; points_ = pointIOField ( IOobject ( "points", pointsInst, meshSubDir, *this, IOobject::MUST_READ, IOobject::NO_WRITE, false ) ); faces_ = faceCompactIOList ( IOobject ( "faces", facesInst, meshSubDir, *this, IOobject::MUST_READ, IOobject::NO_WRITE, false ) ); owner_ = labelIOList ( IOobject ( "owner", facesInst, meshSubDir, *this, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, false ) ); neighbour_ = labelIOList ( IOobject ( "neighbour", facesInst, meshSubDir, *this, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, false ) ); // Reset the boundary patches polyBoundaryMesh newBoundary ( IOobject ( "boundary", facesInst, meshSubDir, *this, IOobject::MUST_READ, IOobject::NO_WRITE, false ), *this ); // Check that patch types and names are unchanged bool boundaryChanged = false; if (newBoundary.size() != boundary_.size()) { boundaryChanged = true; } else { wordList newTypes = newBoundary.types(); wordList newNames = newBoundary.names(); wordList oldTypes = boundary_.types(); wordList oldNames = boundary_.names(); forAll(oldTypes, patchI) { if ( oldTypes[patchI] != newTypes[patchI] || oldNames[patchI] != newNames[patchI] ) { boundaryChanged = true; break; } } } if (boundaryChanged) { WarningIn("polyMesh::readUpdateState polyMesh::readUpdate()") << "Number of patches has changed. This may have " << "unexpected consequences. Proceed with care." << endl; boundary_.clear(); boundary_.setSize(newBoundary.size()); forAll(newBoundary, patchI) { boundary_.set(patchI, newBoundary[patchI].clone(boundary_)); } } else {
scalar GGIInterpolation<MasterPatch, SlavePatch>::polygonIntersection ( const List<point2D>& poly1, const List<point2D>& poly2 ) const { // Using pointers because clipping and subject may be swapped // by the algorithm. HJ, 24/Oct/2008 // The first polygon will be the clipping polygon const List<point2D>* clippingPolygon = &poly1; // Yhe second polygon will be the subject polygon; the one that // is going to be clipped const List<point2D>* subjectPolygon = &poly2; // Empty list so we can detect weird cases later List<point2D> clippedPolygon; scalar intersectionArea = 0.0; // First, let's get rid of the obvious: // 1: Neither polygons intersect one another // --> intersection area == 0.0 : that should not happen // 2: If both polygons completely overlap one another // ---> subjectPolygon is the intersection polygon // 3: If clippingPolygon totally enclosed subjectPolygon // ---> subjectPolygon is the intersecting polygon // 4: If subjectPolygon totally enclosed clippingPolygon // --> clippingPolygon is the intersecting polygon // 5: Otherwise, we have partial or full intersection // // For this, we first detect if the vertices of the subject polygon // are inside or outside of the clipping polygon // This is a quick intersection test... // Keep track of who is inside or outside List<bool> subjectVertexInside(subjectPolygon->size()); insideOutside statusInOut = isVertexInsidePolygon ( *clippingPolygon, *subjectPolygon, subjectVertexInside ); // We check right away if statusInOut == ALL_OUTSIDE // Sometimes, it is just that the clipping polygon is inside the // subject polygon instead So let's explore this situation, just // in case if (statusInOut == ALL_OUTSIDE) { // We need to check if subject is not completely or partially // enclosing clipping instead clippingPolygon = &poly2; subjectPolygon = &poly1; subjectVertexInside.setSize(subjectPolygon->size()); statusInOut = isVertexInsidePolygon ( *clippingPolygon, *subjectPolygon, subjectVertexInside ); } switch(statusInOut) { case ALL_INSIDE: { clippedPolygon = *subjectPolygon; break; } case ALL_OUTSIDE: case PARTIALLY_OVERLAPPING: default: { // Compute the intersection // If by any chance, we have reached a situation where the // intersection is really zero, it is because the quick // reject tests have missed something. The intersection // area will be 0.0, and the calling function should at // least check for this, and report loudly... clippedPolygon = clipPolygon2DSutherlandHodgman ( *clippingPolygon, *subjectPolygon );// For convex polygons #if 0 // This is the next candidate to code if the Sutherland // Hodgman algorithm encounters concave polygons... clippedPolygon = clipPolygon2DGreinerHormann ( *clippingPolygon, *subjectPolygon, subjectVertexInside ); // For arbitrary polygons #endif break; } } // Compute the area of clippedPolygon if we indeed do have a // clipped polygon; otherwise, the computed area stays at 0.0; if (clippedPolygon.size() > 2) { // We are only interested in the absolute value intersectionArea = mag(area2D(clippedPolygon)); } if (debug) { // Check against tolerances scalar clippingArea = area2D(*clippingPolygon); scalar subjectArea = area2D(*subjectPolygon); if ( mag(intersectionArea/clippingArea) < areaErrorTol_ || mag(intersectionArea/subjectArea) < areaErrorTol_ ) { WarningIn ( "GGIInterpolation<MasterPatch, SlavePatch>::" "polygonIntersection" ) << "Intersection might be wrong wrong: clipping side " << intersectionArea/clippingArea << " subject: " << intersectionArea/subjectArea << endl; } } return intersectionArea; }
// Remove a dirctory and it's contents bool rmDir(const fileName& directory) { if (MSwindows::debug) { Info<< "rmdir(const fileName&) : " << "removing directory " << directory << endl; } bool success = true; // Need to destroy DirectorIterator prior to // removing directory otherwise fails on Windows XP { MSwindows::DirectoryIterator dirIt(directory); while (success && dirIt.hasNext()) { const fileName & fName = dirIt.next(); if (fName != "." && fName != "..") { fileName path = directory/fName; if (path.type() == fileName::DIRECTORY) { success = rmDir(path); if (!success) { WarningIn("rmdir(const fileName&)") << "failed to remove directory " << fName << " while removing directory " << directory << endl; } } else { success = rm(path); if (!success) { WarningIn("rmdir(const fileName&)") << "failed to remove file " << fName << " while removing directory " << directory << endl; } } } } } if (success) { success = ::RemoveDirectory(directory.c_str()); if (!success) { WarningIn("rmdir(const fileName&)") << "failed to remove directory " << directory << endl; } } return success; }
void Foam::FitData<FitDataType, ExtendedStencil, Polynomial>::calcFit ( scalarList& coeffsi, const List<point>& C, const scalar wLin, const label facei ) { vector idir(1,0,0); vector jdir(0,1,0); vector kdir(0,0,1); findFaceDirs(idir, jdir, kdir, facei); // Setup the point weights scalarList wts(C.size(), scalar(1)); wts[0] = centralWeight_; if (linearCorrection_) { wts[1] = centralWeight_; } // Reference point point p0 = this->mesh().faceCentres()[facei]; // Info << "Face " << facei << " at " << p0 << " stencil points at:\n" // << C - p0 << endl; // p0 -> p vector in the face-local coordinate system vector d; // Local coordinate scaling scalar scale = 1; // Matrix of the polynomial components scalarRectangularMatrix B(C.size(), minSize_, scalar(0)); for(label ip = 0; ip < C.size(); ip++) { const point& p = C[ip]; d.x() = (p - p0)&idir; d.y() = (p - p0)&jdir; # ifndef SPHERICAL_GEOMETRY d.z() = (p - p0)&kdir; # else d.z() = mag(p) - mag(p0); # endif if (ip == 0) { scale = cmptMax(cmptMag((d))); } // Scale the radius vector d /= scale; Polynomial::addCoeffs ( B[ip], d, wts[ip], dim_ ); } // Additional weighting for constant and linear terms for(label i = 0; i < B.n(); i++) { B[i][0] *= wts[0]; B[i][1] *= wts[0]; } // Set the fit label stencilSize = C.size(); coeffsi.setSize(stencilSize); bool goodFit = false; for(int iIt = 0; iIt < 8 && !goodFit; iIt++) { SVD svd(B, SMALL); scalar maxCoeff = 0; label maxCoeffi = 0; for(label i=0; i<stencilSize; i++) { coeffsi[i] = wts[0]*wts[i]*svd.VSinvUt()[0][i]; if (mag(coeffsi[i]) > maxCoeff) { maxCoeff = mag(coeffsi[i]); maxCoeffi = i; } } if (linearCorrection_) { goodFit = (mag(coeffsi[0] - wLin) < linearLimitFactor_*wLin) && (mag(coeffsi[1] - (1 - wLin)) < linearLimitFactor_*(1 - wLin)) && maxCoeffi <= 1; } else { // Upwind: weight on face is 1. goodFit = (mag(coeffsi[0] - 1.0) < linearLimitFactor_*1.0) && maxCoeffi <= 1; } // if (goodFit && iIt > 0) // { // Info << "FitData<Polynomial>::calcFit" // << "(const List<point>& C, const label facei" << nl // << "Can now fit face " << facei << " iteration " << iIt // << " with sum of weights " << sum(coeffsi) << nl // << " Weights " << coeffsi << nl // << " Linear weights " << wLin << " " << 1 - wLin << nl // << " sing vals " << svd.S() << endl; // } if (!goodFit) // (not good fit so increase weight in the centre and weight // for constant and linear terms) { // if (iIt == 7) // { // WarningIn // ( // "FitData<Polynomial>::calcFit" // "(const List<point>& C, const label facei" // ) << "Cannot fit face " << facei << " iteration " << iIt // << " with sum of weights " << sum(coeffsi) << nl // << " Weights " << coeffsi << nl // << " Linear weights " << wLin << " " << 1 - wLin << nl // << " sing vals " << svd.S() << endl; // } wts[0] *= 10; if (linearCorrection_) { wts[1] *= 10; } for(label j = 0; j < B.m(); j++) { B[0][j] *= 10; B[1][j] *= 10; } for(label i = 0; i < B.n(); i++) { B[i][0] *= 10; B[i][1] *= 10; } } } if (goodFit) { if (linearCorrection_) { // Remove the uncorrected linear coefficients coeffsi[0] -= wLin; coeffsi[1] -= 1 - wLin; } else { // Remove the uncorrected upwind coefficients coeffsi[0] -= 1.0; } } else { // if (debug) // { WarningIn ( "FitData<Polynomial>::calcFit(..)" ) << "Could not fit face " << facei << " Weights = " << coeffsi << ", reverting to linear." << nl << " Linear weights " << wLin << " " << 1 - wLin << endl; // } coeffsi = 0; } }
void Foam::printMeshStats(const polyMesh& mesh, const bool allTopology) { Info<< "Mesh stats" << nl << " points: " << returnReduce(mesh.points().size(), sumOp<label>()) << nl; label nInternalPoints = returnReduce ( mesh.nInternalPoints(), sumOp<label>() ); if (nInternalPoints != -Pstream::nProcs()) { Info<< " internal points: " << nInternalPoints << nl; if (returnReduce(mesh.nInternalPoints(), minOp<label>()) == -1) { WarningIn("Foam::printMeshStats(const polyMesh&, const bool)") << "Some processors have their points sorted into internal" << " and external and some do not." << endl << "This can cause problems later on." << endl; } } if (allTopology && nInternalPoints != -Pstream::nProcs()) { label nEdges = returnReduce(mesh.nEdges(), sumOp<label>()); label nInternalEdges = returnReduce ( mesh.nInternalEdges(), sumOp<label>() ); label nInternal1Edges = returnReduce ( mesh.nInternal1Edges(), sumOp<label>() ); label nInternal0Edges = returnReduce ( mesh.nInternal0Edges(), sumOp<label>() ); Info<< " edges: " << nEdges << nl << " internal edges: " << nInternalEdges << nl << " internal edges using one boundary point: " << nInternal1Edges-nInternal0Edges << nl << " internal edges using two boundary points: " << nInternalEdges-nInternal1Edges << nl; } label nFaces = returnReduce(mesh.faces().size(), sumOp<label>()); label nIntFaces = returnReduce(mesh.faceNeighbour().size(), sumOp<label>()); label nCells = returnReduce(mesh.cells().size(), sumOp<label>()); Info<< " faces: " << nFaces << nl << " internal faces: " << nIntFaces << nl << " cells: " << nCells << nl << " faces per cell: " << scalar(nFaces + nIntFaces)/max(1, nCells) << nl << " boundary patches: " << mesh.boundaryMesh().size() << nl << " point zones: " << mesh.pointZones().size() << nl << " face zones: " << mesh.faceZones().size() << nl << " cell zones: " << mesh.cellZones().size() << nl << endl; // Construct shape recognizers hexMatcher hex; prismMatcher prism; wedgeMatcher wedge; pyrMatcher pyr; tetWedgeMatcher tetWedge; tetMatcher tet; // Counters for different cell types label nHex = 0; label nWedge = 0; label nPrism = 0; label nPyr = 0; label nTet = 0; label nTetWedge = 0; label nUnknown = 0; Map<label> polyhedralFaces; for (label cellI = 0; cellI < mesh.nCells(); cellI++) { if (hex.isA(mesh, cellI)) { nHex++; } else if (tet.isA(mesh, cellI)) { nTet++; } else if (pyr.isA(mesh, cellI)) { nPyr++; } else if (prism.isA(mesh, cellI)) { nPrism++; } else if (wedge.isA(mesh, cellI)) { nWedge++; } else if (tetWedge.isA(mesh, cellI)) { nTetWedge++; } else { nUnknown++; polyhedralFaces(mesh.cells()[cellI].size())++; } } reduce(nHex,sumOp<label>()); reduce(nPrism,sumOp<label>()); reduce(nWedge,sumOp<label>()); reduce(nPyr,sumOp<label>()); reduce(nTetWedge,sumOp<label>()); reduce(nTet,sumOp<label>()); reduce(nUnknown,sumOp<label>()); Info<< "Overall number of cells of each type:" << nl << " hexahedra: " << nHex << nl << " prisms: " << nPrism << nl << " wedges: " << nWedge << nl << " pyramids: " << nPyr << nl << " tet wedges: " << nTetWedge << nl << " tetrahedra: " << nTet << nl << " polyhedra: " << nUnknown << endl; if (nUnknown > 0) { Pstream::mapCombineGather(polyhedralFaces, plusEqOp<label>()); Info<< " Breakdown of polyhedra by number of faces:" << nl << " faces" << " number of cells" << endl; const labelList sortedKeys = polyhedralFaces.sortedToc(); forAll(sortedKeys, keyI) { const label nFaces = sortedKeys[keyI]; Info<< setf(std::ios::right) << setw(13) << nFaces << " " << polyhedralFaces[nFaces] << nl; } }
Foam::SVD::SVD(const scalarRectangularMatrix& A, const scalar minCondition) : U_(A), V_(A.m(), A.m()), S_(A.m()), VSinvUt_(A.m(), A.n()), nZeros_(0) { // SVDcomp to find U_, V_ and S_ - the singular values const label Um = U_.m(); const label Un = U_.n(); scalarList rv1(Um); scalar g = 0; scalar scale = 0; scalar s = 0; scalar anorm = 0; label l = 0; for (label i = 0; i < Um; i++) { l = i+2; rv1[i] = scale*g; g = s = scale = 0; if (i < Un) { for (label k = i; k < Un; k++) { scale += mag(U_[k][i]); } if (scale != 0) { for (label k = i; k < Un; k++) { U_[k][i] /= scale; s += U_[k][i]*U_[k][i]; } scalar f = U_[i][i]; g = -sign(Foam::sqrt(s), f); scalar h = f*g - s; U_[i][i] = f - g; for (label j = l-1; j < Um; j++) { s = 0; for (label k = i; k < Un; k++) { s += U_[k][i]*U_[k][j]; } f = s/h; for (label k = i; k < A.n(); k++) { U_[k][j] += f*U_[k][i]; } } for (label k = i; k < Un; k++) { U_[k][i] *= scale; } } } S_[i] = scale*g; g = s = scale = 0; if (i+1 <= Un && i != Um) { for (label k = l-1; k < Um; k++) { scale += mag(U_[i][k]); } if (scale != 0) { for (label k=l-1; k < Um; k++) { U_[i][k] /= scale; s += U_[i][k]*U_[i][k]; } scalar f = U_[i][l-1]; g = -sign(Foam::sqrt(s),f); scalar h = f*g - s; U_[i][l-1] = f - g; for (label k = l-1; k < Um; k++) { rv1[k] = U_[i][k]/h; } for (label j = l-1; j < Un; j++) { s = 0; for (label k = l-1; k < Um; k++) { s += U_[j][k]*U_[i][k]; } for (label k = l-1; k < Um; k++) { U_[j][k] += s*rv1[k]; } } for (label k = l-1; k < Um; k++) { U_[i][k] *= scale; } } } anorm = max(anorm, mag(S_[i]) + mag(rv1[i])); } for (label i = Um-1; i >= 0; i--) { if (i < Um-1) { if (g != 0) { for (label j = l; j < Um; j++) { V_[j][i] = (U_[i][j]/U_[i][l])/g; } for (label j=l; j < Um; j++) { s = 0; for (label k = l; k < Um; k++) { s += U_[i][k]*V_[k][j]; } for (label k = l; k < Um; k++) { V_[k][j] += s*V_[k][i]; } } } for (label j = l; j < Um;j++) { V_[i][j] = V_[j][i] = 0.0; } } V_[i][i] = 1; g = rv1[i]; l = i; } for (label i = min(Um, Un) - 1; i >= 0; i--) { l = i+1; g = S_[i]; for (label j = l; j < Um; j++) { U_[i][j] = 0.0; } if (g != 0) { g = 1.0/g; for (label j = l; j < Um; j++) { s = 0; for (label k = l; k < Un; k++) { s += U_[k][i]*U_[k][j]; } scalar f = (s/U_[i][i])*g; for (label k = i; k < Un; k++) { U_[k][j] += f*U_[k][i]; } } for (label j = i; j < Un; j++) { U_[j][i] *= g; } } else { for (label j = i; j < Un; j++) { U_[j][i] = 0.0; } } ++U_[i][i]; } for (label k = Um-1; k >= 0; k--) { for (label its = 0; its < 35; its++) { bool flag = true; label nm; for (l = k; l >= 0; l--) { nm = l-1; if (mag(rv1[l]) + anorm == anorm) { flag = false; break; } if (mag(S_[nm]) + anorm == anorm) break; } if (flag) { scalar c = 0.0; s = 1.0; for (label i = l-1; i < k+1; i++) { scalar f = s*rv1[i]; rv1[i] = c*rv1[i]; if (mag(f) + anorm == anorm) break; g = S_[i]; scalar h = sqrtSumSqr(f, g); S_[i] = h; h = 1.0/h; c = g*h; s = -f*h; for (label j = 0; j < Un; j++) { scalar y = U_[j][nm]; scalar z = U_[j][i]; U_[j][nm] = y*c + z*s; U_[j][i] = z*c - y*s; } } } scalar z = S_[k]; if (l == k) { if (z < 0.0) { S_[k] = -z; for (label j = 0; j < Um; j++) V_[j][k] = -V_[j][k]; } break; } if (its == 34) { WarningIn ( "SVD::SVD" "(scalarRectangularMatrix& A, const scalar minCondition)" ) << "no convergence in 35 SVD iterations" << endl; } scalar x = S_[l]; nm = k-1; scalar y = S_[nm]; g = rv1[nm]; scalar h = rv1[k]; scalar f = ((y - z)*(y + z) + (g - h)*(g + h))/(2.0*h*y); g = sqrtSumSqr(f, scalar(1)); f = ((x - z)*(x + z) + h*((y/(f + sign(g, f))) - h))/x; scalar c = 1.0; s = 1.0; for (label j = l; j <= nm; j++) { label i = j + 1; g = rv1[i]; y = S_[i]; h = s*g; g = c*g; scalar z = sqrtSumSqr(f, h); rv1[j] = z; c = f/z; s = h/z; f = x*c + g*s; g = g*c - x*s; h = y*s; y *= c; for (label jj = 0; jj < Um; jj++) { x = V_[jj][j]; z = V_[jj][i]; V_[jj][j] = x*c + z*s; V_[jj][i] = z*c - x*s; } z = sqrtSumSqr(f, h); S_[j] = z; if (z) { z = 1.0/z; c = f*z; s = h*z; } f = c*g + s*y; x = c*y - s*g; for (label jj=0; jj < Un; jj++) { y = U_[jj][j]; z = U_[jj][i]; U_[jj][j] = y*c + z*s; U_[jj][i] = z*c - y*s; } } rv1[l] = 0.0; rv1[k] = f; S_[k] = x; } } // zero singular values that are less than minCondition*maxS const scalar minS = minCondition*S_[findMax(S_)]; for (label i = 0; i < S_.size(); i++) { if (S_[i] <= minS) { //Info << "Removing " << S_[i] << " < " << minS << endl; S_[i] = 0; nZeros_++; } } // now multiply out to find the pseudo inverse of A, VSinvUt_ multiply(VSinvUt_, V_, inv(S_), U_.T()); // test SVD /*scalarRectangularMatrix SVDA(A.n(), A.m()); multiply(SVDA, U_, S_, transpose(V_)); scalar maxDiff = 0; scalar diff = 0; for(label i = 0; i < A.n(); i++) { for(label j = 0; j < A.m(); j++) { diff = mag(A[i][j] - SVDA[i][j]); if (diff > maxDiff) maxDiff = diff; } } Info << "Maximum discrepancy between A and svd(A) = " << maxDiff << endl; if (maxDiff > 4) { Info << "singular values " << S_ << endl; } */ }