Commit fb83a495 authored by jouke's avatar jouke
Browse files

Manual edits after master

parent 63044f3f
Loading
Loading
Loading
Loading
+15 −10
Original line number Diff line number Diff line
@@ -29,24 +29,29 @@ note that this requires historical information on leave area, so the garbage col
			name="senescedLeafDryWeight" 
			unit="g" 
			function="leafSenescence" />

<!--  these are optional and can be renamed, the code does not use them -->	
		<SimulaDerivative name="leafArea_green" function="useFormula">
			<SimulaConstant name="formula" type="string"> leafArea - senescedLeafArea </SimulaConstant>
		</SimulaDerivative>
		<SimulaDerivative name="leafDryWeight_green" function="useFormula">
			<SimulaConstant name="formula" type="string"> leafDryWeight - senescedLeafDryWeight </SimulaConstant>
		<SimulaDerivative
			name="greenLeafArea"
			unit="cm2"
			function="useFormula">
			<SimulaConstant
				name="formula"
				type="string"> leafArea - senescedLeafArea
			</SimulaConstant>
		</SimulaDerivative>
	</SimulaDirective>
	<SimulaDirective path="/plants">			
			<SimulaVariable name="senescedLeafArea" function="sumOverAllPlantShoots" unit="cm2" />
	</SimulaDirective>


	<SimulaDirective path="/plantTemplate">
		<SimulaDerivative name="shootDryWeight_green" function="useFormula">
		<SimulaDerivative name="greenShootDryWeight" function="useFormula">
			<SimulaConstant name="formula" type="string"> shootDryWeight - senescedLeafDryWeight </SimulaConstant>
			<SimulaBase name="variablePaths">
				<SimulaConstant name="senescedLeafDryWeight" type="string"> plantPosition/shoot/senescedLeafDryWeight </SimulaConstant>
			</SimulaBase>
		</SimulaDerivative>
		<SimulaDerivative name="plantDryWeight_green" function="useFormula">
		<SimulaDerivative name="greenPlantDryWeight" function="useFormula">
			<SimulaConstant name="formula" type="string"> plantDryWeight - senescedLeafDryWeight </SimulaConstant>
			<SimulaBase name="variablePaths">
				<SimulaConstant name="senescedLeafDryWeight" type="string"> plantPosition/shoot/senescedLeafDryWeight </SimulaConstant>
