From 31b39e41e807dff6645aaf8772fcf29bb469d120 Mon Sep 17 00:00:00 2001 From: Michele Invernizzi Date: Wed, 29 Nov 2023 17:53:04 +0100 Subject: [PATCH] OPES: Making parsing not reliant on NaN (#992) --- src/opes/ECVlinear.cpp | 22 +++++++++++++++++++--- src/opes/ECVmultiThermal.cpp | 24 ++++++++++++------------ src/opes/ECVmultiThermalBaric.cpp | 24 ++++++++++++++++++++---- 3 files changed, 51 insertions(+), 19 deletions(-) diff --git a/src/opes/ECVlinear.cpp b/src/opes/ECVlinear.cpp index 56e895e3c3..be573ed5e2 100644 --- a/src/opes/ECVlinear.cpp +++ b/src/opes/ECVlinear.cpp @@ -122,6 +122,22 @@ ECVlinear::ECVlinear(const ActionOptions&ao) if(dimensionless) beta0_=1; +//workaround needed for intel compiler + bool nan_support=true; + const double my_nan_value=-42; + if(!std::isnan(std::numeric_limits::quiet_NaN())) + { + nan_support=false; + log.printf(" +++ WARNING +++ do not set LAMBDA_MIN/MAX=%g, see https://github.com/plumed/plumed2/pull/990\n", my_nan_value); + } + auto isNone=[nan_support,my_nan_value](const double value) + { + if(nan_support) + return std::isnan(value); + else + return value==my_nan_value; + }; + //parse lambda info parse("LAMBDA",lambda0_); double lambda_min=std::numeric_limits::quiet_NaN(); @@ -140,7 +156,7 @@ ECVlinear::ECVlinear(const ActionOptions&ao) if(lambdas.size()>0) { plumed_massert(lambda_steps==0,"cannot set both LAMBDA_STEPS and LAMBDA_SET_ALL"); - plumed_massert(std::isnan(lambda_min) && std::isnan(lambda_max),"cannot set both LAMBDA_SET_ALL and LAMBDA_MIN/MAX"); + plumed_massert(isNone(lambda_min) && isNone(lambda_max),"cannot set both LAMBDA_SET_ALL and LAMBDA_MIN/MAX"); plumed_massert(lambdas.size()>=2,"set at least 2 lambdas with LAMBDA_SET_ALL"); for(unsigned k=0; k&) override; }; -PLUMED_REGISTER_ACTION(ECVmultiCanonical,"ECV_MULTITHERMAL") +PLUMED_REGISTER_ACTION(ECVmultiThermal,"ECV_MULTITHERMAL") -void ECVmultiCanonical::registerKeywords(Keywords& keys) +void ECVmultiThermal::registerKeywords(Keywords& keys) { ExpansionCVs::registerKeywords(keys); keys.remove("ARG"); @@ -114,7 +114,7 @@ void ECVmultiCanonical::registerKeywords(Keywords& keys) keys.addFlag("NO_GEOM_SPACING",false,"do not use geometrical spacing in temperature, but instead linear spacing in inverse temperature"); } -ECVmultiCanonical::ECVmultiCanonical(const ActionOptions&ao) +ECVmultiThermal::ECVmultiThermal(const ActionOptions&ao) : Action(ao) , ExpansionCVs(ao) , todoAutomatic_(false) @@ -188,28 +188,28 @@ ECVmultiCanonical::ECVmultiCanonical(const ActionOptions&ao) log.printf(" -- NO_GEOM_SPACING: inverse temperatures will be linearly spaced\n"); } -void ECVmultiCanonical::calculateECVs(const double * ene) +void ECVmultiThermal::calculateECVs(const double * ene) { for(unsigned k=0; k ECVmultiCanonical::getLambdas() const +std::vector ECVmultiThermal::getLambdas() const { plumed_massert(!todoAutomatic_,"cannot access lambdas before initializing them"); const double temp0=kbt_/plumed.getAtoms().getKBoltzmann(); @@ -223,7 +223,7 @@ std::vector ECVmultiCanonical::getLambdas() const return lambdas; } -void ECVmultiCanonical::initECVs() +void ECVmultiThermal::initECVs() { plumed_massert(!isReady_,"initialization should not be called twice"); plumed_massert(!todoAutomatic_,"this should not happen"); @@ -233,7 +233,7 @@ void ECVmultiCanonical::initECVs() log.printf(" *%4lu temperatures for %s\n",derECVs_.size(),getName().c_str()); } -void ECVmultiCanonical::initECVs_observ(const std::vector& all_obs_cvs,const unsigned ncv,const unsigned index_j) +void ECVmultiThermal::initECVs_observ(const std::vector& all_obs_cvs,const unsigned ncv,const unsigned index_j) { if(todoAutomatic_) //estimate the steps in beta from observations { @@ -250,7 +250,7 @@ void ECVmultiCanonical::initECVs_observ(const std::vector& all_obs_cvs,c calculateECVs(&all_obs_cvs[index_j]); } -void ECVmultiCanonical::initECVs_restart(const std::vector& lambdas) +void ECVmultiThermal::initECVs_restart(const std::vector& lambdas) { std::size_t pos=lambdas[0].find("_"); plumed_massert(pos==std::string::npos,"this should not happen, only one CV is used in "+getName()); diff --git a/src/opes/ECVmultiThermalBaric.cpp b/src/opes/ECVmultiThermalBaric.cpp index 17b3d07e31..5ede40c3b0 100644 --- a/src/opes/ECVmultiThermalBaric.cpp +++ b/src/opes/ECVmultiThermalBaric.cpp @@ -146,6 +146,22 @@ ECVmultiThermalBaric::ECVmultiThermalBaric(const ActionOptions&ao) const double kB=plumed.getAtoms().getKBoltzmann(); const double temp0=kbt_/kB; +//workaround needed for intel compiler + bool nan_support=true; + const double my_nan_value=-42; + if(!std::isnan(std::numeric_limits::quiet_NaN())) + { + nan_support=false; + log.printf(" +++ WARNING +++ do not set PRESSURE_MIN/MAX=%g, see https://github.com/plumed/plumed2/pull/990\n", my_nan_value); + } + auto isNone=[nan_support,my_nan_value](const double value) + { + if(nan_support) + return std::isnan(value); + else + return value==my_nan_value; + }; + //parse temp range double temp_min=-1; double temp_max=-1; @@ -181,7 +197,7 @@ ECVmultiThermalBaric::ECVmultiThermalBaric(const ActionOptions&ao) plumed_massert(temp_steps==0,"cannot set both SET_ALL_TEMP_PRESSURE and TEMP_STEPS"); plumed_massert(pres_steps==0,"cannot set both SET_ALL_TEMP_PRESSURE and PRESSURE_STEPS"); plumed_massert(temp_min==-1 && temp_max==-1,"cannot set both SET_ALL_TEMP_PRESSURE and TEMP_MIN/MAX"); - plumed_massert(std::isnan(pres_min) && std::isnan(pres_max),"cannot set both SET_ALL_TEMP_PRESSURE and PRESSURE_MIN/MAX"); + plumed_massert(isNone(pres_min) && isNone(pres_max),"cannot set both SET_ALL_TEMP_PRESSURE and PRESSURE_MIN/MAX"); plumed_massert(cut_corner.size()==0,"cannot set both SET_ALL_TEMP_PRESSURE and CUT_CORNER"); //setup the target temperature-pressure grid derECVs_beta_.resize(custom_lambdas_.size()); @@ -257,7 +273,7 @@ ECVmultiThermalBaric::ECVmultiThermalBaric(const ActionOptions&ao) if(pres_.size()>0) { plumed_massert(pres_steps==0,"cannot set both PRESSURE_STEPS and PRESSURE_SET_ALL"); - plumed_massert(std::isnan(pres_min) && std::isnan(pres_max),"cannot set both PRESSURE_SET_ALL and PRESSURE_MIN/MAX"); + plumed_massert(isNone(pres_min) && isNone(pres_max),"cannot set both PRESSURE_SET_ALL and PRESSURE_MIN/MAX"); plumed_massert(pres_.size()>=2,"set at least 2 pressures"); for(unsigned kk=0; kk