-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Various fixes and update of ResultWriter #255
Conversation
…s as true/false instead of 1/0
…-fixes, cleanup, etc.
src/molecules/Site.h
Outdated
std::string strShifted = "false"; | ||
xmlconfig.getNodeValue("shifted", strShifted); | ||
// Convert to lower case to avoid input errors | ||
std::transform(strShifted.begin(), strShifted.end(), strShifted.begin(), [](auto c) { return std::tolower(c); }); | ||
if (strShifted == "true" || strShifted == "false") { | ||
std::istringstream(strShifted) >> std::boolalpha >> _shiftRequested; | ||
} else { | ||
global_log->error() << "Parameter <shifted> of components has to be either set to 'true' or 'false'" << std::endl; | ||
mardyn_exit(1); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should not be necessary at as the xml parser code already handles "YES", "TRUE", "ON" ignoring case. See
ls1-mardyn/src/utils/xmlfile.cpp
Line 589 in b6f274e
template<> bool XMLfile::Node::getValue<bool>(bool& value) const |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The point of this code is to check if the input value of <shifted>
is really a boolean as it was a float before introducing the _shiftRequested
variable a few month ago. If we would just do xmlconfig.getNodeValue("shifted", _shiftRequested);
then a float will be probably converted to false. Even though a user would expect a number != 0 to shift the potential. This code makes sure that an old version of the components where the shift value was set to be 0.097901347
(shift for cutoff radius =2.5) can not be used without an error. If we just parsed this value, the potential would not be shifted and the simulation run would yield wrong results.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is now solved by checking all boolean input values, and additionally also other user input via the xmlfile.
src/io/ResultWriter.cpp
Outdated
if ((simstep % _writeFrequency == 0) and (simstep > 0UL)) { | ||
// Only main rank writes data to file | ||
if (domainDecomp->getRank() == 0) { | ||
const string resultfile(_outputPrefix+".res"); | ||
std::ofstream resultStream; | ||
resultStream.open(resultfile.c_str(), std::ios::app); | ||
auto printOutput = [&](auto value) { | ||
resultStream << std::setw(_writeWidth) << std::scientific << std::setprecision(_writePrecision) << value; | ||
}; | ||
resultStream << std::setw(10) << simstep; | ||
printOutput(_simulation.getSimulationTime()); | ||
printOutput(_uPot_acc/_numSamples); | ||
printOutput(_uKin_acc/_numSamples); | ||
printOutput(_uKinTrans_acc/_numSamples); | ||
printOutput(_uKinRot_acc/_numSamples); | ||
printOutput(_p_acc/_numSamples); | ||
printOutput(domain->cv()); | ||
printOutput(globalNumMolecules); | ||
resultStream << std::endl; | ||
resultStream.close(); | ||
} | ||
|
||
// Reset values | ||
_numSamples = 0UL; | ||
_uPot_acc = 0.0F; | ||
_uKin_acc = 0.0F; | ||
_uKinTrans_acc = 0.0F; | ||
_uKinRot_acc = 0.0F; | ||
_p_acc = 0.0F; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a step back from what we had with the Accumulator class and removes existing functionality.
Note: sometimes you want higher write frequency than the sample count .
Also this moves time consuming MPI collectives into the plugin - if all plugins compute energies by themselves this will lead to unnecessary overheads - where the domain/ensemble classes will compute once and cache the values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The existing implementation was not what was documented. For me, it seems like the accumulator returns not only the value averaged over the last _writeFrequency
steps but for the whole simulation. Otherwise it would had to reset the data after getting the average which it does not.
What do you mean by "higher write frequency than the sample count"? The sample count just counts the number of sampling steps. It is often the writing frequency but not at the very beginning (simstep=0 is sampled but it would lead to wrong averages if at e.g. simstep=10=writefrequency) the accumulated value is divided by 10 and not 11.)
I know that it is not perfect to have the loop and MPI call in here. But at the moment, the domain/ensemble does not provide a working method to get the global kinetic energy. There is no MPI collective in the plugin anymore. The domain can now return the global kinetic energy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cniethammer So what do you suggest regarding my comments?
@cniethammer Furthermore, I think, that the whole I was also running a test with a different number of frames. When endPosition=_seekTable.back(), the file was not corrupted according to MMPLD tool mmpldinfo.py. I also commented out the |
Until now, it was updated too late
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although I agree with @cniethammer's comment in principle, I think that the solution proposed in this PR is "good enough" for now so that we can move on. But I'd like to hear @cniethammer's opinion.
Do you mean the comment on the xml parser code for boolean? I revoked the special check for |
No I was referring to this comment:
Not sure what functionality is lost though... |
Ok, I see. In a former version of this PR, I calculated the kinetic energies in the plugin itself. But this is now done in the Domain class since it was calculated there anyway for the thermostat (but not stored yet). I would also be much interested in the issue regarding the MMPLDWriter. This bug was very strange for me :D |
Just saw this now - I will try to catch up with what was done since I reviewed this long time ago. Sry. |
I now had some time to look at this. Honestly, this seems an agglomerate of changes that touch various parts besides the ResultWriter - including unrelated fixes in e.g. the Molecule class or MmpldWriter. IMHO, this should be split into several clean PRs that address single aspects. |
@cniethammer |
OK, I will clean this PR up by splitting it into separate PRs. |
Alright, thank you :) |
@cniethammer |
Hello @cniethammer , |
Description
This PR is split into several smaller ones.
Open issues:
none
Already fixed in smaller PR:
--> Fix mixing rules in input files for the DropletCoalescence example #278
--> Several xml parser improvements #279
--> Fixes and improvements for the MMPLD writer #280
<shifted>
parameter correctly--> Fix xmlreader allowed bool values #286 and Fix shifted parameter in SpinodalDecomp #298
--> Add log output for site parameters when reading xml input configuration #309
--> Set initial simulation time step earlier #313
--> Fix and improvement of Logger #308
pandas.read_csv()
. Sampling of kinetic energy added.To my knowledge, there is no working way to directly get the global kinetic energy e.g. from the domain object.(<-- added in this PR)--> Add sampling of kinetic energy to ResultWriter #336
--> Fix quaternion default initialisation #300