#include "modelvariable.h" #include "errorhandler.h" #include "readword.h" #include "gadget.h" #include "global.h" ModelVariable::ModelVariable() { value = 0.0; mvtype = MVFORMULA; } void ModelVariable::setValue(double newValue) { if (mvtype != MVFORMULA) handle.logMessage(LOGFAIL, "Error in modelvariable - cannot set value for entries read from file"); init.setValue(newValue); value = newValue; } void ModelVariable::read(CommentStream& infile, const TimeClass* const TimeInfo, Keeper* const keeper) { keeper->addString("modelvariable"); ifstream subfile; CommentStream subcomment(subfile); char text[MaxStrLength]; strncpy(text, "", MaxStrLength); streampos readPos; readPos = infile.tellg(); infile >> text; subfile.open(text, ios::in); if (subfile.fail()) { // this is a single value that is read as a formula in case infile.seekg(readPos); if (!(infile >> init)) handle.logFileMessage(LOGFAIL, "Error in size of vector - didnt expect to find", text); init.Inform(keeper); } else { // this is either a timevariable or a stockvariable that is read from file handle.Open(text); subcomment >> text >> ws; // description of model variable keeper->addString(text); char c = subcomment.peek(); int numcoeff = 0; if ((c == 'n') || (c == 'N')) { readWordAndVariable(subcomment, "nrofcoeff", numcoeff); subcomment >> ws; c = subcomment.peek(); if (numcoeff > 0) handle.logFileMessage(LOGWARN, "The modelmatrix timevariable formulation is no longer supported"); } // JMB optional multiplier if ((c == 'm') || (c == 'M')) readWordAndVariable(subcomment, "multiplier", init); else init.setValue(1.0); init.Inform(keeper); subcomment >> ws >> text; if ((strcasecmp(text, "timedata") == 0) || (strcasecmp(text, "data") == 0)) { // JMB this is a timevariable mvtype = MVTIME; TV.read(subcomment, TimeInfo, keeper); } else if (strcasecmp(text, "stockdata") == 0) { // JMB this is a stockvariable mvtype = MVSTOCK; SV.read(subcomment); } else handle.logFileUnexpected(LOGFAIL, "timedata or stockdata", text); keeper->clearLast(); handle.Close(); subfile.close(); subfile.clear(); } keeper->clearLast(); } int ModelVariable::didChange(const TimeClass* const TimeInfo) { if (TimeInfo->getTime() == 1) return 1; //return true for the first timestep switch (mvtype) { case MVFORMULA: return 0; //return false if the values were not read from file break; case MVTIME: return TV.didChange(TimeInfo); //return based on time step break; case MVSTOCK: return 1; //return true if this is based on the stock population break; default: handle.logMessage(LOGWARN, "Warning in modelvariable - unrecognised type", mvtype); return 0; break; } } void ModelVariable::Update(const TimeClass* const TimeInfo) { switch (mvtype) { case MVFORMULA: value = init; break; case MVTIME: TV.Update(TimeInfo); value = TV.getValue(); value *= init; // JMB multiply by scaling factor break; case MVSTOCK: SV.Update(); value = SV.getValue(); value *= init; // JMB multiply by scaling factor handle.logMessage(LOGDETAIL, "Value calculated in stock variable", value); break; default: handle.logMessage(LOGWARN, "Warning in modelvariable - unrecognised type", mvtype); break; } } void ModelVariable::Delete(Keeper* const keeper) const { init.Delete(keeper); if (mvtype == MVTIME) TV.Delete(keeper); if (mvtype == MVSTOCK) SV.Delete(); } void ModelVariable::Interchange(ModelVariable& newMV, Keeper* const keeper) const { newMV.value = value; newMV.mvtype = mvtype; init.Interchange(newMV.init, keeper); if (mvtype == MVTIME) TV.Interchange(newMV.TV, keeper); if (mvtype == MVSTOCK) SV.Interchange(newMV.SV); }