Split from #400. Draft is written and reviewed locally but not posted, since it publishes to another organisation's tracker.
The defect
src/landuse/check_lu.c is documented as a predicate — /** \return TRUE if crop stand can be established */ — and takes a const Standlist, but was changed to mutate the stands it inspects, with the local const Stand *stand downgraded to allow the write:
if(getlandusetype(stand)!=URBAN && stand->pftlist.n==0)
stand->type=&kill_stand;
The guard's intent is correct (getpft(&stand->pftlist,0) on the next line reads past the end of an empty PFT list) but it destroys empty stands rather than skipping them. Setaside stands are legitimately empty at the moment a crop is about to be sown into them, so asking "can a crop establish here?" deletes the stand needed to answer yes; sowingcft() then cannot find it via findlandusetype() and the land is never sown.
Fixed on our fork's master (c7b56564) by skipping instead of converting, and restoring const correctness.
Why it is worth reporting
It is present in PIK-LPJmL/LPJmL master, so anyone running 6.x with land use is affected. Nothing matching exists in their tracker (searched check_lu, setaside, kill_stand, cftfrac, "crop establishment" — zero hits each).
The symptom is easy to miss and hard to attribute: the model's own outputs disagree, with fpc band 1 and globalflux area reporting managed land unchanged while cftfrac accounts for only ~64% of it. Nine crop-physiology experiments failed to find it before that reconciliation pointed at establishment.
To do
Post the draft at scratchpad/UPSTREAM_REPORT.md (or rewrite it) as an issue on PIK-LPJmL/LPJmL, ideally with the suggested patch. Their issue tracker is open and takes external reports.
Split from #400. Draft is written and reviewed locally but not posted, since it publishes to another organisation's tracker.
The defect
src/landuse/check_lu.cis documented as a predicate —/** \return TRUE if crop stand can be established */— and takes aconst Standlist, but was changed to mutate the stands it inspects, with the localconst Stand *standdowngraded to allow the write:The guard's intent is correct (
getpft(&stand->pftlist,0)on the next line reads past the end of an empty PFT list) but it destroys empty stands rather than skipping them. Setaside stands are legitimately empty at the moment a crop is about to be sown into them, so asking "can a crop establish here?" deletes the stand needed to answer yes;sowingcft()then cannot find it viafindlandusetype()and the land is never sown.Fixed on our fork's
master(c7b56564) by skipping instead of converting, and restoring const correctness.Why it is worth reporting
It is present in
PIK-LPJmL/LPJmLmaster, so anyone running 6.x with land use is affected. Nothing matching exists in their tracker (searchedcheck_lu,setaside,kill_stand,cftfrac, "crop establishment" — zero hits each).The symptom is easy to miss and hard to attribute: the model's own outputs disagree, with
fpcband 1 and globalfluxareareporting managed land unchanged whilecftfracaccounts for only ~64% of it. Nine crop-physiology experiments failed to find it before that reconciliation pointed at establishment.To do
Post the draft at
scratchpad/UPSTREAM_REPORT.md(or rewrite it) as an issue onPIK-LPJmL/LPJmL, ideally with the suggested patch. Their issue tracker is open and takes external reports.