+70 −39
Original line number Diff line number Diff line
@@ -412,42 +412,21 @@ SimulaBase* SimulaBase::existingSibling(const std::string& name,const Unit& u){


SimulaBase* SimulaBase::getPath(const std::string &name, const Time &t){
	SimulaBase *probe(getPath(name));
	if(!probe->evaluateTime(t)) msg::error("SimulaBase::getPath: path "+getPath()+'/'+name+" found but life time is not correct.");
	SimulaBase *probe(existingPath(name,t));
	if(!probe) msg::error("SimulaBase::getPath: path "+getPath()+name+" not found");
	return probe;
}
SimulaBase* SimulaBase::getPath(const std::string &name, const Unit &u){
	SimulaBase *probe(getPath(name));
	probe->checkUnit(u);
	SimulaBase *probe(existingPath(name,u));
	if(!probe) {
		std::string p(name[0]=='/'?"":getPath());
		msg::error("SimulaBase::getPath: path "+p+name+" not found");
	}
	return probe;
}
SimulaBase* SimulaBase::getPath(const std::string &name){
	//Separate path into list names
	std::list<std::string> list;
	std::string::size_type pos(0);
	//loop through the list
	SimulaBase* probe;
	Database* l;
	if(name[pos]=='/'){
		++pos;
		while (pos<name.size()) list.push_back(nextWord(name,pos,'/'));
		probe=ORIGIN;
	}else{
		while (pos<name.size()) list.push_back(nextWord(name,pos,'/'));
		probe=this;
	}
	for(std::list<std::string>::iterator it(list.begin());it!=list.end() && probe!=nullptr ;++it){
		if(*it==".."){
			probe=probe->getParent();
		}else{
			l=probe->hasChildren();
			if(l){
				probe=l->get(*it);
			}else{
				msg::error("SimulaBase::getPath: path "+getPath()+'/'+name+" not found. "+probe->getPath()+" has no children.");
			}
		}
	}
	SimulaBase *probe(existingPath(name));
	if(!probe) msg::error("SimulaBase::getPath: path "+getPath()+name+" not found");
	return probe;
}

@@ -475,7 +454,9 @@ SimulaBase* SimulaBase::getOneOfThesePathsIfExisting(const std::string &name0,
	return probe;
}

SimulaBase* SimulaBase::existingPath(const std::string &name){


SimulaBase* SimulaBase::existingPath(const std::string &name, const Time &t){
	//Separate path into list names
	std::list<std::string> list;
	std::string::size_type pos(0);
@@ -496,7 +477,7 @@ SimulaBase* SimulaBase::existingPath(const std::string &name){
		}else{
			l=probe->hasChildren();
			if(l){
				probe=l->existing(*it);
				probe=l->existing(*it,t);
			}else{
				probe=nullptr;
			}
@@ -504,14 +485,33 @@ SimulaBase* SimulaBase::existingPath(const std::string &name){
	}
	return probe;
}

SimulaBase* SimulaBase::existingPath(const std::string &name, const Time &t){
	SimulaBase* probe = existingPath(name);
	if(probe && ! probe->evaluateTime(t)) probe=nullptr;
	return probe;
}
SimulaBase* SimulaBase::existingPath(const std::string &name, const Unit &u){
	SimulaBase* probe = existingPath(name);
	//Separate path into list names
	std::list<std::string> list;
	std::string::size_type pos(0);
	//loop through the list
	SimulaBase* probe;
	Database* l;
	if(name[pos]=='/'){
		++pos;
		while (pos<name.size()) list.push_back(nextWord(name,pos,'/'));
		probe=ORIGIN;
	}else{
		while (pos<name.size()) list.push_back(nextWord(name,pos,'/'));
		probe=this;
	}
	for(std::list<std::string>::iterator it(list.begin());it!=list.end() && probe!=nullptr ;++it){
		if(*it==".."){
			probe=probe->getParent();
		}else{
			l=probe->hasChildren();
			if(l){
				probe=l->existing(*it);
			}else{
				probe=nullptr;
			}
		}
	}
	if(probe) probe->checkUnit(u);
	return probe;
}
@@ -628,6 +628,37 @@ void SimulaBase::stopUpdatefunction(){
	if(attributes) attributes->stopUpdatefunction();
}

SimulaBase* SimulaBase::existingPath(const std::string &name){
	//Separate path into list names
	std::list<std::string> list;
	std::string::size_type pos(0);
	//loop through the list
	SimulaBase* probe;
	Database* l;
	if(name[pos]=='/'){
		++pos;
		while (pos<name.size()) list.push_back(nextWord(name,pos,'/'));
		probe=ORIGIN;
	}else{
		while (pos<name.size()) list.push_back(nextWord(name,pos,'/'));
		probe=this;
	}
	for(std::list<std::string>::iterator it(list.begin());it!=list.end() && probe!=nullptr ;++it){
		if(*it==".."){
			probe=probe->getParent();
		}else{
			l=probe->hasChildren();
			if(l){
				probe=l->existing(*it);
			}else{
				probe=nullptr;
			}
		}
	}
	return probe;
}


///@todo getNext, getFirst and getPrevious are expensive code, which could be done more elegantly?
SimulaBase* SimulaBase::getNextSibling(const Time &t){
	Database *a=getParent()->getChildren();
+43 −11
Original line number Diff line number Diff line
@@ -42,13 +42,26 @@ DerivativeBase * newInstantiationUseRootClassAndNutrientSpecificTable(SimulaDyna
bool OptimalNutrientContent::issueMessage(true);

OptimalNutrientContent::OptimalNutrientContent(SimulaDynamic* pSD) :
		TotalBaseLabeled(pSD) {
		TotalBaseLabeled(pSD),
		current(nullptr), dw(nullptr), rca(nullptr), paramConc(nullptr) {
	std::string l(pSD->getName().substr(11, 7));
	if (l[0] == 'O')
		l[0] = 'o';
	if (l[0] == 'M')
		l[0] = 'm';
	current = pSD->getSibling(l + "NutrientConcentration");
	current = pSD->existingSibling(l + "NutrientConcentration");
	if(!current){
		//use parameter section to get target concentrations
		//plant type and root type
		std::string plantType;
		PLANTTYPE(plantType,pSD);
		//get the root type
		std::string rootType;
		pSD->getParent(4)->getChild("rootType")->get(rootType);
		SimulaBase *param=GETROOTPARAMETERS(plantType,rootType);
		paramConc=param->getChild(pSD->getParent()->getName())->getChild(l + "NutrientConcentration");
	}

	//dryweight
	dw = pSD->getParent(2)->getChild("rootSegmentDryWeight");

@@ -92,15 +105,23 @@ void OptimalNutrientContent::calculate(const Time &t, double &result) {
		l[0] = 'o';
	if (l[0] == 'M')
		l[0] = 'm';
	SimulaBase *next = getNext(t)->getSibling(l + "NutrientConcentration");
	SimulaBase *next = getNext(t);


	//get optimal concentrations at these datapoints
	double concD0(0);
	double concD0(0), concD1(0);
	if(current){
		current->get(t, concD0);
	double concD1(concD0);
		next=next->getSibling(l + "NutrientConcentration");
		if(next!=current && next->evaluateTime(t)){
			next->get(t, concD1);
		}
	}else{
		const double t0=pSD->getStartTime();
		const double t1=next->getStartTime();
		paramConc->get(t-t0,concD0);
		paramConc->get(t-t1,concD1);
	}

	//get dryweight
	double d;
@@ -124,6 +145,7 @@ void OptimalNutrientContent::calculate(const Time &t, double &result) {
	scale_ = result;
}
bool OptimalNutrientContent::postIntegrationCorrection(SimulaVariable::Table & data) {
	//only for old input files that expect integration, rather than a simply algabreic solution.
	bool r(false);
	//iterators
	SimulaVariable::Table::iterator eit(data.end());
@@ -148,7 +170,7 @@ DerivativeBase * newInstantiationOptimalNutrientContent(SimulaDynamic* const pSD
}

ShootOptimalNutrientContent::ShootOptimalNutrientContent(SimulaDynamic* pSD) :
	DerivativeBase(pSD), dws(nullptr) {	//leafs or stem
		DerivativeBase(pSD), conc(nullptr), dw(nullptr), dws(nullptr), refTime(0) {	//leafs or stem
	std::string s(pSD->getName());
	std::size_t n(s.size() - 22);
	std::string sp(s.substr(0, n));
@@ -157,7 +179,17 @@ ShootOptimalNutrientContent::ShootOptimalNutrientContent(SimulaDynamic* pSD) :
	dw  = pSD->getParent(2)->getChild(sp + "DryWeight", "g");
	if(sp=="leaf") dws = pSD->getParent(2)->existingChild("senescedLeafDryWeight", "g");
	//concentration
	conc = pSD->getSibling(som + "NutrientConcentration", pSD->getUnit() / "g");
	conc = pSD->existingSibling(som + "NutrientConcentration", pSD->getUnit() / "g");
	if(!conc){
		refTime=pSD->getStartTime();
		//use parameter section to get target concentrations
		//plant type and root type
		std::string plantType;
		PLANTTYPE(plantType,pSD);
		//get the root type
		SimulaBase *param=GETSHOOTPARAMETERS(plantType);
		conc = param->getChild(pSD->getParent()->getName())->getChild(som + "NutrientConcentration", pSD->getUnit() / "g");
	}
}
void ShootOptimalNutrientContent::calculate(const Time &t, double &result) {
	dw->get(t, result);
@@ -167,7 +199,7 @@ void ShootOptimalNutrientContent::calculate(const Time &t, double &result) {
		result-=senescence;
	}
	double c;
	conc->get(t, c);
	conc->get(t-refTime, c);
	result *= c;
}
std::string ShootOptimalNutrientContent::getName() const {
+2 −1
Original line number Diff line number Diff line
@@ -39,7 +39,7 @@ public:
	std::string getName() const;
protected:
	void calculate(const Time &t, double &var);
	SimulaBase *current, *dw, *rca;
	SimulaBase *current, *dw, *rca, *paramConc;
	static bool issueMessage;
	double scale_;
};
@@ -50,6 +50,7 @@ public:
protected:
	void calculate(const Time &t, double &var);
	SimulaBase *conc, *dw, *dws;
	Time refTime;
};
class ActualNutrientContent: public TotalBaseLabeled {
public: