diff --git a/applications/utilities/postProcessing/noise/noise.C b/applications/utilities/postProcessing/noise/noise.C index c872b1557ce74419df4b78a0c090f64de21fe176..089efeefac8724dc3fd5c7e3a2f17e89680f6aea 100644 --- a/applications/utilities/postProcessing/noise/noise.C +++ b/applications/utilities/postProcessing/noise/noise.C @@ -102,6 +102,8 @@ using namespace Foam; int main(int argc, char *argv[]) { + argList::noCheckProcessorDirectories(); + #include "addDictOption.H" #include "setRootCase.H" #include "createTime.H" diff --git a/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/extractFromFile.H b/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/extractFromFile.H index 83853fab2debf4b2eff8cd39a71e07e74def950d..8cd5cf4a97d17c54d305a4005d0c080404dac794 100644 --- a/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/extractFromFile.H +++ b/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/extractFromFile.H @@ -27,6 +27,7 @@ Class Description Run-time selectable surface feature extraction. + Selectable as "extractFromFile". Mandatory dictionary entries: "featureEdgeFile". Optional dictionary entries: "geometricTestOnly". @@ -60,17 +61,13 @@ class extractFromFile public: - // Constructors - - //- Construct from dictionary - extractFromFile(const dictionary& dict); - + //- Construct from dictionary + extractFromFile(const dictionary& dict); //- Destructor virtual ~extractFromFile(); - - //- Extracted features from surface + //- Features loaded (extracted) from featureEdgeFile virtual autoPtr<surfaceFeatures> features ( const triSurface& surf diff --git a/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/extractFromNone.C b/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/extractFromNone.C index c49db760a98269e4728a28c1333afe7bad31dbce..45061472c462af117a88ff10e10bfe7466299b2d 100644 --- a/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/extractFromNone.C +++ b/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/extractFromNone.C @@ -52,10 +52,10 @@ Foam::surfaceFeaturesExtraction::extractFromNone::extractFromNone : method() { - const dictionary& coeffDict = dict.optionalSubDict("noneCoeffs"); + // A "noneCoeffs" sub-dictionary doesn't make much sense. - coeffDict.readIfPresent("includedAngle", includedAngle_); - coeffDict.readIfPresent("geometricTestOnly", geometricTestOnly_); + dict.readIfPresent("includedAngle", includedAngle_); + dict.readIfPresent("geometricTestOnly", geometricTestOnly_); } @@ -67,7 +67,6 @@ Foam::surfaceFeaturesExtraction::extractFromNone::~extractFromNone() // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // - Foam::autoPtr<Foam::surfaceFeatures> Foam::surfaceFeaturesExtraction::extractFromNone::features ( diff --git a/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/extractFromNone.H b/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/extractFromNone.H index 9f9b94410f47ba38a6ccac0af1d814b033ba4d09..9cc9ebae6013c8766c2bfab4a8efaf411d36d181 100644 --- a/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/extractFromNone.H +++ b/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/extractFromNone.H @@ -28,6 +28,7 @@ Description Run-time selectable surface feature extraction - no extraction. Primarily useful with self-intersection methods. + Selectable as "none". Optional dictionary entries: "includedAngle", "geometricTestOnly". SourceFiles @@ -58,16 +59,12 @@ class extractFromNone public: - // Constructors - - //- Construct from dictionary - extractFromNone(const dictionary& dict); - + //- Construct from dictionary + extractFromNone(const dictionary& dict); //- Destructor virtual ~extractFromNone(); - //- Extracted features from surface (no-op) virtual autoPtr<surfaceFeatures> features ( diff --git a/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/extractFromSurface.H b/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/extractFromSurface.H index 3ad3412819aa9db252c531deb18d13d0df28f8c8..83c2888d02f6b4227bf28c227cae6ddb6901ed7f 100644 --- a/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/extractFromSurface.H +++ b/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/extractFromSurface.H @@ -27,6 +27,8 @@ Class Description Run-time selectable surface feature extraction - extract from surface. + Selectable as "extractFromSurface". + Mandatory dictionary entries: "includedAngle". Optional dictionary entries: "geometricTestOnly". @@ -57,23 +59,18 @@ class extractFromSurface { public: - // Constructors - - //- Construct from dictionary - extractFromSurface(const dictionary& dict); - + //- Construct from dictionary + extractFromSurface(const dictionary& dict); //- Destructor virtual ~extractFromSurface(); - - //- Extracted features from surface + //- Features extracted from surface virtual autoPtr<surfaceFeatures> features ( const triSurface& surf ) const override; - }; diff --git a/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/surfaceFeaturesExtraction.C b/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/surfaceFeaturesExtraction.C index 28bd8f092d7479e785fe718de4d422dbab87750d..2108e73a9df708bdecf14290ad73ca1f67613a25 100644 --- a/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/surfaceFeaturesExtraction.C +++ b/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/surfaceFeaturesExtraction.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2017 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2017 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -70,22 +70,20 @@ Foam::surfaceFeaturesExtraction::method::New { const word methodName = dict.lookup("extractionMethod"); - dictionaryConstructorTable::iterator cstrIter = - dictionaryConstructorTablePtr_->find(methodName); + auto cstrIter = dictionaryConstructorTablePtr_->cfind(methodName); if (!cstrIter.found()) { FatalIOErrorInFunction ( dict - ) << "Unknown extractionMethod " - << methodName << nl << nl - << "Valid extraction methods: :" << nl + ) << "Unknown extractionMethod " << methodName << nl << nl + << "Valid extraction methods:" << nl << flatOutput(dictionaryConstructorTablePtr_->sortedToc()) << exit(FatalIOError); } - return autoPtr<method>(cstrIter()(dict)); + return autoPtr<method>(cstrIter.object()(dict)); } diff --git a/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/surfaceFeaturesExtraction.H b/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/surfaceFeaturesExtraction.H index 6f9482144fef93a9facf73dc31501f5f56aa06b9..71c5ba5bc5a24dc0d1a43452f9f084855684631a 100644 --- a/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/surfaceFeaturesExtraction.H +++ b/applications/utilities/surface/surfaceFeatureExtract/extractionMethod/surfaceFeaturesExtraction.H @@ -21,11 +21,17 @@ License You should have received a copy of the GNU General Public License along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. +Namespace + Foam::surfaceFeaturesExtraction + +Description + Namespace for run-time selectable surface feature extraction methods. + Class Foam::surfaceFeaturesExtraction::method Description - Run-time selectable surface feature extraction methods. + Abstract base for run-time selectable surface feature extraction methods. SourceFiles surfaceFeaturesExtraction.C @@ -123,7 +129,6 @@ public: }; - // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace surfaceFeaturesExtraction diff --git a/applications/utilities/surface/surfaceFeatureExtract/surfaceFeatureExtract.C b/applications/utilities/surface/surfaceFeatureExtract/surfaceFeatureExtract.C index 7cd22735a72bd66984859485372800894eccb7e3..bcf8358a105009fcb5e900b15ff123b95696af6a 100644 --- a/applications/utilities/surface/surfaceFeatureExtract/surfaceFeatureExtract.C +++ b/applications/utilities/surface/surfaceFeatureExtract/surfaceFeatureExtract.C @@ -31,6 +31,153 @@ Description Extracts and writes surface features to file. All but the basic feature extraction is a work-in-progress. + The extraction process is driven by the \a system/surfaceFeatureExtractDict + dictionary, but the \a -dict option can be used to define an alternative + location. + + The \a system/surfaceFeatureExtractDict dictionary contains entries + for each extraction process. + The name of the individual dictionary is used to load the input surface + (found under \a constant/triSurface) and also as the basename for the + output. + + If the \c surfaces entry is present in a sub-dictionary, it has absolute + precedence over a surface name deduced from the dictionary name. + If the dictionary name itself does not have an extension, the \c surfaces + entry becomes mandatory since in this case the dictionary name cannot + represent an input surface file (ie, there is no file extension). + The \c surfaces entry is a wordRe list, which allows loading and + combining of multiple surfaces. Any exactly specified surface names must + exist, but surfaces selected via regular expressions need not exist. + The selection mechanism preserves order and is without duplicates. + For example, + \verbatim + dictName + { + surfaces (surface1.stl "other.*" othersurf.obj); + ... + } + \endverbatim + + When loading surfaces, the points/faces/regions of each surface are + normally offset to create an aggregated surface. No merging of points + or faces is done. The optional entry \c loadingOption can be used to + adjust the treatment of the regions when loading single or multiple files, + with selections according to the Foam::triSurfaceLoader::loadingOption + enumeration. + \verbatim + dictName + { + // Optional treatment of surface regions when loading + // (single, file, offset, merge) + loadingOption file; + ... + } + \endverbatim + The \c loadingOption is primarily used in combination with the + \c intersectionMethod (specifically its \c region option). + The default \c loadingOption is normally \c offset, + but this changes to \c file if the \c intersectionMethod + \c region is being used. + + Once surfaces have been loaded, the first stage is to extract + features according to the specified \c extractionMethod with values + as per the following table: + \table + extractionMethod | Description + none | No feature extraction + extractFromFile | Load features from the file named in featureEdgeFile + extractFromSurface | Extract features from surface geometry + \endtable + + There are a few entries that influence the extraction behaviour: + \verbatim + // File to use for extractFromFile input + featureEdgeFile "FileName" + + // Mark edges whose adjacent surface normals are at an angle less + // than includedAngle as features + // - 0 : selects no edges + // - 180: selects all edges + includedAngle 120; + + // Do not mark region edges + geometricTestOnly yes; + \endverbatim + + This initial set of edges can be trimmed: + \verbatim + trimFeatures + { + // Remove features with fewer than the specified number of edges + minElem 0; + + // Remove features shorter than the specified cumulative length + minLen 0.0; + } + \endverbatim + + and subsetted + \verbatim + subsetFeatures + { + // Use a plane to select feature edges (normal)(basePoint) + // Only keep edges that intersect the plane + plane (1 0 0)(0 0 0); + + // Select feature edges using a box // (minPt)(maxPt) + // Only keep edges inside the box: + insideBox (0 0 0)(1 1 1); + + // Only keep edges outside the box: + outsideBox (0 0 0)(1 1 1); + + // Keep nonManifold edges (edges with >2 connected faces where + // the faces form more than two different normal planes) + nonManifoldEdges yes; + + // Keep open edges (edges with 1 connected face) + openEdges yes; + } + \endverbatim + + Subsequently, additional features can be added from another file: + \verbatim + addFeatures + { + // Add (without merging) another extendedFeatureEdgeMesh + name axZ.extendedFeatureEdgeMesh; + } + \endverbatim + + The intersectionMethod provides a final means of adding additional + features. These are loosely termed "self-intersection", since it + detects the face/face intersections of the loaded surface or surfaces. + + \table + intersectionMethod | Description + none | Do nothing + self | All face/face intersections + region | Limit face/face intersections to those between different regions. + \endtable + The optional \c tolerance tuning parameter is available for handling + the face/face intersections, but should normally not be touched. + + As well as the normal extendedFeatureEdgeMesh written, + other items can be selected with boolean switches: + + \table + Output option | Description + closeness | Output the closeness of surface elements to other surface elements. + curvature | Output surface curvature + featureProximity | Output the proximity of feature points and edges to another + writeObj | Write features to OBJ format for postprocessing + writeVTK | Write closeness/curvature/proximity fields as VTK for postprocessing + \endtable + +Note + Although surfaceFeatureExtract can do many things, there are still a fair + number of corner cases where it may not produce the desired result. \*---------------------------------------------------------------------------*/ #include "argList.H" @@ -60,16 +207,26 @@ int main(int argc, char *argv[]) { argList::addNote ( - "extract and write surface features to file" + "Extract and write surface features to file" ); argList::noParallel(); argList::noFunctionObjects(); - #include "addDictOption.H" + argList::addOption + ( + "dict", + "file", + "read surfaceFeatureExtractDict from specified location" + ); #include "setRootCase.H" #include "createTime.H" + Info<< nl + << "Note: " + << "Feature line extraction only valid on closed manifold surfaces" + << nl << nl; + const word dictName("surfaceFeatureExtractDict"); #include "setSystemRunTimeDictionaryIO.H" @@ -82,44 +239,58 @@ int main(int argc, char *argv[]) // Where to write VTK output files const fileName vtkOutputDir = runTime.constantPath()/"triSurface"; - forAllConstIter(dictionary, dict, iter) + forAllConstIters(dict, iter) { - const word& dictName = iter().keyword(); - - if (!iter().isDict()) + if (!iter().isDict() || iter().keyword().isPattern()) { continue; } + const dictionary& surfaceDict = iter().dict(); if (!surfaceDict.found("extractionMethod")) { + // Insist on an extractionMethod continue; } + // The output name based in dictionary name (without extensions) + const word& dictName = iter().keyword(); + const word outputName = dictName.lessExt(); + autoPtr<surfaceFeaturesExtraction::method> extractor = surfaceFeaturesExtraction::method::New ( surfaceDict ); - // The output name, cleansed of extensions - // Optional "output" entry, or the dictionary name. - const word outputName = - fileName + // We don't needs the intersectionMethod yet, but can use it + // for setting a reasonable loading option + const surfaceIntersection::intersectionType selfIntersect = + surfaceIntersection::selfIntersectionNames.lookupOrDefault ( - surfaceDict.lookupOrDefault<word>("output", dictName) - ).lessExt(); - - // The "surfaces" entry is normally optional, but if the sub-dictionary - // is itself called "surfaces", then this becomes mandatory. - // This provides a simple means of handling both situations without an - // additional switch. - if + "intersectionMethod", + surfaceDict, + surfaceIntersection::NONE + ); + + const Switch writeObj = surfaceDict.lookupOrDefault<Switch> ( - dictName == "surfaces" // mandatory - || surfaceDict.found("surfaces") // or optional - ) + "writeObj", + Switch::OFF + ); + const Switch writeVTK = surfaceDict.lookupOrDefault<Switch> + ( + "writeVTK", + Switch::OFF + ); + + // The "surfaces" entry is normally optional, but make it mandatory + // if the dictionary name doesn't have an extension + // (ie, probably not a surface filename at all). + // If it is missing, this will fail nicely with an appropriate error + // message. + if (surfaceDict.found("surfaces") || !dictName.hasExt()) { loader.select(wordReList(surfaceDict.lookup("surfaces"))); } @@ -128,39 +299,45 @@ int main(int argc, char *argv[]) loader.select(dictName); } + // DebugVar(loader.available()); + // DebugVar(outputName); + if (loader.selected().empty()) { FatalErrorInFunction << "No surfaces specified/found for entry: " << dictName << exit(FatalError); } - // DebugVar(loader.available()); - // DebugVar(outputName); - - Info<< "Surfaces : "; + Info<< "Surfaces : "; if (loader.selected().size() == 1) { - Info<< loader.selected()[0] << nl; + Info<< loader.selected().first() << nl; } else { Info<< flatOutput(loader.selected()) << nl; } - Info<< "Output : " << outputName << nl; + Info<< "Output : " << outputName << nl; + // Loading option - default depends on context triSurfaceLoader::loadingOption loadingOption = triSurfaceLoader::loadingOptionNames.lookupOrDefault ( "loadingOption", surfaceDict, - triSurfaceLoader::loadingOption::OFFSET_REGION + ( + selfIntersect == surfaceIntersection::SELF_REGION + ? triSurfaceLoader::FILE_REGION + : triSurfaceLoader::OFFSET_REGION + ) ); - Info<<"loading with " - << triSurfaceLoader::loadingOptionNames[loadingOption] - << endl; - + Info<<"Load options : " + << triSurfaceLoader::loadingOptionNames[loadingOption] << nl + << "Write options:" + << " writeObj=" << writeObj + << " writeVTK=" << writeVTK << nl; // Load a single file, or load and combine multiple selected files autoPtr<triSurface> surfPtr = loader.load(loadingOption); @@ -173,25 +350,12 @@ int main(int argc, char *argv[]) triSurface surf = surfPtr(); - const Switch writeVTK = surfaceDict.lookupOrDefault<Switch> - ( - "writeVTK", - Switch::OFF - ); - const Switch writeObj = surfaceDict.lookupOrDefault<Switch> - ( - "writeObj", - Switch::OFF - ); - - Info<< "write VTK: " << writeVTK << nl; - - Info<< "Feature line extraction is only valid on closed manifold " + Info<< "NB: Feature line extraction is only valid on closed manifold " << "surfaces." << nl; - Info<< nl << "Statistics:" << nl; + Info<< nl + << "Statistics:" << nl; surf.writeStats(Info); - Info<< nl; // Need a copy as plain faces if outputting VTK format faceList faces; @@ -403,14 +567,6 @@ int main(int argc, char *argv[]) feMesh.add(addFeMesh); } - const surfaceIntersection::intersectionType selfIntersect = - surfaceIntersection::selfIntersectionNames.lookupOrDefault - ( - "intersectionMethod", - surfaceDict, - surfaceIntersection::NONE - ); - if (selfIntersect != surfaceIntersection::NONE) { triSurfaceSearch query(surf); @@ -461,7 +617,8 @@ int main(int argc, char *argv[]) feMesh.write(); - // Write a featureEdgeMesh for backwards compatibility + // Write a featureEdgeMesh (.eMesh) for backwards compatibility + // Used by snappyHexMesh (JUN-2017) if (true) { featureEdgeMesh bfeMesh diff --git a/applications/utilities/surface/surfaceFeatureExtract/surfaceFeatureExtractDict b/applications/utilities/surface/surfaceFeatureExtract/surfaceFeatureExtractDict index 89f5b9c6b78426933007f208573d7846b73b548b..176a0e193842f6aba0610b97b3a4871bdf1548ae 100644 --- a/applications/utilities/surface/surfaceFeatureExtract/surfaceFeatureExtractDict +++ b/applications/utilities/surface/surfaceFeatureExtract/surfaceFeatureExtractDict @@ -16,7 +16,7 @@ FoamFile surface1.stl { - // How to obtain raw features (none | extractFromFile | extractFromSurface) + // Extract raw features (none | extractFromFile | extractFromSurface) extractionMethod extractFromSurface; // Mark edges whose adjacent surface normals are at an angle less @@ -28,37 +28,48 @@ surface1.stl // Do not mark region edges geometricTestOnly yes; - /* alternative specification as coeff dictionary - extractFromSurfaceCoeffs - { - includedAngle 120; + // Generate additional intersection features (none | self | region) + intersectionMethod none; + + // Tolerance for surface intersections + // tolerance 1e-3; + + // Output options: + + // Write features to obj format for postprocessing + writeObj yes; +} + + +// Self intersection (single or multiple surfaces). +// - Use 'surfaces' entry (a wordRe list) if it exists. +// - If the dictionary name does not have an extension, 'surfaces' is mandatory. +outputName1 +{ + extractionMethod none; - geometricTestOnly yes; - } */ + surfaces (surface1.stl surface2.nas); // Generate additional intersection features (none | self | region) - intersectionMethod none; + intersectionMethod self; // Tolerance for surface intersections - tolerance 1e-3; + // tolerance 1e-3; - // Write options + // Output options: - // Write features to obj format for postprocessing - writeObj yes; + // Write features to OBJ format for postprocessing + writeObj yes; } surface2.nas { - // How to obtain raw features (none | extractFromFile | extractFromSurface) + // Extract raw features (none | extractFromFile | extractFromSurface) extractionMethod extractFromFile; - extractFromFileCoeffs - { - // Load from an existing feature edge file - featureEdgeFile "constant/triSurface/featureEdges.nas"; - } + // Load from an existing feature edge file + featureEdgeFile "constant/triSurface/featureEdges.nas"; trimFeatures { @@ -71,16 +82,15 @@ surface2.nas subsetFeatures { - // Use a plane to select feature edges - // (normal)(basePoint) - // Keep only edges that intersect the plane will be included + // Use a plane to select feature edges (normal)(basePoint) + // Only keep edges that intersect the plane plane (1 0 0)(0 0 0); - // Select feature edges using a box - // (minPt)(maxPt) - // Keep edges inside the box: + // Select feature edges using a box // (minPt)(maxPt) + // Only keep edges inside the box: insideBox (0 0 0)(1 1 1); - // Keep edges outside the box: + + // Only keep edges outside the box: outsideBox (0 0 0)(1 1 1); // Keep nonManifold edges (edges with >2 connected faces where @@ -95,110 +105,35 @@ surface2.nas { // Add (without merging) another extendedFeatureEdgeMesh name axZ.extendedFeatureEdgeMesh; - - // Optionally flip features (invert all normals, making - // convex<->concave etc) - //flip false; } - // Output the curvature of the surface - curvature no; - - // Output the proximity of feature points and edges to each other - featureProximity no; - - // The maximum search distance to use when looking for other feature - // points and edges - maxFeatureProximity 1; - - // Out put the closeness of surface elements to other surface elements. - closeness no; // Generate additional intersection features (none | self | region) intersectionMethod none; // Tolerance for surface intersections - tolerance 1e-3; - - // Write options - - // Write features to obj format for postprocessing - writeObj yes; - - // Write surface proximity and curvature fields to vtk format - // for postprocessing - writeVTK no; -} - + // tolerance 1e-3; -// Handle single or multiple surfaces -// -// - If the dictionary is named 'surfaces', it must also contain a 'surfaces' -// entry (wordRe list). -// -// - If other dictionaries contain a 'surfaces' entry, -// it will be taken for the input. -// -dummyName -{ - extractionMethod extractFromSurface; - - surfaces (surface1.stl surface2.nas); + // Output options: - // Base output name (optional) - // output surfaces; - - // Generate additional intersection features (none | self | region) - intersectionMethod self; + // Output the closeness of surface elements to other surface elements. + closeness no; - // Tolerance for surface intersections - tolerance 1e-3; + // Output surface curvature + curvature no; - includedAngle 120; + // Output the proximity of feature points and edges to another + featureProximity no; - // Do not mark region edges - geometricTestOnly yes; + // The maximum search distance when checking feature proximity + maxFeatureProximity 1; - // Write options + // Write features to OBJ format for postprocessing + writeObj no; - // Write features to obj format for postprocessing - writeObj yes; + // Write closeness/curvature/proximity fields as VTK for postprocessing + writeVTK no; } -// Handle single or multiple surfaces -// -// - If the dictionary is named 'surfaces', it must also contain a 'surfaces' -// entry (wordRe list). -// -// - If other dictionaries contain a 'surfaces' entry, -// it will be taken for the input. -// -surfaces -{ - extractionMethod none; - - surfaces (surface1.stl surface2.nas); - - // Base output name (optional) - // output surfaces; - - // Generate additional intersection features (none | self | region) - intersectionMethod self; - - // Tolerance for surface intersections - tolerance 1e-3; - - /* alternative specification as coeff dictionary - noneCoeffs - { - includedAngle 0; - } */ - - // Write options - - // Write features to obj format for postprocessing - writeObj yes; -} - // ************************************************************************* // diff --git a/src/OpenFOAM/global/argList/argList.C b/src/OpenFOAM/global/argList/argList.C index 01b68a32de4aaf63702308af3544a04609801292..72215bc0a03341c09cddebc145d9aac534f2e9bb 100644 --- a/src/OpenFOAM/global/argList/argList.C +++ b/src/OpenFOAM/global/argList/argList.C @@ -43,6 +43,7 @@ License // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // bool Foam::argList::bannerEnabled_ = true; +bool Foam::argList::checkProcessorDirectories_ = true; Foam::SLList<Foam::string> Foam::argList::validArgs; Foam::HashTable<Foam::string> Foam::argList::validOptions; Foam::HashTable<Foam::string> Foam::argList::validParOptions; @@ -194,6 +195,12 @@ void Foam::argList::noParallel() } +void Foam::argList::noCheckProcessorDirectories() +{ + checkProcessorDirectories_ = false; +} + + void Foam::argList::printOptionUsage ( const label location, @@ -759,7 +766,7 @@ void Foam::argList::parse // - normal running : nProcs = dictNProcs = nProcDirs // - decomposition to more processors : nProcs = dictNProcs // - decomposition to fewer processors : nProcs = nProcDirs - if (dictNProcs > Pstream::nProcs()) + if (checkProcessorDirectories_ && dictNProcs > Pstream::nProcs()) { FatalError << source @@ -814,7 +821,11 @@ void Foam::argList::parse { // Possibly going to fewer processors. // Check if all procDirs are there. - if (dictNProcs < Pstream::nProcs()) + if + ( + checkProcessorDirectories_ + && dictNProcs < Pstream::nProcs() + ) { label nProcDirs = 0; while @@ -1337,15 +1348,30 @@ bool Foam::argList::checkRootCase() const return false; } - if (Pstream::master() && !isDir(path())) + if (Pstream::parRun()) { - // Allow slaves on non-existing processor directories, created later - FatalError - << executable_ - << ": cannot open case directory " << path() - << endl; + if (Pstream::master() && (checkProcessorDirectories_ && !isDir(path()))) + { + // Allow slaves on non-existing processor directories created later + FatalError + << executable_ + << ": cannot open case directory " << path() + << endl; - return false; + return false; + } + } + else + { + if (!isDir(path())) + { + FatalError + << executable_ + << ": cannot open case directory " << path() + << endl; + + return false; + } } return true; diff --git a/src/OpenFOAM/global/argList/argList.H b/src/OpenFOAM/global/argList/argList.H index 09c6777261cedff59a35f29fee42d26c6951b200..569125c7da9ac0e4b0955663987e162cfa2c35e5 100644 --- a/src/OpenFOAM/global/argList/argList.H +++ b/src/OpenFOAM/global/argList/argList.H @@ -119,6 +119,9 @@ class argList //- Track enabled/disabled banner state static bool bannerEnabled_; + //- Track enabled/disabled checking of processor directories state + static bool checkProcessorDirectories_; + //- Switch on/off parallel mode. Has to be first to be constructed // so destructor is done last. ParRunControl parRunControl_; @@ -387,6 +390,9 @@ public: //- Remove the parallel options static void noParallel(); + //- Remove checking of processor directories + static void noCheckProcessorDirectories(); + //- Return true if the post-processing option is specified static bool postProcess(int argc, char *argv[]); diff --git a/src/finiteVolume/functionObjects/volRegion/volRegion.C b/src/finiteVolume/functionObjects/volRegion/volRegion.C index 07d4c1775efdc9f98f66b3b1ca18ae89cac56fa7..ab2f65fcfb06a49e6075d78055be88f115255539 100644 --- a/src/finiteVolume/functionObjects/volRegion/volRegion.C +++ b/src/finiteVolume/functionObjects/volRegion/volRegion.C @@ -83,6 +83,7 @@ Foam::functionObjects::volRegion::volRegion ? regionTypeNames_.read(dict.lookup("regionType")) : vrtAll ), + regionName_(polyMesh::defaultRegion), regionID_(-1) { read(dict); diff --git a/src/functionObjects/field/fieldValues/volFieldValue/volFieldValueTemplates.C b/src/functionObjects/field/fieldValues/volFieldValue/volFieldValueTemplates.C index 94a3b8b758ba053b4fc3ee6f5c7ab82b96d8e8fa..a4f1fb82a6cd4609c38052ed828722b10c45ce35 100644 --- a/src/functionObjects/field/fieldValues/volFieldValue/volFieldValueTemplates.C +++ b/src/functionObjects/field/fieldValues/volFieldValue/volFieldValueTemplates.C @@ -217,12 +217,17 @@ bool Foam::functionObjects::fieldValues::volFieldValue::writeValues if (Pstream::master()) { + word outName = fieldName + '_' + regionTypeNames_[regionType_]; + if (this->volRegion::regionName_ != polyMesh::defaultRegion) + { + outName = outName + '-' + this->volRegion::regionName_; + } + IOField<Type> ( IOobject ( - fieldName + '_' + regionTypeNames_[regionType_] - + '-' + volRegion::regionName_, + outName, obr_.time().timeName(), obr_, IOobject::NO_READ, @@ -241,13 +246,17 @@ bool Foam::functionObjects::fieldValues::volFieldValue::writeValues file()<< tab << result; Log << " " << operationTypeNames_[operation_] - << "(" << volRegion::regionName_ << ") of " << fieldName + << "(" << this->volRegion::regionName_ << ") of " << fieldName << " = " << result << endl; // Write state/results information const word& opName = operationTypeNames_[operation_]; - word resultName = - opName + '(' + volRegion::regionName_ + ',' + fieldName + ')'; + word outName = fieldName; + if (this->volRegion::regionName_ != polyMesh::defaultRegion) + { + outName = this->volRegion::regionName_ + ',' + outName; + } + word resultName = opName + '(' + outName + ')'; this->setResult(resultName, result); } diff --git a/src/meshTools/meshTools/meshToolsTemplates.C b/src/meshTools/meshTools/meshToolsTemplates.C index 51d7e328ec8866230ad410cd68240363b243a32e..17dc152a45590c94ab17d8a83412d894e5da2971 100644 --- a/src/meshTools/meshTools/meshToolsTemplates.C +++ b/src/meshTools/meshTools/meshToolsTemplates.C @@ -49,7 +49,7 @@ void Foam::meshTools::writeOBJ } } - os << 'l'; + os << 'f'; forAll(f, fp) { os << ' ' << foamToObj[f[fp]]+1; diff --git a/src/randomProcesses/noise/noiseModels/noiseModel/noiseModel.C b/src/randomProcesses/noise/noiseModels/noiseModel/noiseModel.C index b98f00c8bda13ec2afc036a9bb0e2ae7c9a24849..84ba84ca4be2b13f77479f73294095ecc71a9d16 100644 --- a/src/randomProcesses/noise/noiseModels/noiseModel/noiseModel.C +++ b/src/randomProcesses/noise/noiseModels/noiseModel/noiseModel.C @@ -92,6 +92,28 @@ Foam::scalar Foam::noiseModel::checkUniformTimeStep } +bool Foam::noiseModel::validateBounds(const scalarList& p) const +{ + forAll(p, i) + { + if ((p[i] < minPressure_) || (p[i] > maxPressure_)) + { + WarningInFunction + << "Pressure data at position " << i + << " is outside of permitted bounds:" << nl + << " pressure: " << p[i] << nl + << " minimum pressure: " << minPressure_ << nl + << " maximum pressure: " << maxPressure_ << nl + << endl; + + return false; + } + } + + return true; +} + + Foam::label Foam::noiseModel::findStartTimeIndex ( const instantList& allTimes, @@ -141,6 +163,8 @@ Foam::noiseModel::noiseModel(const dictionary& dict, const bool readFields) startTime_(0), windowModelPtr_(), graphFormat_("raw"), + minPressure_(-0.5*VGREAT), + maxPressure_(0.5*VGREAT), outputPrefix_(), writePrmsf_(true), writeSPL_(true), @@ -178,6 +202,8 @@ bool Foam::noiseModel::read(const dictionary& dict) } dict.readIfPresent("startTime", startTime_); dict.readIfPresent("graphFormat", graphFormat_); + dict.readIfPresent("minPressure", minPressure_); + dict.readIfPresent("maxPressure", maxPressure_); dict.readIfPresent("outputPrefix", outputPrefix_); // Check number of samples - must be a power of 2 for our FFT @@ -225,6 +251,8 @@ bool Foam::noiseModel::read(const dictionary& dict) windowModelPtr_ = windowModel::New(dict, nSamples_); + Info<< nl << endl; + return true; } diff --git a/src/randomProcesses/noise/noiseModels/noiseModel/noiseModel.H b/src/randomProcesses/noise/noiseModels/noiseModel/noiseModel.H index 7b625096cea8b742e2a28b5b6d5539c60ea0e9a7..b74e053dd003a1e9702d94c7d807758928f530ff 100644 --- a/src/randomProcesses/noise/noiseModels/noiseModel/noiseModel.H +++ b/src/randomProcesses/noise/noiseModels/noiseModel/noiseModel.H @@ -126,7 +126,7 @@ protected: //- Upper frequency limit, default = 10kHz scalar fUpper_; - //- Flag to indicate that custom frequenct bounds are being used + //- Flag to indicate that custom frequency bounds are being used bool customBounds_; //- Start time, default = 0s @@ -139,6 +139,15 @@ protected: word graphFormat_; + // Data validation + + //- Min pressure value + scalar minPressure_; + + //- Min pressure value + scalar maxPressure_; + + // Write options //- Output file prefix, default = '' @@ -176,6 +185,9 @@ protected: const scalarList& times ) const; + //- Return true if all pressure data is within min/max bounds + bool validateBounds(const scalarList& p) const; + //- Find and return start time index label findStartTimeIndex ( diff --git a/src/randomProcesses/noise/noiseModels/pointNoise/pointNoise.C b/src/randomProcesses/noise/noiseModels/pointNoise/pointNoise.C index befb1660613d56560d75eab5c3c8def58ce93fe9..209febd8c99421583031ed112650ef45818cb796 100644 --- a/src/randomProcesses/noise/noiseModels/pointNoise/pointNoise.C +++ b/src/randomProcesses/noise/noiseModels/pointNoise/pointNoise.C @@ -84,8 +84,16 @@ void pointNoise::processData Info<< " read " << t.size() << " values" << nl << endl; Info<< "Creating noise FFT" << endl; + const scalar deltaT = checkUniformTimeStep(t); + if (!validateBounds(p)) + { + Info<< "No noise data generated" << endl; + return; + } + + // Determine the windowing windowModelPtr_->validate(t.size()); const windowModel& win = windowModelPtr_();