diff --git a/src/OpenFOAM/db/dictionary/functionEntries/codeStream/codeStream.C b/src/OpenFOAM/db/dictionary/functionEntries/codeStream/codeStream.C index c7df23c8dee551d89b45999bbf59dcc0529f2e15..10e845e0f7a7fa3d33368e6c6d8885e2c24f81b6 100644 --- a/src/OpenFOAM/db/dictionary/functionEntries/codeStream/codeStream.C +++ b/src/OpenFOAM/db/dictionary/functionEntries/codeStream/codeStream.C @@ -94,27 +94,19 @@ bool Foam::functionEntries::codeStream::doingMasterOnlyReading topDict ); - if (debug) - { - Pout<< "codeStream : baseIOdictionary:" << dict.name() - << " master-only-reading:" << d.globalObject() - << endl; - } + DebugPout + << "codeStream : baseIOdictionary:" << dict.name() + << " master-only-reading:" << d.globalObject() << endl; return d.globalObject(); } - else - { - if (debug) - { - Pout<< "codeStream : not a baseIOdictionary:" << dict.name() - << " master-only-reading:" << regIOobject::masterOnlyReading - << endl; - } - // Fall back to regIOobject::masterOnlyReading - return regIOobject::masterOnlyReading; - } + DebugPout + << "codeStream : not a baseIOdictionary:" << dict.name() + << " master-only-reading:" << regIOobject::masterOnlyReading << endl; + + // Fall back to regIOobject::masterOnlyReading + return regIOobject::masterOnlyReading; } @@ -147,17 +139,13 @@ Foam::functionEntries::codeStream::getFunction lib = libs(parentDict).findLibrary(libPath); } + // nothing loaded + // avoid compilation if possible by loading an existing library if (!lib) { DetailInfo << "Using #codeStream with " << libPath << endl; - } - - // nothing loaded - // avoid compilation if possible by loading an existing library - if (!lib) - { if (isA<baseIOdictionary>(topDict)) { // Cached access to dl libs. Guarantees clean up upon destruction @@ -237,26 +225,21 @@ Foam::functionEntries::codeStream::getFunction off_t masterSize = mySize; Pstream::scatter(masterSize); - if (debug) - { - Pout<< endl<< "on processor " << Pstream::myProcNo() - << " have masterSize:" << masterSize - << " and localSize:" << mySize - << endl; - } - + DebugPout + << nl << "on processor " << Pstream::myProcNo() + << " have masterSize:" << masterSize + << " and localSize:" << mySize << endl; if (mySize < masterSize) { - if (debug) - { - Pout<< "Local file " << libPath - << " not of same size (" << mySize - << ") as master (" - << masterSize << "). Waiting for " - << regIOobject::fileModificationSkew - << " seconds." << endl; - } + DebugPout + << "Local file " << libPath + << " not of same size (" << mySize + << ") as master (" + << masterSize << "). Waiting for " + << regIOobject::fileModificationSkew + << " seconds." << endl; + Foam::sleep(regIOobject::fileModificationSkew); // Recheck local size @@ -278,13 +261,10 @@ Foam::functionEntries::codeStream::getFunction } } - if (debug) - { - Pout<< endl<< "on processor " << Pstream::myProcNo() - << " after waiting: have masterSize:" << masterSize - << " and localSize:" << mySize - << endl; - } + DebugPout + << nl << "on processor " << Pstream::myProcNo() + << " after waiting: have masterSize:" << masterSize + << " and localSize:" << mySize << endl; } if (isA<baseIOdictionary>(topDict)) @@ -293,10 +273,8 @@ Foam::functionEntries::codeStream::getFunction // of Time. dlLibraryTable& dlLibs = libs(parentDict); - if (debug) - { - Pout<< "Opening cached dictionary:" << libPath << endl; - } + DebugPout + << "Opening cached dictionary:" << libPath << endl; if (!dlLibs.open(libPath, false)) { @@ -312,10 +290,9 @@ Foam::functionEntries::codeStream::getFunction else { // Uncached opening of libPath - if (debug) - { - Pout<< "Opening uncached dictionary:" << libPath << endl; - } + DebugPout + << "Opening uncached dictionary:" << libPath << endl; + lib = dlOpen(libPath, true); } } diff --git a/src/OpenFOAM/db/dynamicLibrary/codedBase/codedBase.C b/src/OpenFOAM/db/dynamicLibrary/codedBase/codedBase.C index 031b3d8fdd1a3f3b85487273a00fc1a5a50f8576..03af8cddf9e3e4ac497416b8e4f226c90e3a0b4b 100644 --- a/src/OpenFOAM/db/dynamicLibrary/codedBase/codedBase.C +++ b/src/OpenFOAM/db/dynamicLibrary/codedBase/codedBase.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2016-2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- | Copyright (C) 2011-2016 OpenFOAM Foundation @@ -56,7 +56,6 @@ static inline void writeEntryIfPresent const word& key ) { - // non-recursive like dictionary::found, but no pattern-match either const entry* eptr = dict.findEntry(key, keyType::LITERAL); if (eptr) @@ -89,57 +88,58 @@ void* Foam::codedBase::loadLibrary ( const fileName& libPath, const string& globalFuncName, - const dictionary& contextDict + const dynamicCodeContext& context ) const { - void* lib = 0; + // Avoid compilation by loading an existing library + + void* lib = + ( + !libPath.empty() && libs().open(libPath, false) + ? libs().findLibrary(libPath) + : nullptr + ); + + if (!lib) + { + return lib; + } - // avoid compilation by loading an existing library - if (!libPath.empty()) + // verify the loaded version and unload if needed + + // provision for manual execution of code after loading + if (dlSymFound(lib, globalFuncName)) { - if (libs().open(libPath, false)) + loaderFunctionType function = + reinterpret_cast<loaderFunctionType> + ( + dlSym(lib, globalFuncName) + ); + + if (function) + { + (*function)(true); // force load + } + else { - lib = libs().findLibrary(libPath); + FatalIOErrorInFunction(context.dict()) + << "Failed looking up symbol " << globalFuncName + << nl << "from " << libPath << exit(FatalIOError); + } + } + else + { + FatalIOErrorInFunction(context.dict()) + << "Failed looking up symbol " << globalFuncName << nl + << "from " << libPath << exit(FatalIOError); - // verify the loaded version and unload if needed - if (lib) - { - // provision for manual execution of code after loading - if (dlSymFound(lib, globalFuncName)) - { - loaderFunctionType function = - reinterpret_cast<loaderFunctionType> - ( - dlSym(lib, globalFuncName) - ); - - if (function) - { - (*function)(true); // force load - } - else - { - FatalIOErrorInFunction(contextDict) - << "Failed looking up symbol " << globalFuncName - << nl << "from " << libPath << exit(FatalIOError); - } - } - else - { - FatalIOErrorInFunction(contextDict) - << "Failed looking up symbol " << globalFuncName << nl - << "from " << libPath << exit(FatalIOError); - - lib = 0; - if (!libs().close(libPath, false)) - { - FatalIOErrorInFunction(contextDict) - << "Failed unloading library " - << libPath - << exit(FatalIOError); - } - } - } + lib = nullptr; + if (!libs().close(libPath, false)) + { + FatalIOErrorInFunction(context.dict()) + << "Failed unloading library " + << libPath + << exit(FatalIOError); } } @@ -151,17 +151,16 @@ void Foam::codedBase::unloadLibrary ( const fileName& libPath, const string& globalFuncName, - const dictionary& contextDict + const dynamicCodeContext& context ) const { - void* lib = 0; - - if (libPath.empty()) - { - return; - } - lib = libs().findLibrary(libPath); + void* lib = + ( + !libPath.empty() && libs().open(libPath, false) + ? libs().findLibrary(libPath) + : nullptr + ); if (!lib) { @@ -183,7 +182,7 @@ void Foam::codedBase::unloadLibrary } else { - FatalIOErrorInFunction(contextDict) + FatalIOErrorInFunction(context.dict()) << "Failed looking up symbol " << globalFuncName << nl << "from " << libPath << exit(FatalIOError); } @@ -191,7 +190,7 @@ void Foam::codedBase::unloadLibrary if (!libs().close(libPath, false)) { - FatalIOErrorInFunction(contextDict) + FatalIOErrorInFunction(context.dict()) << "Failed unloading library " << libPath << exit(FatalIOError); } @@ -305,21 +304,30 @@ void Foam::codedBase::createLibrary // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // +void Foam::codedBase::setCodeContext(const dictionary& dict) +{ + context_.setCodeContext(dict); +} + + +void Foam::codedBase::append(const std::string& str) +{ + context_.append(str); +} + + void Foam::codedBase::updateLibrary ( - const word& name + const word& name, + const dynamicCodeContext& context ) const { - const dictionary& dict = this->codeDict(); - dynamicCode::checkSecurity ( "codedBase::updateLibrary()", - dict + context ); - dynamicCodeContext context(dict); - // codeName: name + _<sha1> // codeDir : name dynamicCode dynCode @@ -327,10 +335,11 @@ void Foam::codedBase::updateLibrary name + context.sha1().str(true), name ); + const fileName libPath = dynCode.libPath(); - // the correct library was already loaded => we are done + // The correct library was already loaded => we are done if (libs().findLibrary(libPath)) { return; @@ -338,44 +347,55 @@ void Foam::codedBase::updateLibrary DetailInfo << "Using dynamicCode for " << this->description().c_str() - << " at line " << dict.startLineNumber() - << " in " << dict.name() << endl; + << " at line " << context.dict().startLineNumber() + << " in " << context.dict().name() << endl; - // remove instantiation of fvPatchField provided by library + // Remove instantiation of fvPatchField provided by library this->clearRedirect(); - // may need to unload old library + // May need to unload old library unloadLibrary ( oldLibPath_, dynamicCode::libraryBaseName(oldLibPath_), - context.dict() + context ); - // try loading an existing library (avoid compilation when possible) - if (!loadLibrary(libPath, dynCode.codeName(), context.dict())) + // Try loading an existing library (avoid compilation when possible) + if (!loadLibrary(libPath, dynCode.codeName(), context)) { createLibrary(dynCode, context); - loadLibrary(libPath, dynCode.codeName(), context.dict()); + loadLibrary(libPath, dynCode.codeName(), context); } - // retain for future reference + // Retain for future reference oldLibPath_ = libPath; } -// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // - -Foam::codedBase::codedBase() -{} - +void Foam::codedBase::updateLibrary +( + const word& name, + const dictionary& dict +) const +{ + updateLibrary(name, dynamicCodeContext(dict)); +} -// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // -Foam::codedBase::~codedBase() -{} +void Foam::codedBase::updateLibrary(const word& name) const +{ + if (context_.valid()) + { + updateLibrary(name, context_); + } + else + { + updateLibrary(name, dynamicCodeContext(this->codeDict())); + } +} // ************************************************************************* // diff --git a/src/OpenFOAM/db/dynamicLibrary/codedBase/codedBase.H b/src/OpenFOAM/db/dynamicLibrary/codedBase/codedBase.H index 2d318848e94e716ddd78fc54a20a6810f4802a35..a32c8f5e15beaee66fb9db3ce933f556bf6a23a0 100644 --- a/src/OpenFOAM/db/dynamicLibrary/codedBase/codedBase.H +++ b/src/OpenFOAM/db/dynamicLibrary/codedBase/codedBase.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2016 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2016-2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- | Copyright (C) 2011-2016 OpenFOAM Foundation @@ -28,6 +28,15 @@ Class Description Base class for function objects and boundary conditions using dynamic code + that provides methods for managing loading/unloading/updating + of a dynamic library. For these purposes, it uses a dynamicCodeContext + object to maintain information about the state. + + For simple coded objects, the default state management is sufficient. + When there are more complicated code segements + (eg, functionObjects::codedFunctionObject), the state management + must also register these elements as well, starting with an initial + setCodeContext() call and followed by append() to register each element. SourceFiles codedBase.C @@ -38,16 +47,16 @@ SourceFiles #define codedBase_H #include "dictionary.H" +#include "dynamicCodeContext.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { -// Forward declaration of classes +// Forward Declarations class Ostream; class dynamicCode; -class dynamicCodeContext; class dlLibraryTable; /*---------------------------------------------------------------------------*\ @@ -56,11 +65,15 @@ class dlLibraryTable; class codedBase { - // Private data + // Private Data + + //- The code context + dynamicCodeContext context_; //- Previously loaded library mutable fileName oldLibPath_; + // Private Member Functions //- Global loader/unloader function type @@ -71,7 +84,7 @@ class codedBase ( const fileName& libPath, const string& globalFuncName, - const dictionary& contextDict + const dynamicCodeContext& context ) const; //- Execute globalFuncName(false) and unload specified library @@ -79,11 +92,15 @@ class codedBase ( const fileName& libPath, const string& globalFuncName, - const dictionary& contextDict + const dynamicCodeContext& context ) const; //- Create library based on the dynamicCodeContext - void createLibrary(dynamicCode&, const dynamicCodeContext&) const; + void createLibrary + ( + dynamicCode& dynCode, + const dynamicCodeContext& context + ) const; //- No copy construct codedBase(const codedBase&) = delete; @@ -95,22 +112,45 @@ class codedBase protected: //- Write code-dictionary contents - static void writeCodeDict(Ostream&, const dictionary&); + static void writeCodeDict(Ostream& os, const dictionary& dict); + + + // Protected Member Functions + + //- Set code context from a dictionary + void setCodeContext(const dictionary& dict); - //- Update library as required + //- Set code context from a dictionary + void append(const dictionary& dict); + + + //- Update library as required, using the given context void updateLibrary ( - const word& name + const word& name, + const dynamicCodeContext& context ) const; + //- Update library as required, using the given code dictionary + //- to use for the context + void updateLibrary + ( + const word& name, + const dictionary& dict + ) const; + + //- Update library as required, using the predefined context + //- or use the codeDict() to generate one + void updateLibrary(const word& name) const; + //- Get the loaded dynamic libraries virtual dlLibraryTable& libs() const = 0; //- Adapt the context for the current object virtual void prepare ( - dynamicCode&, - const dynamicCodeContext& + dynamicCode& dynCode, + const dynamicCodeContext& context ) const = 0; // Return a description (type + name) for the output @@ -132,11 +172,11 @@ public: // Constructors //- Construct null - codedBase(); + codedBase() = default; //- Destructor - virtual ~codedBase(); + virtual ~codedBase() = default; }; diff --git a/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCode.C b/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCode.C index 7e63d8d298d264046e5af2bd8eebec69853727bd..efe56f30d9122e5576d135d5a7a95301a1b1d27a 100644 --- a/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCode.C +++ b/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCode.C @@ -36,6 +36,16 @@ License #include "dictionary.H" #include "foamVersion.H" +#undef EXT_SO +#ifdef __APPLE__ + #define EXT_SO ".dylib" +#elif defined _WIN32 + #define EXT_SO ".dll" +#else + #define EXT_SO ".so" +#endif + + // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // int Foam::dynamicCode::allowSystemOperations @@ -151,10 +161,8 @@ bool Foam::dynamicCode::resolveTemplates const fileName templateDir(Foam::getEnv(codeTemplateEnvName)); bool allOkay = true; - forAll(templateNames, fileI) + for (const fileName& templateName : templateNames) { - const fileName& templateName = templateNames[fileI]; - fileName file; if (!templateDir.empty() && isDir(templateDir)) { @@ -188,15 +196,16 @@ bool Foam::dynamicCode::resolveTemplates bool Foam::dynamicCode::writeCommentSHA1(Ostream& os) const { - const bool hasSHA1 = filterVars_.found("SHA1sum"); + const auto fnd = filterVars_.cfind("SHA1sum"); - if (hasSHA1) + if (!fnd.found()) { - os << "/* dynamicCode:\n * SHA1 = "; - os.writeQuoted(filterVars_["SHA1sum"], false) << "\n */\n"; + return false; } - return hasSHA1; + os << "/* dynamicCode:\n * SHA1 = "; + os.writeQuoted(*fnd, false) << "\n */\n"; + return true; } @@ -214,7 +223,7 @@ bool Foam::dynamicCode::createMakeFiles() const mkDir(dstFile.path()); OFstream os(dstFile); - //Debug: Info << "Writing to " << dstFile << endl; + //Debug: Info<< "Writing to " << dstFile << endl; if (!os.good()) { FatalErrorInFunction @@ -225,9 +234,9 @@ bool Foam::dynamicCode::createMakeFiles() const writeCommentSHA1(os); // Write compile files - forAll(compileFiles_, fileI) + for (const fileName& file : compileFiles_) { - os.writeQuoted(compileFiles_[fileI], false) << nl; + os.writeQuoted(file, false) << nl; } os << nl @@ -317,13 +326,15 @@ Foam::fileName Foam::dynamicCode::codeRelPath() const } +Foam::fileName Foam::dynamicCode::libPath() const +{ + return codeRoot_/libSubDir_/"lib" + codeName_ + EXT_SO; +} + + Foam::fileName Foam::dynamicCode::libRelPath() const { - #ifdef __APPLE__ - return codeRelPath()/libSubDir_/"lib" + codeName_ + ".dylib"; - #else - return codeRelPath()/libSubDir_/"lib" + codeName_ + ".so"; - #endif + return codeRelPath()/libSubDir_/"lib" + codeName_ + EXT_SO; } @@ -336,7 +347,7 @@ void Foam::dynamicCode::clear() filterVars_.set("typeName", codeName_); filterVars_.set("SHA1sum", SHA1Digest().str()); - // Provide default Make/options + // Default Make/options makeOptions_ = "EXE_INC = -g\n" "\n\nLIB_LIBS = "; @@ -426,7 +437,7 @@ bool Foam::dynamicCode::copyOrCreateFiles(const bool verbose) const << "Could not find the code template(s): " << badFiles << nl << "Under the $" << codeTemplateEnvName - << " directory or via via the <etc>/" + << " directory or via the <etc>/" << codeTemplateDirName << " expansion" << exit(FatalError); } @@ -440,10 +451,9 @@ bool Foam::dynamicCode::copyOrCreateFiles(const bool verbose) const mkDir(outputDir); // Copy/filter files - forAll(resolvedFiles, fileI) + for (const fileName& srcFile : resolvedFiles) { - const fileName& srcFile = resolvedFiles[fileI]; - const fileName dstFile(outputDir/srcFile.name()); + const fileName dstFile(outputDir/srcFile.name()); IFstream is(srcFile); //Debug: Info<< "Reading from " << is.name() << endl; @@ -469,23 +479,20 @@ bool Foam::dynamicCode::copyOrCreateFiles(const bool verbose) const // Create files: - forAll(createFiles_, fileI) + for (const fileAndContent& content : createFiles_) { - const fileName dstFile - ( - outputDir/stringOps::expand(createFiles_[fileI].first()) - ); + const fileName dstFile(outputDir/stringOps::expand(content.first())); mkDir(dstFile.path()); OFstream os(dstFile); - //Debug: Info<< "Writing to " << createFiles_[fileI].first() << endl; + //Debug: Info<< "Writing to " << content.first() << endl; if (!os.good()) { FatalErrorInFunction << "Failed writing " << dstFile << exit(FatalError); } - os.writeQuoted(createFiles_[fileI].second(), false) << nl; + os.writeQuoted(content.second(), false) << nl; } @@ -515,8 +522,7 @@ bool Foam::dynamicCode::wmakeLibso() const else { // Even with details turned off, we want some feedback - Serr - << "Invoking wmake libso " << this->codePath().c_str() << endl; + Serr<< "Invoking wmake libso " << this->codePath().c_str() << endl; } if (Foam::system(cmd) == 0) diff --git a/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCode.H b/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCode.H index 4ed7ffaf3cc2228511552e63591a0a84e23bb698..444057c311b005508180006925b96f40ef253db8 100644 --- a/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCode.H +++ b/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCode.H @@ -219,21 +219,13 @@ public: return codeRoot_/codeDirName_; } - //- Library path for specified code name - // Corresponds to codeRoot()/libSubDir()/lib\<codeName\>.so - fileName libPath() const - { - #ifdef __APPLE__ - return codeRoot_/libSubDir_/"lib" + codeName_ + ".dylib"; - #else - return codeRoot_/libSubDir_/"lib" + codeName_ + ".so"; - #endif - } - //- Path for specified code name relative to \<case\> // Corresponds to topDirName/codeDirName() fileName codeRelPath() const; + //- Library path for specified code name + // Corresponds to codeRoot()/libSubDir()/lib\<codeName\>.so + fileName libPath() const; //- Library path for specified code name relative to \<case\> // Corresponds to diff --git a/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCodeContext.C b/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCodeContext.C index 602b713775063f200950c6c6012ca17ca0ff0642..089b48d0020484414a9615660141b1359e5083b5 100644 --- a/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCodeContext.C +++ b/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCodeContext.C @@ -31,97 +31,104 @@ License // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // +Foam::dynamicCodeContext::dynamicCodeContext() +: + dict_(std::cref<dictionary>(dictionary::null)) +{} + + Foam::dynamicCodeContext::dynamicCodeContext(const dictionary& dict) : - dict_(dict), - code_(), - localCode_(), - include_(), - options_(), - libs_() + dynamicCodeContext() { - // Expand dictionary entries + setCodeContext(dict); +} - // Note: removes any leading/trailing whitespace - // - necessary for compilation options, convenient for includes - // and body. - const entry* codePtr = dict.findEntry("code", keyType::LITERAL); +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // - if (codePtr) - { - codePtr->readEntry(code_); - stringOps::inplaceTrim(code_); - stringOps::inplaceExpand(code_, dict); - } +bool Foam::dynamicCodeContext::valid() const +{ + return &(dict_.get()) != &(dictionary::null); +} - const entry* includePtr = dict.findEntry("codeInclude", keyType::LITERAL); - if (includePtr) - { - includePtr->readEntry(include_); - stringOps::inplaceTrim(include_); - stringOps::inplaceExpand(include_, dict); - } +void Foam::dynamicCodeContext::setCodeContext(const dictionary& dict) +{ + dict_ = std::cref<dictionary>(dict); + sha1_.clear(); - const entry* optionsPtr = dict.findEntry("codeOptions", keyType::LITERAL); + // Expand dictionary entries. + // Removing any leading/trailing whitespace is necessary for compilation + // options, but is also convenient for includes and code body. - if (optionsPtr) + const entry* eptr; + + options_.clear(); + sha1_.append("<codeOptions>"); + if ((eptr = dict.findEntry("codeOptions", keyType::LITERAL)) != nullptr) { - optionsPtr->readEntry(options_); + eptr->readEntry(options_); stringOps::inplaceTrim(options_); stringOps::inplaceExpand(options_, dict); - } - const entry* libsPtr = dict.findEntry("codeLibs", keyType::LITERAL); + sha1_.append(options_); + // No #line for options (Make/options) + // - preprocessed as a single line at this point. Can be fixed. + } - if (libsPtr) + libs_.clear(); + sha1_.append("<codeLibs>"); + if ((eptr = dict.findEntry("codeLibs", keyType::LITERAL)) != nullptr) { - libsPtr->readEntry(libs_); + eptr->readEntry(libs_); stringOps::inplaceTrim(libs_); stringOps::inplaceExpand(libs_, dict); - } - - const entry* localPtr = dict.findEntry("localCode", keyType::LITERAL); - if (localPtr) - { - localPtr->readEntry(localCode_); - stringOps::inplaceTrim(localCode_); - stringOps::inplaceExpand(localCode_, dict); + sha1_.append(libs_); + // No #line for libs + // - preprocessed as a single line at this point. Can be fixed. } - // Calculate SHA1 digest from include, options, localCode, code - OSHA1stream os; - os << include_ << options_ << libs_ << localCode_ << code_; - sha1_ = os.digest(); - - - // Add line number after calculating sha1 since includes processorDDD - // in path which differs between processors. - - if (codePtr) + include_.clear(); + sha1_.append("<codeInclude>"); + if ((eptr = dict.findEntry("codeInclude", keyType::LITERAL)) != nullptr) { - addLineDirective(code_, codePtr->startLineNumber(), dict.name()); + eptr->readEntry(include_); + stringOps::inplaceTrim(include_); + stringOps::inplaceExpand(include_, dict); + + sha1_.append(include_); + addLineDirective(include_, eptr->startLineNumber(), dict.name()); } - if (includePtr) + code_.clear(); + sha1_.append("<code>"); + if ((eptr = dict.findEntry("code", keyType::LITERAL)) != nullptr) { - addLineDirective(include_, includePtr->startLineNumber(), dict.name()); + eptr->readEntry(code_); + stringOps::inplaceTrim(code_); + stringOps::inplaceExpand(code_, dict); + + sha1_.append(code_); + addLineDirective(code_, eptr->startLineNumber(), dict.name()); } - // Do not add line directive to options_ (Make/options) and libs since - // they are preprocessed as a single line at this point. Can be fixed. - if (localPtr) + localCode_.clear(); + sha1_.append("<localCode>"); + if ((eptr = dict.findEntry("localCode", keyType::LITERAL)) != nullptr) { - addLineDirective(localCode_, localPtr->startLineNumber(), dict.name()); + eptr->readEntry(localCode_); + stringOps::inplaceTrim(localCode_); + stringOps::inplaceExpand(localCode_, dict); + + sha1_.append(localCode_); + addLineDirective(localCode_, eptr->startLineNumber(), dict.name()); } } -// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // - -void Foam::dynamicCodeContext::addLineDirective +unsigned Foam::dynamicCodeContext::addLineDirective ( string& code, label lineNum, @@ -130,10 +137,16 @@ void Foam::dynamicCodeContext::addLineDirective { ++lineNum; // Change from 0-based to 1-based - if (lineNum > 0 && !name.empty()) + const auto len = code.length(); + + if (lineNum > 0 && len && !name.empty()) { code = "#line " + Foam::name(lineNum) + " \"" + name + "\"\n" + code; + + return (code.length() - len); } + + return 0; } diff --git a/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCodeContext.H b/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCodeContext.H index 7458bcb2ab1b17ea7d46999fc53295fa398c1938..2e6c21ccabc83ddd71d5ef8a4fbfa33664718e38 100644 --- a/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCodeContext.H +++ b/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCodeContext.H @@ -37,8 +37,9 @@ SourceFiles #ifndef dynamicCodeContext_H #define dynamicCodeContext_H +#include <functional> #include "dictionary.H" -#include "SHA1Digest.H" +#include "SHA1.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -51,19 +52,13 @@ namespace Foam class dynamicCodeContext { - // Private data + // Private Data //- The parent dictionary context - const dictionary& dict_; + std::reference_wrapper<const dictionary> dict_; - //- Optional "code" entry - string code_; - - //- Optional "localCode" entry - string localCode_; - - //- Optional "codeInclude" entry - string include_; + //- The SHA1 of the contents + SHA1 sha1_; //- Optional "codeOptions" entry string options_; @@ -71,24 +66,39 @@ class dynamicCodeContext //- Optional "codeLibs" entry string libs_; - //- Calculated SHA1Digest - SHA1Digest sha1_; + //- Optional "codeInclude" entry + string include_; + + //- Optional "code" entry + string code_; + + //- Optional "localCode" entry + string localCode_; public: // Constructors + //- Construct null + dynamicCodeContext(); + //- Construct from a dictionary - dynamicCodeContext(const dictionary& dict); + explicit dynamicCodeContext(const dictionary& dict); + + + // Member Functions + //- Considered valid if not using dictionary::null as the context + bool valid() const; - // Member functions + //- Set code context from a dictionary + void setCodeContext(const dictionary& dict); //- Return the parent dictionary context const dictionary& dict() const { - return dict_; + return dict_.get(); } //- Return the code-includes @@ -121,20 +131,42 @@ public: return localCode_; } - //- Return SHA1 digest calculated from include, options, code - const SHA1Digest& sha1() const + //- Return SHA1 calculated from options, libs, include, code + const SHA1& sha1() const { return sha1_; } - //- Helper: add \#line directive - // The lineNum is 0-based. No-op if the lineNum is negative. - static void addLineDirective + //- Add content to SHA1 hashing + void append(const std::string& str) + { + sha1_.append(str); + } + + + //- Helper: Prefix a \#line directive to code. + // The input lineNum is 0-based. + // Is a no-op if any of the arguments are invalid + // (lineNum is negative, code or name are empty) + // + // \return The change in string length caused by the directive. + // This can potentially be used to recover the substring portions. + static unsigned addLineDirective ( string& code, label lineNum, const fileName& name ); + + + // Member Operators + + //- Cast to dictionary + operator const dictionary&() const + { + return dict_.get(); + } + }; diff --git a/src/OpenFOAM/fields/pointPatchFields/derived/codedFixedValue/codedFixedValuePointPatchField.C b/src/OpenFOAM/fields/pointPatchFields/derived/codedFixedValue/codedFixedValuePointPatchField.C index e842924dcf872aca5bf292f658ce862ab6d2efa2..357e3ceb83de13c77f791725cc27aaac4a840e93 100644 --- a/src/OpenFOAM/fields/pointPatchFields/derived/codedFixedValue/codedFixedValuePointPatchField.C +++ b/src/OpenFOAM/fields/pointPatchFields/derived/codedFixedValue/codedFixedValuePointPatchField.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2016 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2016-2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- | Copyright (C) 2012-2016 OpenFOAM Foundation @@ -71,27 +71,26 @@ const { const objectRegistry& obr = this->db(); - if (obr.foundObject<IOdictionary>("codeDict")) + const IOdictionary* dictptr = obr.cfindObject<IOdictionary>("codeDict"); + if (dictptr) { - return obr.lookupObject<IOdictionary>("codeDict"); + return *dictptr; } - else - { - return obr.store + + return obr.store + ( + new IOdictionary ( - new IOdictionary + IOobject ( - IOobject - ( - "codeDict", - this->db().time().system(), - this->db(), - IOobject::MUST_READ_IF_MODIFIED, - IOobject::NO_WRITE - ) + "codeDict", + this->db().time().system(), + this->db(), + IOobject::MUST_READ_IF_MODIFIED, + IOobject::NO_WRITE ) - ); - } + ) + ); } @@ -113,7 +112,6 @@ void Foam::codedFixedValuePointPatchField<Type>::prepare dynCode.setFilterVariable("typeName", name_); // Set TemplateType and FieldType filter variables - // (for pointPatchField) setFieldTemplates(dynCode); // Compile filtered C template @@ -122,23 +120,22 @@ void Foam::codedFixedValuePointPatchField<Type>::prepare // Copy filtered H template dynCode.addCopyFile(codeTemplateH); - - // Debugging: make BC verbose + // Debugging: make verbose // dynCode.setFilterVariable("verbose", "true"); // Info<<"compile " << name_ << " sha1: " // << context.sha1() << endl; // Define Make/options dynCode.setMakeOptions - ( - "EXE_INC = -g \\\n" - "-I$(LIB_SRC)/finiteVolume/lnInclude \\\n" - + context.options() - + "\n\nLIB_LIBS = \\\n" - + " -lOpenFOAM \\\n" - + " -lfiniteVolume \\\n" - + context.libs() - ); + ( + "EXE_INC = -g \\\n" + "-I$(LIB_SRC)/finiteVolume/lnInclude \\\n" + + context.options() + + "\n\nLIB_LIBS = \\\n" + " -lOpenFOAM \\\n" + " -lfiniteVolume \\\n" + + context.libs() + ); } diff --git a/src/dynamicMesh/motionSolvers/displacement/codedPoints0/codedPoints0MotionSolver.C b/src/dynamicMesh/motionSolvers/displacement/codedPoints0/codedPoints0MotionSolver.C index e3c0f914dd61a4ab61b39bf83d7eec4ebc6f3d33..e2fddda71dbf91f84241e67ef45cae7bd0ba9034 100644 --- a/src/dynamicMesh/motionSolvers/displacement/codedPoints0/codedPoints0MotionSolver.C +++ b/src/dynamicMesh/motionSolvers/displacement/codedPoints0/codedPoints0MotionSolver.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-2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -63,7 +63,7 @@ void Foam::codedPoints0MotionSolver::prepare // Copy filtered H template dynCode.addCopyFile("codedPoints0MotionSolverTemplate.H"); - // Debugging: make BC verbose + // Debugging: make verbose // dynCode.setFilterVariable("verbose", "true"); // Info<<"compile " << name_ << " sha1: " // << context.sha1() << endl; @@ -73,12 +73,15 @@ void Foam::codedPoints0MotionSolver::prepare ( "EXE_INC = -g \\\n" "-I$(LIB_SRC)/finiteVolume/lnInclude \\\n" - "-I$(LIB_SRC)/fvMotionSolvers/lnInclude \\\n" - "-I$(LIB_SRC)/dynamicMesh/lnInclude \\\n" "-I$(LIB_SRC)/meshTools/lnInclude \\\n" + "-I$(LIB_SRC)/dynamicMesh/lnInclude \\\n" + "-I$(LIB_SRC)/fvMotionSolvers/lnInclude \\\n" + context.options() + "\n\nLIB_LIBS = \\\n" - + " -lfvMotionSolvers \\\n" + " -lfiniteVolume \\\n" + " -lmeshTools \\\n" + " -ldynamicMesh \\\n" + " -lfvMotionSolvers \\\n" + context.libs() ); } diff --git a/src/dynamicMesh/motionSolvers/displacement/codedPoints0/codedPoints0MotionSolver.H b/src/dynamicMesh/motionSolvers/displacement/codedPoints0/codedPoints0MotionSolver.H index d095d9481b10f8ec4a65ebbb151d373297309f62..d54141102e052cb834099662a57296338e812e33 100644 --- a/src/dynamicMesh/motionSolvers/displacement/codedPoints0/codedPoints0MotionSolver.H +++ b/src/dynamicMesh/motionSolvers/displacement/codedPoints0/codedPoints0MotionSolver.H @@ -107,17 +107,17 @@ protected: //- Adapt the context for the current object virtual void prepare(dynamicCode&, const dynamicCodeContext&) const; - // Return a description (type + name) for the output + //- Return a description (type + name) for the output virtual string description() const; - // Clear any redirected objects + //- Clear any redirected objects virtual void clearRedirect() const; - // Get the dictionary to initialize the codeContext + // The dictionary to initialize the codeContext virtual const dictionary& codeDict() const; - //- No copy assignment construct + //- No copy construct codedPoints0MotionSolver(const codedPoints0MotionSolver&) = delete; //- No copy assignment @@ -156,10 +156,10 @@ public: virtual void solve(); //- Update local data for geometry changes - virtual void movePoints(const pointField&); + virtual void movePoints(const pointField& fld); //- Update local data for topology changes - virtual void updateMesh(const mapPolyMesh&); + virtual void updateMesh(const mapPolyMesh& mpm); }; diff --git a/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchField.C index 3ec2b3a5b148596ad99d9e74d275dcbc5dacd2a1..8ca016ba8e97a143c4bbc0c513c8a1ef4f62271a 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchField.C +++ b/src/finiteVolume/fields/fvPatchFields/derived/codedFixedValue/codedFixedValueFvPatchField.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011-2011, 2016 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2011-2011, 2016-2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- | Copyright (C) 2011-2016 OpenFOAM Foundation @@ -54,7 +54,7 @@ void Foam::codedFixedValueFvPatchField<Type>::setFieldTemplates { word fieldType(pTraits<Type>::typeName); - // template type for fvPatchField + // Template type for fvPatchField dynCode.setFilterVariable("TemplateType", fieldType); // Name for fvPatchField - eg, ScalarField, VectorField, ... @@ -70,27 +70,26 @@ const Foam::IOdictionary& Foam::codedFixedValueFvPatchField<Type>::dict() const { const objectRegistry& obr = this->db(); - if (obr.foundObject<IOdictionary>("codeDict")) + const IOdictionary* dictptr = obr.cfindObject<IOdictionary>("codeDict"); + if (dictptr) { - return obr.lookupObject<IOdictionary>("codeDict"); + return *dictptr; } - else - { - return obr.store + + return obr.store + ( + new IOdictionary ( - new IOdictionary + IOobject ( - IOobject - ( - "codeDict", - this->db().time().system(), - this->db(), - IOobject::MUST_READ_IF_MODIFIED, - IOobject::NO_WRITE - ) + "codeDict", + this->db().time().system(), + this->db(), + IOobject::MUST_READ_IF_MODIFIED, + IOobject::NO_WRITE ) - ); - } + ) + ); } @@ -108,36 +107,35 @@ void Foam::codedFixedValueFvPatchField<Type>::prepare const dynamicCodeContext& context ) const { - // take no chances - typeName must be identical to name_ + // Take no chances - typeName must be identical to name_ dynCode.setFilterVariable("typeName", name_); - // set TemplateType and FieldType filter variables - // (for fvPatchField) + // Set TemplateType and FieldType filter variables setFieldTemplates(dynCode); - // compile filtered C template + // Compile filtered C template dynCode.addCompileFile(codeTemplateC); - // copy filtered H template + // Copy filtered H template dynCode.addCopyFile(codeTemplateH); - - // debugging: make BC verbose + // debugging: make verbose // dynCode.setFilterVariable("verbose", "true"); - // Info<<"compile " << name_ << " sha1: " + // DetailInfo + // <<"compile " << name_ << " sha1: " // << context.sha1() << endl; - // define Make/options + // Define Make/options dynCode.setMakeOptions - ( - "EXE_INC = -g \\\n" - "-I$(LIB_SRC)/finiteVolume/lnInclude \\\n" - + context.options() - + "\n\nLIB_LIBS = \\\n" - + " -lOpenFOAM \\\n" - + " -lfiniteVolume \\\n" - + context.libs() - ); + ( + "EXE_INC = -g \\\n" + "-I$(LIB_SRC)/finiteVolume/lnInclude \\\n" + + context.options() + + "\n\nLIB_LIBS = \\\n" + " -lOpenFOAM \\\n" + " -lfiniteVolume \\\n" + + context.libs() + ); } diff --git a/src/finiteVolume/fields/fvPatchFields/derived/codedMixed/codedMixedFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/derived/codedMixed/codedMixedFvPatchField.C index 7e2bff9185eeb9c21b4e538573d5388026a5c75b..5591be805585015c2f4c46c52ce7c6104b1d02b1 100644 --- a/src/finiteVolume/fields/fvPatchFields/derived/codedMixed/codedMixedFvPatchField.C +++ b/src/finiteVolume/fields/fvPatchFields/derived/codedMixed/codedMixedFvPatchField.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2016 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2016-2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- | Copyright (C) 2011-2016 OpenFOAM Foundation @@ -54,7 +54,7 @@ void Foam::codedMixedFvPatchField<Type>::setFieldTemplates { word fieldType(pTraits<Type>::typeName); - // template type for fvPatchField + // Template type for fvPatchField dynCode.setFilterVariable("TemplateType", fieldType); // Name for fvPatchField - eg, ScalarField, VectorField, ... @@ -70,27 +70,26 @@ const Foam::IOdictionary& Foam::codedMixedFvPatchField<Type>::dict() const { const objectRegistry& obr = this->db(); - if (obr.foundObject<IOdictionary>("codeDict")) + const IOdictionary* dictptr = obr.cfindObject<IOdictionary>("codeDict"); + if (dictptr) { - return obr.lookupObject<IOdictionary>("codeDict"); + return *dictptr; } - else - { - return obr.store + + return obr.store + ( + new IOdictionary ( - new IOdictionary + IOobject ( - IOobject - ( - "codeDict", - this->db().time().system(), - this->db(), - IOobject::MUST_READ_IF_MODIFIED, - IOobject::NO_WRITE - ) + "codeDict", + this->db().time().system(), + this->db(), + IOobject::MUST_READ_IF_MODIFIED, + IOobject::NO_WRITE ) - ); - } + ) + ); } @@ -108,36 +107,34 @@ void Foam::codedMixedFvPatchField<Type>::prepare const dynamicCodeContext& context ) const { - // take no chances - typeName must be identical to name_ + // Take no chances - typeName must be identical to name_ dynCode.setFilterVariable("typeName", name_); - // set TemplateType and FieldType filter variables - // (for fvPatchField) + // Set TemplateType and FieldType filter variables setFieldTemplates(dynCode); - // compile filtered C template + // Compile filtered C template dynCode.addCompileFile(codeTemplateC); - // copy filtered H template + // Copy filtered H template dynCode.addCopyFile(codeTemplateH); - - // debugging: make BC verbose + // Debugging: make verbose // dynCode.setFilterVariable("verbose", "true"); // Info<<"compile " << name_ << " sha1: " // << context.sha1() << endl; - // define Make/options + // Define Make/options dynCode.setMakeOptions - ( - "EXE_INC = -g \\\n" - "-I$(LIB_SRC)/finiteVolume/lnInclude \\\n" - + context.options() - + "\n\nLIB_LIBS = \\\n" - + " -lOpenFOAM \\\n" - + " -lfiniteVolume \\\n" - + context.libs() - ); + ( + "EXE_INC = -g \\\n" + "-I$(LIB_SRC)/finiteVolume/lnInclude \\\n" + + context.options() + + "\n\nLIB_LIBS = \\\n" + " -lOpenFOAM \\\n" + " -lfiniteVolume \\\n" + + context.libs() + ); } diff --git a/src/functionObjects/utilities/codedFunctionObject/codedFunctionObject.C b/src/functionObjects/utilities/codedFunctionObject/codedFunctionObject.C index ce45990ae10a940ad55f3c6fe67a85f5d034907d..c639cff8a8e510d948344dec709c04567cdb2cee 100644 --- a/src/functionObjects/utilities/codedFunctionObject/codedFunctionObject.C +++ b/src/functionObjects/utilities/codedFunctionObject/codedFunctionObject.C @@ -75,7 +75,7 @@ void Foam::functionObjects::codedFunctionObject::prepare // Copy filtered H template dynCode.addCopyFile("functionObjectTemplate.H"); - // Debugging: make BC verbose + // Debugging: make verbose // dynCode.setFilterVariable("verbose", "true"); // Info<<"compile " << name_ << " sha1: " // << context.sha1() << endl; @@ -88,9 +88,9 @@ void Foam::functionObjects::codedFunctionObject::prepare "-I$(LIB_SRC)/meshTools/lnInclude \\\n" + context.options() + "\n\nLIB_LIBS = \\\n" - + " -lOpenFOAM \\\n" - + " -lfiniteVolume \\\n" - + " -lmeshTools \\\n" + " -lOpenFOAM \\\n" + " -lfiniteVolume \\\n" + " -lmeshTools \\\n" + context.libs() ); } @@ -187,79 +187,115 @@ bool Foam::functionObjects::codedFunctionObject::read(const dictionary& dict) { timeFunctionObject::read(dict); + codedBase::setCodeContext(dict); + dict.readCompat<word>("name", {{"redirectType", 1706}}, name_); - const entry* dataPtr = dict.findEntry("codeData", keyType::LITERAL); + label nKeywords = 0; + + const entry* eptr; - if (dataPtr) + codeData_.clear(); + codedBase::append("<codeData>"); + if ((eptr = dict.findEntry("codeData", keyType::LITERAL)) != nullptr) { - dataPtr->readEntry(codeData_); + eptr->readEntry(codeData_); + stringOps::inplaceTrim(codeData_); stringOps::inplaceExpand(codeData_, dict); + + codedBase::append(codeData_); + dynamicCodeContext::addLineDirective ( codeData_, - dataPtr->startLineNumber(), + eptr->startLineNumber(), dict.name() ); - } - const entry* readPtr = dict.findEntry("codeRead", keyType::LITERAL); + ++nKeywords; + } - if (readPtr) + codeRead_.clear(); + codedBase::append("<codeRead>"); + if ((eptr = dict.findEntry("codeRead", keyType::LITERAL)) != nullptr) { - readPtr->readEntry(codeRead_); + eptr->readEntry(codeRead_); + stringOps::inplaceTrim(codeRead_); stringOps::inplaceExpand(codeRead_, dict); + + codedBase::append(codeRead_); + dynamicCodeContext::addLineDirective ( codeRead_, - readPtr->startLineNumber(), + eptr->startLineNumber(), dict.name() ); - } - const entry* execPtr = dict.findEntry("codeExecute", keyType::LITERAL); + ++nKeywords; + } - if (execPtr) + codeExecute_.clear(); + codedBase::append("<codeExecute>"); + if ((eptr = dict.findEntry("codeExecute", keyType::LITERAL)) != nullptr) { - execPtr->readEntry(codeExecute_); + eptr->readEntry(codeExecute_); + stringOps::inplaceTrim(codeExecute_); stringOps::inplaceExpand(codeExecute_, dict); + + codedBase::append(codeExecute_); + dynamicCodeContext::addLineDirective ( codeExecute_, - execPtr->startLineNumber(), + eptr->startLineNumber(), dict.name() ); - } - const entry* writePtr = dict.findEntry("codeWrite", keyType::LITERAL); + ++nKeywords; + } - if (writePtr) + codeWrite_.clear(); + codedBase::append("<codeWrite>"); + if ((eptr = dict.findEntry("codeWrite", keyType::LITERAL)) != nullptr) { - writePtr->readEntry(codeWrite_); + eptr->readEntry(codeWrite_); + stringOps::inplaceTrim(codeWrite_); stringOps::inplaceExpand(codeWrite_, dict); + + codedBase::append(codeWrite_); + dynamicCodeContext::addLineDirective ( codeWrite_, - writePtr->startLineNumber(), + eptr->startLineNumber(), dict.name() ); - } - const entry* endPtr = dict.findEntry("codeEnd", keyType::LITERAL); + ++nKeywords; + } - if (endPtr) + codeEnd_.clear(); + codedBase::append("<codeEnd>"); + if ((eptr = dict.findEntry("codeEnd", keyType::LITERAL)) != nullptr) { - endPtr->readEntry(codeEnd_); + eptr->readEntry(codeEnd_); + stringOps::inplaceTrim(codeEnd_); stringOps::inplaceExpand(codeEnd_, dict); + + codedBase::append(codeEnd_); + dynamicCodeContext::addLineDirective ( codeEnd_, - endPtr->startLineNumber(), + eptr->startLineNumber(), dict.name() ); + + ++nKeywords; } - if (!dataPtr && !readPtr && !execPtr && !writePtr && !endPtr) + if (!nKeywords) { IOWarningInFunction(dict) << "No critical \"code\" prefixed keywords were found." diff --git a/src/functionObjects/utilities/codedFunctionObject/codedFunctionObject.H b/src/functionObjects/utilities/codedFunctionObject/codedFunctionObject.H index 7bac4e67b61a5c40d25eb14b3c4718563100a0ad..c1b597f877121ee7f853d67a37b7ff282c537308 100644 --- a/src/functionObjects/utilities/codedFunctionObject/codedFunctionObject.H +++ b/src/functionObjects/utilities/codedFunctionObject/codedFunctionObject.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2011, 2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- | Copyright (C) 2011-2017 OpenFOAM Foundation @@ -123,13 +123,13 @@ protected: //- Adapt the context for the current object virtual void prepare(dynamicCode&, const dynamicCodeContext&) const; - // Return a description (type + name) for the output + //- Return a description (type + name) for the output virtual string description() const; - // Clear any redirected objects + //- Clear any redirected objects virtual void clearRedirect() const; - // Get the dictionary to initialize the codeContext + //- The dictionary to initialize the codeContext virtual const dictionary& codeDict() const; diff --git a/src/fvOptions/sources/general/codedSource/CodedSource.C b/src/fvOptions/sources/general/codedSource/CodedSource.C index f995b87ede6213074ec7cf2894b7485616335c58..f07a64b5a22ce869d964e88d271735185657ba09 100644 --- a/src/fvOptions/sources/general/codedSource/CodedSource.C +++ b/src/fvOptions/sources/general/codedSource/CodedSource.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2016 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2016-2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- | Copyright (C) 2012-2016 OpenFOAM Foundation @@ -58,27 +58,28 @@ void Foam::fv::CodedSource<Type>::prepare // copy filtered H template dynCode.addCopyFile("codedFvOptionTemplate.H"); - // debugging: make BC verbose - // dynCode.setFilterVariable("verbose", "true"); - // Info<<"compile " << name_ << " sha1: " - // << context.sha1() << endl; + // debugging: make verbose + // dynCode.setFilterVariable("verbose", "true"); + // DetailInfo + // <<"compile " << name_ << " sha1: " + // << context.sha1() << endl; // define Make/options dynCode.setMakeOptions - ( - "EXE_INC = -g \\\n" - "-I$(LIB_SRC)/finiteVolume/lnInclude \\\n" - "-I$(LIB_SRC)/meshTools/lnInclude \\\n" - "-I$(LIB_SRC)/sampling/lnInclude \\\n" - "-I$(LIB_SRC)/fvOptions/lnInclude \\\n" - + context.options() - + "\n\nLIB_LIBS = \\\n" - + " -lmeshTools \\\n" - + " -lfvOptions \\\n" - + " -lsampling \\\n" - + " -lfiniteVolume \\\n" - + context.libs() - ); + ( + "EXE_INC = -g \\\n" + "-I$(LIB_SRC)/finiteVolume/lnInclude \\\n" + "-I$(LIB_SRC)/fvOptions/lnInclude \\\n" + "-I$(LIB_SRC)/meshTools/lnInclude \\\n" + "-I$(LIB_SRC)/sampling/lnInclude \\\n" + + context.options() + + "\n\nLIB_LIBS = \\\n" + " -lfvOptions \\\n" + " -lmeshTools \\\n" + " -lsampling \\\n" + " -lfiniteVolume \\\n" + + context.libs() + ); } diff --git a/src/fvOptions/sources/general/codedSource/CodedSource.H b/src/fvOptions/sources/general/codedSource/CodedSource.H index 6e670bdb965729be9004b91d70d2a090fa45f923..16d0777f45f28bafd187aaa843d48b503f99566a 100644 --- a/src/fvOptions/sources/general/codedSource/CodedSource.H +++ b/src/fvOptions/sources/general/codedSource/CodedSource.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | + \\ / A nd | Copyright (C) 2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- | Copyright (C) 2012-2016 OpenFOAM Foundation @@ -131,12 +131,12 @@ template<class Type> class CodedSource : public cellSetOption, - public codedBase + protected codedBase { protected: - // Protected data + // Protected Data word name_; @@ -156,13 +156,13 @@ protected: //- Adapt the context for the current object virtual void prepare(dynamicCode&, const dynamicCodeContext&) const; - // Return a description (type + name) for the output + //- Return a description (type + name) for the output virtual string description() const; - // Clear any redirected objects + //- Clear any redirected objects virtual void clearRedirect() const; - // Get the dictionary to initialize the codeContext + //- Get the dictionary to initialize the codeContext virtual const dictionary& codeDict() const; @@ -189,42 +189,42 @@ public: //- Dynamically compiled fvOption option& redirectFvOption() const; - // Evaluation - - //- Correct field - virtual void correct - ( - GeometricField<Type, fvPatchField, volMesh>& - ); - - //- Explicit and implicit matrix contributions - virtual void addSup - ( - fvMatrix<Type>& eqn, - const label fieldi - ); - - //- Explicit and implicit matrix contributions - // to compressible equation - virtual void addSup - ( - const volScalarField& rho, - fvMatrix<Type>& eqn, - const label fieldi - ); - - //- Set value - virtual void constrain - ( - fvMatrix<Type>& eqn, - const label fieldi - ); - - - // IO - - //- Read source dictionary - virtual bool read(const dictionary& dict); + + // Evaluation + + //- Correct field + virtual void correct + ( + GeometricField<Type, fvPatchField, volMesh>& + ); + + //- Explicit/implicit matrix contributions + virtual void addSup + ( + fvMatrix<Type>& eqn, + const label fieldi + ); + + //- Explicit/implicit matrix contributions to compressible equation + virtual void addSup + ( + const volScalarField& rho, + fvMatrix<Type>& eqn, + const label fieldi + ); + + //- Set value + virtual void constrain + ( + fvMatrix<Type>& eqn, + const label fieldi + ); + + + // IO + + //- Read source dictionary + virtual bool read(const dictionary& dict); }; diff --git a/src/fvOptions/sources/general/codedSource/CodedSourceIO.C b/src/fvOptions/sources/general/codedSource/CodedSourceIO.C index 6bd56cb6c588f707c5169338e4f6045d29ddbf93..0e0b1ea70e71fa1497369a4e585d958d36d79553 100644 --- a/src/fvOptions/sources/general/codedSource/CodedSourceIO.C +++ b/src/fvOptions/sources/general/codedSource/CodedSourceIO.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | + \\ / A nd | Copyright (C) 2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- | Copyright (C) 2012-2016 OpenFOAM Foundation @@ -33,63 +33,78 @@ License template<class Type> bool Foam::fv::CodedSource<Type>::read(const dictionary& dict) { - if (cellSetOption::read(dict)) + codedBase::setCodeContext(coeffs_); + + if (!cellSetOption::read(dict)) + { + return false; + } + + coeffs_.readEntry("fields", fieldNames_); + applied_.setSize(fieldNames_.size(), false); + + dict.readCompat<word>("name", {{"redirectType", 1706}}, name_); + + // Code chunks + + codedBase::append("<codeCorrect>"); + { + const entry& e = + coeffs_.lookupEntry("codeCorrect", keyType::LITERAL); + + e.readEntry(codeCorrect_); + stringOps::inplaceTrim(codeCorrect_); + stringOps::inplaceExpand(codeCorrect_, coeffs_); + + codedBase::append(codeCorrect_); + + dynamicCodeContext::addLineDirective + ( + codeCorrect_, + e.startLineNumber(), + coeffs_.name() + ); + } + + codedBase::append("<codeAddSup>"); { - coeffs_.readEntry("fields", fieldNames_); - applied_.setSize(fieldNames_.size(), false); - - dict.readCompat<word>("name", {{"redirectType", 1706}}, name_); - - // Code snippets - { - const entry& e = - coeffs_.lookupEntry("codeCorrect", keyType::LITERAL); - - e.readEntry(codeCorrect_); - stringOps::inplaceTrim(codeCorrect_); - stringOps::inplaceExpand(codeCorrect_, coeffs_); - dynamicCodeContext::addLineDirective - ( - codeCorrect_, - e.startLineNumber(), - coeffs_.name() - ); - } - - { - const entry& e = - coeffs_.lookupEntry("codeAddSup", keyType::LITERAL); - - e.readEntry(codeAddSup_); - stringOps::inplaceTrim(codeAddSup_); - stringOps::inplaceExpand(codeAddSup_, coeffs_); - dynamicCodeContext::addLineDirective - ( - codeAddSup_, - e.startLineNumber(), - coeffs_.name() - ); - } - - { - const entry& e = - coeffs_.lookupEntry("codeSetValue", keyType::LITERAL); - - e.readEntry(codeSetValue_); - stringOps::inplaceTrim(codeSetValue_); - stringOps::inplaceExpand(codeSetValue_, coeffs_); - dynamicCodeContext::addLineDirective - ( - codeSetValue_, - e.startLineNumber(), - coeffs_.name() - ); - } - - return true; + const entry& e = + coeffs_.lookupEntry("codeAddSup", keyType::LITERAL); + + e.readEntry(codeAddSup_); + stringOps::inplaceTrim(codeAddSup_); + stringOps::inplaceExpand(codeAddSup_, coeffs_); + + codedBase::append(codeAddSup_); + + dynamicCodeContext::addLineDirective + ( + codeAddSup_, + e.startLineNumber(), + coeffs_.name() + ); + } + + codedBase::append("<codeSetValue>"); + { + const entry& e = + coeffs_.lookupEntry("codeSetValue", keyType::LITERAL); + + e.readEntry(codeSetValue_); + stringOps::inplaceTrim(codeSetValue_); + stringOps::inplaceExpand(codeSetValue_, coeffs_); + + codedBase::append(codeSetValue_); + + dynamicCodeContext::addLineDirective + ( + codeSetValue_, + e.startLineNumber(), + coeffs_.name() + ); } - return false; + return true; }