diff --git a/etc/controlDict b/etc/controlDict-EXAMPLE similarity index 100% rename from etc/controlDict rename to etc/controlDict-EXAMPLE diff --git a/src/foam/global/argList/argList.C b/src/foam/global/argList/argList.C index 874b6ef44..c739c3c19 100644 --- a/src/foam/global/argList/argList.C +++ b/src/foam/global/argList/argList.C @@ -33,8 +33,6 @@ License #include "JobInfo.H" #include "labelList.H" #include "SortableList.H" -//#include "dimensionedConstants.H" - // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -44,29 +42,6 @@ Foam::HashTable Foam::argList::validParOptions; Foam::word Foam::argList::appDictName_(""); bool Foam::argList::bannerEnabled(true); -template<> -const char* -Foam::NamedEnum -< - Foam::debug::globalControlDictSwitchSet, - 5 ->::names[] = -{ - "DebugSwitches", - "InfoSwitches", - "OptimisationSwitches", - "Tolerances", - "DimensionedConstants" -}; - - -const Foam::NamedEnum -< - Foam::debug::globalControlDictSwitchSet, - 5 -> -Foam::argList::globalControlDictSwitchSetNames_; - Foam::argList::initValidTables::initValidTables() { @@ -74,11 +49,24 @@ Foam::argList::initValidTables::initValidTables() validOptions.set("parallel", ""); validParOptions.set("parallel", ""); validOptions.set("noFunctionObjects", ""); - validOptions.set("DebugSwitches", "key1=val1,key2=val2,..."); - validOptions.set("InfoSwitches", "key1=val1,key2=val2,..."); - validOptions.set("OptimisationSwitches", "key1=val1,key2=val2,..."); - validOptions.set("Tolerances", "key1=val1,key2=val2,..."); - validOptions.set("DimensionedConstants", "key1=val1,key2=val2,..."); + + // Add the parameters for modifying the controlDict + // switches from the command-line + + // Instantiate a NamedEnum for the controlDict switches names + const Foam::NamedEnum + < + Foam::debug::globalControlDictSwitchSet, + DIM_GLOBALCONTROLDICTSWITCHSET + > + globalControlDictSwitchSetNames; + + forAll(globalControlDictSwitchSetNames, gI) + { + word switchSetName = globalControlDictSwitchSetNames.names[gI]; + validOptions.set(switchSetName, "key1=val1,key2=val2,..."); + } + Pstream::addValidParOptions(validParOptions); } @@ -354,24 +342,10 @@ Foam::argList::argList << "Date : " << dateString.c_str() << nl << "Time : " << timeString.c_str() << nl << "Host : " << hostName() << nl - << "PID : " << pid() << nl - << "CtrlDict : " << ctrlDictString.c_str() + << "PID : " << pid() << endl; } - // Command-line override for central controlDict's variables - forAll(globalControlDictSwitchSetNames_, cI) - { - word switchSetName = globalControlDictSwitchSetNames_.names[cI]; - - if( optionFound(switchSetName) ) - Foam::debug::updateCentralDictVars - ( - globalControlDictSwitchSetNames_[switchSetName], - option(switchSetName) - ); - } - jobInfo.add("startDate", dateString); jobInfo.add("startTime", timeString); jobInfo.add("userName", userName()); @@ -540,6 +514,62 @@ Foam::argList::argList case_ = globalCase_; } + // Managing the overrides for the global control switches: + // + // Here is the order of precedence for the definition/overriding of the + // control switches, from lowest to highest: + // - source code definitions from the various libraries/solvers + // - file specified by the env. variable FOAM_GLOBAL_CONTROLDICT + // - case's system/controlDict file + // - command-line parameters + // + // First, we allow the users to specify the location of a centralized + // global controlDict dictionary using the environment variable + // FOAM_GLOBAL_CONTROLDICT. + fileName optionalGlobControlDictFileName = + getEnv("FOAM_GLOBAL_CONTROLDICT"); + + if (optionalGlobControlDictFileName.size() ) + { + debug::updateCentralDictVars + ( + optionalGlobControlDictFileName, + Pstream::master() && bannerEnabled + ); + } + + // Now that the rootPath_/globalCase_ directory is known (following the call + // to getRootCase()), we grab any global control switches overrides from the + // current case's controlDict. + + debug::updateCentralDictVars + ( + rootPath_/globalCase_/"system/controlDict", + Pstream::master() && bannerEnabled + ); + + // Finally, a command-line override for central controlDict's variables. + // This is the ultimate override for the global control switches. + + // Instantiate a NamedEnum for the controlDict switches names + const Foam::NamedEnum + < + Foam::debug::globalControlDictSwitchSet, + DIM_GLOBALCONTROLDICTSWITCHSET + > + globalControlDictSwitchSetNames; + + forAll(globalControlDictSwitchSetNames, gI) + { + word switchSetName = globalControlDictSwitchSetNames.names[gI]; + + if( optionFound(switchSetName) ) + Foam::debug::updateCentralDictVars + ( + globalControlDictSwitchSetNames[switchSetName], + option(switchSetName) + ); + } wordList slaveProcs; diff --git a/src/foam/global/argList/argList.H b/src/foam/global/argList/argList.H index edd32ebd8..6ba972002 100644 --- a/src/foam/global/argList/argList.H +++ b/src/foam/global/argList/argList.H @@ -126,9 +126,6 @@ public: // Static data members - //- Central dictionary switchSet names - static const NamedEnum globalControlDictSwitchSetNames_; - //- A list of valid (mandatory) arguments static SLList validArgs; diff --git a/src/foam/global/debug/debug.C b/src/foam/global/debug/debug.C index 200aa1113..005c8878b 100644 --- a/src/foam/global/debug/debug.C +++ b/src/foam/global/debug/debug.C @@ -37,6 +37,8 @@ Description #include "optimisationSwitch.H" #include "tolerancesSwitch.H" #include "constantsSwitch.H" +#include "fileName.H" +#include "NamedEnum.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -45,6 +47,22 @@ namespace Foam namespace debug { +template<> +const char* +Foam::NamedEnum +< + Foam::debug::globalControlDictSwitchSet, + 5 +>::names[] = +{ + "DebugSwitches", + "InfoSwitches", + "OptimisationSwitches", + "Tolerances", + "DimensionedConstants" +}; + + //! @cond ignoreDocumentation - local scope dictionary* controlDictPtr_(NULL); dictionary* debugSwitchesPtr_(NULL); @@ -95,19 +113,46 @@ Foam::dictionary& Foam::debug::controlDict() { if (!controlDictPtr_) { - // Allow users to override the location of the global controlDict - // dictionary using an environment variable. Using this environment - // variable, one can assign a different global controlDict for each - // case, without having to modify the "default" ones. - fileName globControlDictFileName = getEnv("FOAM_GLOBAL_CONTROLDICT"); + // We are totally getting rid of the central controlDict file located + // under $WM_PROJECT_DIR/etc/controlDict. + // But we still need to create a central dictionary for the global control + // switches. + // At first, all the different subdicts will be empty, like this: + // DebugSwitches{} + // InfoSwitches{} + // OptimisationSwitches{} + // Tolerances{} + // DimensionedConstants{} + // + // We will also merge with other predefined dictionaries as we go along. + // Then, as the libraries will instantiate the various control switches, + // the corresponding subdicts will get populated. + // MB 05/2015 - // Fallback to default locations if filename is empty or not valid - if( ! isFile(globControlDictFileName) ) - globControlDictFileName = findEtcFile("controlDict", true); + const string dictEmptySectionStr("{}\n"); + string emptyGlobalDictStr; - controlDictPtr_ = new dictionary + // This is a bit less readable than explicitely reusing the hard-coded + // string values, but we then get the added flexibility to change the + // name of the subDicts without too much impact to the rest of source + // code. + const Foam::NamedEnum + < + Foam::debug::globalControlDictSwitchSet, + DIM_GLOBALCONTROLDICTSWITCHSET + > + globalControlDictSwitchSetNames; + + forAll(globalControlDictSwitchSetNames, gI) + { + emptyGlobalDictStr += + globalControlDictSwitchSetNames.names[gI] + + dictEmptySectionStr; + } + + controlDictPtr_ = new dictionary ( - IFstream(globControlDictFileName)() + IStringStream(emptyGlobalDictStr)() ); } @@ -117,12 +162,21 @@ Foam::dictionary& Foam::debug::controlDict() Foam::dictionary& Foam::debug::switchSet ( - const char* subDictName, + const globalControlDictSwitchSet globalControlDictSwitchSetName, dictionary*& subDictPtr ) { if (!subDictPtr) { + const Foam::NamedEnum + < + Foam::debug::globalControlDictSwitchSet, + DIM_GLOBALCONTROLDICTSWITCHSET + > + globalControlDictSwitchSetNames; + + word subDictName = globalControlDictSwitchSetNames[globalControlDictSwitchSetName]; + entry* ePtr = controlDict().lookupEntryPtr ( subDictName, false, false @@ -130,7 +184,7 @@ Foam::dictionary& Foam::debug::switchSet if (!ePtr || !ePtr->isDict()) { - cerr<< "debug::switchSet(const char*, dictionary*&):\n" + cerr<< "debug::switchSet(const globalControlDictSwitchSet, dictionary*&):\n" << " Cannot find " << subDictName << " in dictionary " << controlDict().name().c_str() << std::endl << std::endl; @@ -147,30 +201,30 @@ Foam::dictionary& Foam::debug::switchSet Foam::dictionary& Foam::debug::debugSwitches() { - return switchSet("DebugSwitches", debugSwitchesPtr_); + return switchSet(debug::DEBUGSWITCHES, debugSwitchesPtr_); } Foam::dictionary& Foam::debug::infoSwitches() { - return switchSet("InfoSwitches", infoSwitchesPtr_); + return switchSet(debug::INFOSWITCHES, infoSwitchesPtr_); } Foam::dictionary& Foam::debug::optimisationSwitches() { - return switchSet("OptimisationSwitches", optimisationSwitchesPtr_); + return switchSet(debug::OPTIMISATIONSWITCHES, optimisationSwitchesPtr_); } Foam::dictionary& Foam::debug::tolerances() { - return switchSet("Tolerances", tolerancesPtr_); + return switchSet(debug::TOLERANCES, tolerancesPtr_); } Foam::dictionary& Foam::debug::constants() { - return switchSet("DimensionedConstants", constantsPtr_); + return switchSet(debug::DIMENSIONEDCONSTANTS, constantsPtr_); } @@ -258,8 +312,9 @@ double Foam::debug::constantsFromDict void Foam::debug::updateCentralDictVars ( - Foam::debug::globalControlDictSwitchSet globalControlDictSwitchSetName, - Foam::string keyValues + const Foam::debug::globalControlDictSwitchSet globalControlDictSwitchSetName, + const Foam::string& keyValues, + const bool verbose ) { Foam::word token; @@ -298,12 +353,14 @@ void Foam::debug::updateCentralDictVars ) ) { - Info << endl - << "Warning: Modification of DebugSwitches: " - << key << endl - << " Old value: " << oldDebugValue << endl - << " New value: " << newDebugValue << endl - << endl; + if (verbose) + { + Info << "CtrlDict : Modification of DebugSwitches: " + << key + << ": old value: " << oldDebugValue + << ", new value: " << newDebugValue + << endl; + } Foam::debug::debugSwitches().set ( @@ -382,12 +439,14 @@ void Foam::debug::updateCentralDictVars ) ) { - Info << endl - << "Warning: Modification of InfoSwitches: " - << key << endl - << " Old value: " << oldInfoValue << endl - << " New value: " << newInfoValue << endl - << endl; + if (verbose) + { + Info << "CtrlDict : Modification of InfoSwitches: " + << key + << ": old value: " << oldInfoValue + << ", new value: " << newInfoValue + << endl; + } Foam::debug::infoSwitches().set(key, newInfoValue); @@ -498,15 +557,17 @@ void Foam::debug::updateCentralDictVars if(keyIsPresent) { - Info << endl - << "Warning: Modification of " - << "OptimisationSwitches: " - << key << endl - << " Old value: " - << oldOptimisationValueStr << endl - << " New value: " - << newOptimisationValueStr << endl - << endl; + if (verbose) + { + Info << "CtrlDict : Modification of " + << "OptimisationSwitches: " + << key + << ": old value: " + << oldOptimisationValueStr + << ", new value: " + << newOptimisationValueStr + << endl; + } Foam::debug::optimisationSwitches().set ( @@ -517,7 +578,6 @@ void Foam::debug::updateCentralDictVars std::list *> curList = optimisationSwitchValues[key]; - std::cout << "curList.size(): " << curList.size() << std::endl; // Modify all entries for this key forAllIter ( @@ -586,14 +646,14 @@ void Foam::debug::updateCentralDictVars ) ) { - Info << endl - << "Warning: Modification of Tolerances: " - << key << endl - << " Old value: " - << oldTolerancesValue << endl - << " New value: " - << newTolerancesValue << endl - << endl; + if (verbose) + { + Info << "CtrlDict : Modification of Tolerances: " + << key + << ": old value: " << oldTolerancesValue + << ", new value: " << newTolerancesValue + << endl; + } Foam::debug::tolerances().set ( @@ -672,14 +732,16 @@ void Foam::debug::updateCentralDictVars ) ) { - Info << endl - << "Warning: Modification of DimensionedConstants: " - << key << endl - << " Old value: " - << oldDimensionedConstantsValue << endl - << " New value: " - << newDimensionedConstantsValue << endl - << endl; + if (verbose) + { + Info << "CtrlDict : Modification of DimensionedConstants: " + << key + << ": old value: " + << oldDimensionedConstantsValue + << ", new value: " + << newDimensionedConstantsValue + << endl; + } Foam::dimensionedConstants().set ( @@ -748,4 +810,65 @@ void Foam::debug::updateCentralDictVars } } +void Foam::debug::updateCentralDictVars +( + const Foam::fileName& fName, + const bool verbose +) +{ + // Add a trace to the banner + if (verbose) + { + Info << "CtrlDict : " << fName << endl; + } + + if(fName.size() && isFile(fName)) + { + const dictionary* optionalGlobControlDictPtr_ = new dictionary + ( + IFstream(fName)() + ); + + const dictionary& optionalGlobControlDict = *optionalGlobControlDictPtr_; + + const Foam::NamedEnum + < + Foam::debug::globalControlDictSwitchSet, + DIM_GLOBALCONTROLDICTSWITCHSET + > + globalControlDictSwitchSetNames; + + // We merge the content of each subdicts + forAll(globalControlDictSwitchSetNames, gI) + { + string subDictName(globalControlDictSwitchSetNames.names[gI]); + + if (optionalGlobControlDict.isDict(subDictName)) + { + const dictionary& subD = optionalGlobControlDict.subDict(subDictName); + const wordList toc = subD.toc(); + + OStringStream keyValuePairs; + forAll(toc, tocI) + { + token value; + subD.lookup(toc[tocI]).read(value); + keyValuePairs << toc[tocI] << "=" << value << ", "; + } + + // Update global dictionary + updateCentralDictVars + ( + globalControlDictSwitchSetNames[subDictName], + keyValuePairs.str(), + false // keep quiet when using files... + ); + } + } + + // Cleaning up + delete optionalGlobControlDictPtr_; + } +} + // ************************************************************************* // diff --git a/src/foam/global/debug/debug.H b/src/foam/global/debug/debug.H index f06d64edd..5694c5bb1 100644 --- a/src/foam/global/debug/debug.H +++ b/src/foam/global/debug/debug.H @@ -40,8 +40,15 @@ SourceFiles namespace Foam { +// Number of global controlDict switches sets +// Currently, we have: +// DebugSwitches, InfoSwitches, OptimisationSwitches, Tolerances, +// and DimensionedConstants +#define DIM_GLOBALCONTROLDICTSWITCHSET 5 + // Forward declaration of classes class dictionary; +class fileName; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -58,8 +65,6 @@ namespace debug }; //- The central control dictionary. - // Located in $WM_PROJECT_DIR/etc - // @sa Foam::findEtcFile() dictionary& controlDict(); //- The DebugSwitches sub-dictionary in the central controlDict. @@ -94,14 +99,26 @@ namespace debug double constantsFromDict(const char* name, const double defaultValue = 0); //- Internal function to lookup a sub-dictionary from controlDict. - dictionary& switchSet(const char* subDictName, dictionary*& subDictPtr); + dictionary& switchSet + ( + const globalControlDictSwitchSet globalControlDictSwitchSetName, + dictionary*& subDictPtr + ); //- Update central controlDict variables // supported keyValues format: key1=value1,key2=value2 void updateCentralDictVars ( - globalControlDictSwitchSet centralDictSwitchSetName, - Foam::string keyValues + const globalControlDictSwitchSet centralDictSwitchSetName, + const Foam::string& keyValues, + const bool verbose=true + ); + + //- Update central controlDict variables from a file + void updateCentralDictVars + ( + const Foam::fileName& file, + const bool verbose=true ); } // End namespace debug diff --git a/src/foam/global/dimensionedConstants/dimensionedConstants.C b/src/foam/global/dimensionedConstants/dimensionedConstants.C index 5385c739b..8728d41e4 100644 --- a/src/foam/global/dimensionedConstants/dimensionedConstants.C +++ b/src/foam/global/dimensionedConstants/dimensionedConstants.C @@ -38,7 +38,7 @@ dictionary& dimensionedConstants() { return debug::switchSet ( - "DimensionedConstants", + debug::DIMENSIONEDCONSTANTS, dimensionedConstantsPtr_ ); }