parameters.cpp 66 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775
  1. /////////////////////////////////////////////////////////////////////////////////
  2. /// \file parameters.cpp
  3. /// \brief Implementation of the parameters module
  4. ///
  5. /// New instructions (PLIB keywords) may be added (this would require addition of a
  6. /// declareitem call in function plib_declarations, and possibly some additional code in
  7. /// function plib_callback).
  8. ///
  9. /// \author Joe Siltberg
  10. /// $Date: 2014-05-13 14:55:59 +0200 (Tue, 13 May 2014) $
  11. ///
  12. ///////////////////////////////////////////////////////////////////////////////////////
  13. #include "config.h"
  14. #include "parameters.h"
  15. #include "guess.h"
  16. #include "plib.h"
  17. #include <map>
  18. // Definitions of parameters defined globally in parameters.h,
  19. // for documentation, see parameters.h
  20. xtring title;
  21. vegmodetype vegmode;
  22. int npatch;
  23. int npatch_secondarystand;
  24. bool reduce_all_stands;
  25. int age_limit_reduce;
  26. double patcharea;
  27. bool ifbgestab;
  28. bool ifsme;
  29. bool ifstochestab;
  30. bool ifstochmort;
  31. bool iffire;
  32. bool ifdisturb;
  33. bool ifcalcsla;
  34. bool ifcalccton;
  35. int estinterval;
  36. double distinterval;
  37. bool ifcdebt;
  38. bool ifcentury;
  39. bool ifnlim;
  40. int freenyears;
  41. double nrelocfrac;
  42. double nfix_a;
  43. double nfix_b;
  44. bool ifsmoothgreffmort;
  45. bool ifdroughtlimitedestab;
  46. bool ifrainonwetdaysonly;
  47. bool ifbvoc;
  48. wateruptaketype wateruptake;
  49. bool run_landcover;
  50. bool run[NLANDCOVERTYPES];
  51. bool frac_fixed[NLANDCOVERTYPES];
  52. bool lcfrac_fixed;
  53. bool all_fracs_const;
  54. bool ifslowharvestpool;
  55. bool ifintercropgrass;
  56. bool ifcalcdynamic_phu;
  57. int gross_land_transfer;
  58. bool gross_input_present = false;
  59. bool ifprimary_lc_transfer = false;
  60. bool use_primary_lc_transfer = false;
  61. bool ifprimary_to_secondary_transfer = false;
  62. int transfer_level;
  63. bool ifdyn_phu_limit;
  64. bool iftransfer_to_new_stand;
  65. int nyear_dyn_phu;
  66. int nyear_spinup;
  67. bool textured_soil;
  68. bool disturb_pasture;
  69. bool grassforcrop;
  70. xtring state_path;
  71. xtring state_name; // ecev3
  72. bool restart;
  73. bool save_state;
  74. int state_year;
  75. bool readsowingdates = false;
  76. bool readharvestdates = false;
  77. bool readNfert = false;
  78. bool readNfert_st = false;
  79. bool readwoodharvest_frac = false;
  80. bool readwoodharvest_vol = false;
  81. bool harvest_secondary_to_new_stand = true;
  82. bool printseparatestands = false;
  83. bool printcrescendo = false;
  84. bool printcrescendodaily = false;
  85. bool printcrescendofacedaily = false;
  86. bool printcmip6 = false;
  87. bool printcmip6daily = false;
  88. bool printifsinputdaily = false;
  89. bool iftillage = false;
  90. // for LUMIP deforest experiment (see the .h file)
  91. int deforest_method_type = 0;
  92. int deforest_start_year = 0;
  93. int deforest_end_year = 0;
  94. ///////////////////////////////////////////////////////////////////////////////////////
  95. // Implementation of the Paramlist class
  96. Paramlist param;
  97. void Paramlist::addparam(xtring name,xtring value) {
  98. Paramtype* p = find(name);
  99. if (p == 0) {
  100. p = &createobj();
  101. }
  102. p->name=name.lower();
  103. p->str=value;
  104. }
  105. void Paramlist::addparam(xtring name,double value) {
  106. Paramtype* p = find(name);
  107. if (p == 0) {
  108. p = &createobj();
  109. }
  110. p->name=name.lower();
  111. p->num=value;
  112. }
  113. Paramtype& Paramlist::operator[](xtring name) {
  114. Paramtype* param = find(name);
  115. if (param == 0) {
  116. fail("Paramlist::operator[]: parameter \"%s\" not found",(char*)name);
  117. }
  118. return *param;
  119. }
  120. Paramtype* Paramlist::find(xtring name) {
  121. name = name.lower();
  122. firstobj();
  123. while (isobj) {
  124. Paramtype& p=getobj();
  125. if (p.name==name) return &p;
  126. nextobj();
  127. }
  128. // nothing found
  129. return 0;
  130. }
  131. bool Paramlist::isparam(xtring name) {
  132. if (!find(name))
  133. return false;
  134. else
  135. return true;
  136. }
  137. ///////////////////////////////////////////////////////////////////////////////////////
  138. // ENUM DECLARATIONS OF INTEGER CONSTANTS FOR PLIB INTERFACE
  139. enum {BLOCK_GLOBAL,BLOCK_PFT,BLOCK_PARAM,BLOCK_ST,BLOCK_MT};
  140. enum {CB_NONE,CB_VEGMODE,CB_CHECKGLOBAL,CB_LIFEFORM,CB_LANDCOVER,CB_PHENOLOGY,CB_LEAFPHYSIOGNOMY,CB_SELECTION,
  141. CB_STLANDCOVER, CB_STINTERCROP, CB_STNATURALVEG, CB_CHECKST, CB_CHECKMT,
  142. CB_MTPLANTINGSYSTEM, CB_MTHARVESTSYSTEM, CB_MTPFT, CB_STREESTAB, CB_MTSELECTION, CB_MTHYDROLOGY,
  143. CB_PLANTINGSYSTEM, CB_HARVESTSYSTEM, CB_PFT, CB_STSELECTION, CB_STHYDROLOGY, CB_MANAGEMENT1, CB_MANAGEMENT2, CB_MANAGEMENT3,
  144. CB_PATHWAY,CB_ROOTDIST,CB_EST,CB_CHECKPFT,CB_STRPARAM,CB_NUMPARAM,CB_WATERUPTAKE,CB_MTCOMPOUND};
  145. // File local variables
  146. namespace {
  147. Pft* ppft; // pointer to Pft object currently being assigned to
  148. StandType* pst;
  149. ManagementType* pmt;
  150. xtring paramname;
  151. xtring strparam;
  152. double numparam;
  153. bool ifhelp=false;
  154. // 'include' parameter for currently scanned PFT
  155. bool includepft;
  156. bool includest;
  157. bool includemt;
  158. // 'include' parameter per PFT
  159. std::map<xtring, bool> includepft_map;
  160. // 'include' parameter per ST
  161. std::map<xtring, bool> includest_map;
  162. // 'include' parameter per MT
  163. std::map<xtring, bool> includemt_map;
  164. // Whether each PFT has had their parameters checked.
  165. // We only check a PFT:s parameters (in plib_callback) the first time the PFT is
  166. // parsed. If the same PFT occurs again (probably in a different file with a few
  167. // minor modifications) we don't check again (because plib's itemparsed() function
  168. // doesn't remember the old parsed parameters).
  169. std::map<xtring, bool> checked_pft;
  170. std::map<xtring, bool> checked_st;
  171. std::map<xtring, bool> checked_mt;
  172. }
  173. void initsettings() {
  174. // Initialises global settings
  175. // Parameters not initialised here must be set in instruction script
  176. iffire=true;
  177. ifcalcsla=true;
  178. ifdisturb=false;
  179. ifcalcsla=false;
  180. ifcalccton=true;
  181. ifcdebt=false;
  182. distinterval=1.0e10;
  183. npatch=1;
  184. vegmode=COHORT;
  185. run_landcover = false;
  186. printseparatestands = false;
  187. printcrescendo = false;
  188. printcrescendodaily = false;
  189. printcrescendofacedaily = false;
  190. printcmip6 = false;
  191. printcmip6daily = false;
  192. printifsinputdaily = false;
  193. save_state = false;
  194. restart = false;
  195. lcfrac_fixed = true;
  196. for(int lc=0; lc<NLANDCOVERTYPES; lc++)
  197. frac_fixed[lc] = true;
  198. textured_soil = true;
  199. disturb_pasture = false;
  200. grassforcrop = false;
  201. }
  202. void initpft(Pft& pft,xtring& setname) {
  203. // Initialises a PFT object
  204. // Parameters not initialised here must be set in instruction script
  205. pft.name=setname;
  206. pft.lifeform=NOLIFEFORM;
  207. pft.phenology=NOPHENOLOGY;
  208. // Set bioclimatic limits so that PFT can establish and survive under all
  209. // conditions (may be overridden by settings in instruction script)
  210. pft.tcmin_surv=-1000.0;
  211. pft.tcmin_est=-1000.0;
  212. pft.tcmax_est=1000.0;
  213. pft.twmin_est=-1000.0;
  214. pft.gdd5min_est=1000.0;
  215. pft.twminusc=0.0;
  216. // Set chilling parameters so that no chilling period required for budburst
  217. pft.k_chilla=0.0;
  218. pft.k_chillb=0.0;
  219. pft.k_chillk=0.0;
  220. }
  221. void initst(StandType& st,xtring& setname) {
  222. // Initialises a PFT object
  223. // Parameters not initialised here must be set in instruction script
  224. st.name=setname;
  225. st.landcover=NATURAL;
  226. st.intercrop=NOINTERCROP;
  227. }
  228. void initmt(ManagementType& mt,xtring& setname) {
  229. // Initialises a PFT object
  230. // Parameters not initialised here must be set in instruction script
  231. mt.name=setname;
  232. }
  233. ///////////////////////////////////////////////////////////////////////////////////////
  234. // Data structures for storing parameters declared from other modules
  235. // (see the declare_parameter functions)
  236. //
  237. namespace {
  238. struct xtringParam {
  239. xtringParam(const char* name, xtring* param, int maxlen, const char* help)
  240. : name(name),
  241. param(param),
  242. maxlen(maxlen),
  243. help(help) {}
  244. const char* name;
  245. xtring* param;
  246. int maxlen;
  247. const char* help;
  248. };
  249. std::vector<xtringParam> xtringParams;
  250. struct stringParam {
  251. stringParam(const char* name, std::string* param, int maxlen, const char* help)
  252. : name(name),
  253. param(param),
  254. maxlen(maxlen),
  255. help(help) {}
  256. const char* name;
  257. std::string* param;
  258. int maxlen;
  259. const char* help;
  260. };
  261. std::vector<stringParam> stringParams;
  262. struct intParam {
  263. intParam(const char* name, int* param, int min, int max, const char* help)
  264. : name(name),
  265. param(param),
  266. min(min),
  267. max(max),
  268. help(help) {}
  269. const char* name;
  270. int* param;
  271. int min;
  272. int max;
  273. const char* help;
  274. };
  275. std::vector<intParam> intParams;
  276. struct doubleParam {
  277. doubleParam(const char* name, double* param, double min, double max, const char* help)
  278. : name(name),
  279. param(param),
  280. min(min),
  281. max(max),
  282. help(help) {}
  283. const char* name;
  284. double* param;
  285. double min;
  286. double max;
  287. const char* help;
  288. };
  289. std::vector<doubleParam> doubleParams;
  290. struct boolParam {
  291. boolParam(const char* name, bool* param, const char* help)
  292. : name(name),
  293. param(param),
  294. help(help) {}
  295. const char* name;
  296. bool* param;
  297. const char* help;
  298. };
  299. std::vector<boolParam> boolParams;
  300. } // namespace
  301. ///////////////////////////////////////////////////////////////////////////////////////
  302. // The following declare_parameter allow other modules to declare instruction file
  303. // parameters. The information is simply stored and then sent to plib in
  304. // plib_declarations with calls to declareitem().
  305. void declare_parameter(const char* name, xtring* param, int maxlen, const char* help) {
  306. xtringParams.push_back(xtringParam(name, param, maxlen, help));
  307. }
  308. void declare_parameter(const char* name, std::string* param, int maxlen, const char* help) {
  309. stringParams.push_back(stringParam(name, param, maxlen, help));
  310. }
  311. void declare_parameter(const char* name, int* param, int min, int max, const char* help) {
  312. intParams.push_back(intParam(name, param, min, max, help));
  313. }
  314. void declare_parameter(const char* name, double* param, double min, double max, const char* help) {
  315. doubleParams.push_back(doubleParam(name, param, min, max, help));
  316. }
  317. void declare_parameter(const char* name, bool* param, const char* help) {
  318. boolParams.push_back(boolParam(name, param, help));
  319. }
  320. ///////////////////////////////////////////////////////////////////////////////////////
  321. // The following code uses functionality from the PLIB library to process an
  322. // instruction script (ins) file containing simulation settings and PFT parameters.
  323. // Function read_instruction_file() is called by the framework to initiate parsing of the script.
  324. // Function printhelp() is called if GUESS is run with '-help' instead of an ins file
  325. // name as a command line argument. Functions plib_declarations, plib_callback and
  326. // plib_receivemessage comprise part of the interface to PLIB.
  327. void plib_declarations(int id,xtring setname) {
  328. switch (id) {
  329. case BLOCK_GLOBAL:
  330. declareitem("title",&title,80,CB_NONE,"Title for run");
  331. declareitem("nyear_spinup",&nyear_spinup,1,10000,1,CB_NONE,"Number of simulation years to spinup for");
  332. declareitem("vegmode",&strparam,16,CB_VEGMODE,
  333. "Vegetation mode (\"INDIVIDUAL\", \"COHORT\", \"POPULATION\")");
  334. declareitem("ifbgestab",&ifbgestab,1,CB_NONE,
  335. "Whether background establishment enabled (0,1)");
  336. declareitem("ifsme",&ifsme,1,CB_NONE,
  337. "Whether spatial mass effect enabled for establishment (0,1)");
  338. declareitem("ifstochmort",&ifstochmort,1,CB_NONE,
  339. "Whether mortality stochastic (0,1)");
  340. declareitem("ifstochestab",&ifstochestab,1,CB_NONE,
  341. "Whether establishment stochastic (0,1)");
  342. declareitem("estinterval",&estinterval,1,10,1,CB_NONE,
  343. "Interval for establishment of new cohorts (years)");
  344. declareitem("distinterval",&distinterval,1.0,1.0e10,1,CB_NONE,
  345. "Generic patch-destroying disturbance interval (years)");
  346. declareitem("iffire",&iffire,1,CB_NONE,
  347. "Whether fire enabled (0,1)");
  348. declareitem("ifdisturb",&ifdisturb,1,CB_NONE,
  349. "Whether generic patch-destroying disturbance enabled (0,1)");
  350. declareitem("ifcalcsla",&ifcalcsla,1,CB_NONE,
  351. "Whether SLA calculated from leaf longevity");
  352. declareitem("ifcalccton",&ifcalccton,1,CB_NONE,
  353. "Whether leaf C:N min calculated from leaf longevity");
  354. declareitem("ifcdebt",&ifcdebt,1,CB_NONE,
  355. "Whether to allow C storage");
  356. declareitem("npatch",&npatch,1,1000,1,CB_NONE,
  357. "Number of patches simulated");
  358. declareitem("npatch_secondarystand",&npatch_secondarystand,1,1000,1,CB_NONE,
  359. "Number of patches simulated in secondary stands");
  360. declareitem("reduce_all_stands",&reduce_all_stands,1,CB_NONE,
  361. "Whether to reduce equal percentage of all stands of a stand type at land cover change");
  362. declareitem("age_limit_reduce",&age_limit_reduce,0,1000,1,CB_NONE,
  363. "Minimum age of stands to reduce at land cover change");
  364. declareitem("patcharea",&patcharea,1.0,1.0e4,1,CB_NONE,
  365. "Patch area (m2)");
  366. declareitem("wateruptake", &strparam, 20, CB_WATERUPTAKE,
  367. "Water uptake mode (\"WCONT\", \"ROOTDIST\", \"SMART\", \"SPECIESSPECIFIC\")");
  368. declareitem("nrelocfrac",&nrelocfrac,0.0,0.99,1,CB_NONE,
  369. "Fractional nitrogen relocation from shed leaves & roots");
  370. declareitem("nfix_a",&nfix_a,0.0,0.4,1,CB_NONE,
  371. "first term in nitrogen fixation eqn");
  372. declareitem("nfix_b",&nfix_b,-10.0,10.,1,CB_NONE,
  373. "second term in nitrogen fixation eqn");
  374. declareitem("ifcentury",&ifcentury,1,CB_NONE,
  375. "Whether to use CENTURY SOM dynamics (default standard LPJ)");
  376. declareitem("ifnlim",&ifnlim,1,CB_NONE,
  377. "Whether plant growth limited by available nitrogen");
  378. declareitem("freenyears",&freenyears,0,1000,1,CB_NONE,
  379. "Number of years to spinup without nitrogen limitation");
  380. declareitem("ifsmoothgreffmort",&ifsmoothgreffmort,1,CB_NONE,
  381. "Whether to vary mort_greff smoothly with growth efficiency (0,1)");
  382. declareitem("ifdroughtlimitedestab",&ifdroughtlimitedestab,1,CB_NONE,
  383. "Whether establishment drought limited (0,1)");
  384. declareitem("ifrainonwetdaysonly",&ifrainonwetdaysonly,1,CB_NONE,
  385. "Whether it rains on wet days only (1), or a little every day (0);");
  386. declareitem("deforest_method_type",&deforest_method_type,0,10000,1,CB_NONE,"LUMIP: deforestation method: 0=disabled, 1=start<=year<end and in all grid points, 2=like 1, but only in gridpoints and years with vs>0 (could be wrong, shifted by oneyear!!!)");
  387. declareitem("deforest_start_year",&deforest_start_year,0,10000,1,CB_NONE,"LUMIP: year the establishment for trees will be turned off");
  388. declareitem("deforest_end_year",&deforest_end_year,0,10000,1,CB_NONE,"LUMIP: year the establishment for trees will be turned on again");
  389. // bvoc
  390. declareitem("ifbvoc",&ifbvoc,1,CB_NONE,
  391. "Whether or not BVOC calculations are performed (0,1)");
  392. declareitem("run_landcover",&run_landcover,1,CB_NONE,"Landcover version");
  393. declareitem("run_urban",&run[URBAN],1,CB_NONE,"Whether urban land is to be simulated");
  394. declareitem("run_crop",&run[CROPLAND],1,CB_NONE,"Whether crop-land is to be simulated");
  395. declareitem("run_pasture",&run[PASTURE],1,CB_NONE,"Whether pasture is to be simulated");
  396. declareitem("run_forest",&run[FOREST],1,CB_NONE,"Whether managed forest is to be simulated");
  397. declareitem("run_natural",&run[NATURAL],1,CB_NONE,"Whether natural vegetation is to be simulated");
  398. declareitem("run_peatland",&run[PEATLAND],1,CB_NONE,"Whether peatland is to be simulated");
  399. declareitem("run_barren",&run[BARREN],1,CB_NONE,"Whether barren land is to be simulated");
  400. declareitem("ifslowharvestpool",&ifslowharvestpool,1,CB_NONE,"If a slow harvested product pool is included in patchpft.");
  401. declareitem("ifintercropgrass",&ifintercropgrass,1,CB_NONE,"Whether intercrop growth is allowed");
  402. declareitem("ifcalcdynamic_phu",&ifcalcdynamic_phu,1,CB_NONE,"Whether to calculate dynamic potential heat units");
  403. declareitem("gross_land_transfer",&gross_land_transfer,0,3,1,CB_NONE,
  404. "Whether to use gross land transfer: simulate gross lcc (1); read landcover transfer matrix input file (2); read stand type transfer matrix input file (3), or not (0)");
  405. declareitem("ifprimary_lc_transfer",&ifprimary_lc_transfer,1,CB_NONE,
  406. "Whether to use primary/secondary land transition info in landcover transfer input file (1). or not (0)");
  407. declareitem("ifprimary_to_secondary_transfer",&ifprimary_to_secondary_transfer,1,CB_NONE,
  408. "Whether to use primary-to-secondary land transition info (within land cover type) in landcover transfer input file (1). or not (0)");
  409. declareitem("harvest_secondary_to_new_stand",&harvest_secondary_to_new_stand,1,CB_NONE,
  410. "Whether to create new stands at clearcut of secondary stands (1). or not (0)");
  411. declareitem("transfer_level",&transfer_level,0,3,1,CB_NONE,"Pooling level of land cover transitions; 0: one big pool; 1: land cover-level; 2: stand type-level");
  412. declareitem("ifdyn_phu_limit",&ifdyn_phu_limit,1,CB_NONE,"Whether to limit dynamic phu calculation to a time period");
  413. declareitem("iftransfer_to_new_stand",&iftransfer_to_new_stand,1,CB_NONE,"Whether to create new stands in transfer_to_new_stand()");
  414. declareitem("nyear_dyn_phu",&nyear_dyn_phu,0,1000,1,CB_NONE, "Number of years to calculate dynamic phu");
  415. declareitem("printseparatestands",&printseparatestands, 1, CB_NONE, "Whether to print multiple stands within a land cover type (except cropland) separately");
  416. declareitem("printcrescendo", &printcrescendo, 1, CB_NONE, "Whether to print CRESCENDO outputs");
  417. declareitem("printcrescendodaily", &printcrescendodaily, 1, CB_NONE, "Whether to print DAILY CRESCENDO outputs");
  418. declareitem("printcrescendofacedaily", &printcrescendofacedaily, 1, CB_NONE, "Whether to print DAILY FACE experiment CRESCENDO outputs");
  419. declareitem("printcmip6", &printcmip6, 1, CB_NONE, "Whether to print C4MIP outputs");
  420. declareitem("printcmip6daily", &printcmip6daily, 1, CB_NONE, "Whether to print DAILY CMIP6 outputs");
  421. declareitem("printifsinputdaily", &printifsinputdaily, 1, CB_NONE, "Whether to print IFS input as outputs");
  422. declareitem("iftillage",&iftillage,1,CB_NONE,"Whether to simulate tillage by increasing soil respiration");
  423. declareitem("textured_soil",&textured_soil,1,CB_NONE,"Use silt/sand fractions specific to soiltype");
  424. declareitem("disturb_pasture",&disturb_pasture,1,CB_NONE,"Whether fire and disturbances enabled on pastures (0,1)");
  425. declareitem("grassforcrop",&grassforcrop,1,CB_NONE,"grassforcrop");
  426. declareitem("state_path", &state_path, 300, CB_NONE, "State files directory (for restarting from, or saving state files)");
  427. /// Declare name of the state files - ecev3
  428. declareitem("state_name", &state_name, 300, CB_NONE, "State file name (for restarting from, or saving state files)");
  429. declareitem("restart", &restart, 1, CB_NONE, "Whether to restart from state files");
  430. declareitem("save_state", &save_state, 1, CB_NONE, "Whether to save new state files");
  431. declareitem("state_year", &state_year, 1, 20000, 1, CB_NONE, "Save/restart year. Unspecified means just after spinup");
  432. declareitem("pft",BLOCK_PFT,CB_NONE,"Header for block defining PFT");
  433. declareitem("param",BLOCK_PARAM,CB_NONE,"Header for custom parameter block");
  434. declareitem("st",BLOCK_ST,CB_NONE,"Header for block defining StandType");
  435. declareitem("mt",BLOCK_MT,CB_NONE,"Header for block defining Management");
  436. for (size_t i = 0; i < xtringParams.size(); ++i) {
  437. const xtringParam& p = xtringParams[i];
  438. declareitem(p.name, p.param, p.maxlen, 0, p.help);
  439. }
  440. for (size_t i = 0; i < stringParams.size(); ++i) {
  441. const stringParam& p = stringParams[i];
  442. declareitem(p.name, p.param, p.maxlen, 0, p.help);
  443. }
  444. for (size_t i = 0; i < intParams.size(); ++i) {
  445. const intParam& p = intParams[i];
  446. declareitem(p.name, p.param, p.min, p.max, 1, 0, p.help);
  447. }
  448. for (size_t i = 0; i < doubleParams.size(); ++i) {
  449. const doubleParam& p = doubleParams[i];
  450. declareitem(p.name, p.param, p.min, p.max, 1, 0, p.help);
  451. }
  452. for (size_t i = 0; i < boolParams.size(); ++i) {
  453. const boolParam& p = boolParams[i];
  454. declareitem(p.name, p.param, 1, 0, p.help);
  455. }
  456. callwhendone(CB_CHECKGLOBAL);
  457. break;
  458. case BLOCK_PFT:
  459. if (!ifhelp) {
  460. ppft = 0;
  461. // Was this pft already created?
  462. for (size_t p = 0; p < pftlist.nobj; ++p) {
  463. if (pftlist[(unsigned int)p].name == setname) {
  464. ppft = &pftlist[(unsigned int)p];
  465. }
  466. }
  467. if (ppft == 0) {
  468. // Create and initialise a new Pft object and obtain a reference to it
  469. ppft=&pftlist.createobj();
  470. initpft(*ppft,setname);
  471. includepft_map[setname] = true;
  472. }
  473. }
  474. declareitem("include",&includepft,1,CB_NONE,"Include PFT in analysis");
  475. declareitem("lifeform",&strparam,16,CB_LIFEFORM,
  476. "Lifeform (\"TREE\" or \"GRASS\")");
  477. declareitem("landcover",&strparam,16,CB_LANDCOVER,
  478. "Landcovertype (\"URBAN\", \"CROP\", \"PASTURE\", \"FOREST\", \"NATURAL\", \"PEATLAND\" or \"BARREN\")");
  479. declareitem("selection",&strparam,16,CB_SELECTION ,"Name of pft selection");
  480. declareitem("phenology",&strparam,16,CB_PHENOLOGY,
  481. "Phenology (\"EVERGREEN\", \"SUMMERGREEN\", \"RAINGREEN\", \"CROPGREEN\" or \"ANY\")");
  482. declareitem("leafphysiognomy",&strparam,16,CB_LEAFPHYSIOGNOMY,
  483. "Leaf physiognomy (\"NEEDLELEAF\" or \"BROADLEAF\")");
  484. declareitem("phengdd5ramp",&ppft->phengdd5ramp,0.0,1000.0,1,CB_NONE,
  485. "GDD on 5 deg C base to attain full leaf cover");
  486. declareitem("wscal_min",&ppft->wscal_min,0.0,1.0,1,CB_NONE,
  487. "Water stress threshold for leaf abscission (raingreen PFTs)");
  488. declareitem("pathway",&strparam,16,CB_PATHWAY,
  489. "Biochemical pathway (\"C3\" or \"C4\")");
  490. declareitem("pstemp_min",&ppft->pstemp_min,-50.0,50.0,1,CB_NONE,
  491. "Approximate low temp limit for photosynthesis (deg C)");
  492. declareitem("pstemp_low",&ppft->pstemp_low,-50.0,50.0,1,CB_NONE,
  493. "Approx lower range of temp optimum for photosynthesis (deg C)");
  494. declareitem("pstemp_high",&ppft->pstemp_high,0.0,60.0,1,CB_NONE,
  495. "Approx higher range of temp optimum for photosynthesis (deg C)");
  496. declareitem("pstemp_max",&ppft->pstemp_max,0.0,60.0,1,CB_NONE,
  497. "Maximum temperature limit for photosynthesis (deg C)");
  498. declareitem("lambda_max",&ppft->lambda_max,0.1,0.99,1,CB_NONE,
  499. "Non-water-stressed ratio of intercellular to ambient CO2 pp");
  500. declareitem("rootdist",ppft->rootdist,0.0,1.0,NSOILLAYER,CB_ROOTDIST,
  501. "Fraction of roots in each soil layer (first value=upper layer)");
  502. declareitem("gmin",&ppft->gmin,0.0,1.0,1,CB_NONE,
  503. "Canopy conductance not assoc with photosynthesis (mm/s)");
  504. declareitem("emax",&ppft->emax,0.0,50.0,1,CB_NONE,
  505. "Maximum evapotranspiration rate (mm/day)");
  506. // guess2008 - increased the upper limit to possible respcoeff values (was 1.2)
  507. declareitem("respcoeff",&ppft->respcoeff,0.0,3,1,CB_NONE,
  508. "Respiration coefficient (0-1)");
  509. declareitem("cton_root",&ppft->cton_root,1.0,1.0e4,1,CB_NONE,
  510. "Reference Fine root C:N mass ratio");
  511. declareitem("cton_sap",&ppft->cton_sap,1.0,1.0e4,1,CB_NONE,
  512. "Reference Sapwood C:N mass ratio");
  513. declareitem("nuptoroot",&ppft->nuptoroot,0.0,1.0,1,CB_NONE,
  514. "Maximum nitrogen uptake per fine root");
  515. declareitem("km_volume",&ppft->km_volume,0.0,10.0,1,CB_NONE,
  516. "Michaelis-Menten kinetic parameters for nitrogen uptake");
  517. declareitem("fnstorage",&ppft->fnstorage,0.0,10.0,1,CB_NONE,
  518. "fraction of sapwood (root for herbaceous pfts) that can be used as a nitrogen storage scalar");
  519. declareitem("reprfrac",&ppft->reprfrac,0.0,1.0,1,CB_NONE,
  520. "Fraction of NPP allocated to reproduction");
  521. declareitem("turnover_leaf",&ppft->turnover_leaf,0.0,1.0,1,CB_NONE,
  522. "Leaf turnover (fraction/year)");
  523. declareitem("turnover_root",&ppft->turnover_root,0.0,1.0,1,CB_NONE,
  524. "Fine root turnover (fraction/year)");
  525. declareitem("turnover_sap",&ppft->turnover_sap,0.0,1.0,1,CB_NONE,
  526. "Sapwood turnover (fraction/year)");
  527. declareitem("wooddens",&ppft->wooddens,10.0,1000.0,1,CB_NONE,
  528. "Sapwood and heartwood density (kgC/m3)");
  529. declareitem("crownarea_max",&ppft->crownarea_max,1.0,1000.0,1,CB_NONE,
  530. "Maximum tree crown area (m2)");
  531. declareitem("k_allom1",&ppft->k_allom1,10.0,1000.0,1,CB_NONE,
  532. "Constant in allometry equations");
  533. // guess2008 - changed lower limit for k_allom2 to 1 from 10. This is needed
  534. // for the shrub allometries.
  535. declareitem("k_allom2",&ppft->k_allom2,1.0,1.0e4,1,CB_NONE,
  536. "Constant in allometry equations");
  537. declareitem("k_allom3",&ppft->k_allom3,0.1,1.0,1,CB_NONE,
  538. "Constant in allometry equations");
  539. declareitem("k_rp",&ppft->k_rp,1.0,2.0,1,CB_NONE,
  540. "Constant in allometry equations");
  541. declareitem("k_latosa",&ppft->k_latosa,100.0,1.0e5,1,CB_NONE,
  542. "Tree leaf to sapwood xs area ratio");
  543. declareitem("sla",&ppft->sla,1.0,1000.0,1,CB_NONE,
  544. "Specific leaf area (m2/kgC)");
  545. declareitem("cton_leaf_min",&ppft->cton_leaf_min,1.0,1.0e4,1,CB_NONE,
  546. "Minimum leaf C:N mass ratio");
  547. declareitem("ltor_max",&ppft->ltor_max,0.1,10.0,1,CB_NONE,
  548. "Non-water-stressed leaf:fine root mass ratio");
  549. declareitem("litterme",&ppft->litterme,0.0,1.0,1,CB_NONE,
  550. "Litter moisture flammability threshold (fraction of AWC)");
  551. declareitem("fireresist",&ppft->fireresist,0.0,1.0,1,CB_NONE,
  552. "Fire resistance (0-1)");
  553. declareitem("tcmin_surv",&ppft->tcmin_surv,-1000.0,50.0,1,CB_NONE,
  554. "Min 20-year coldest month mean temp for survival (deg C)");
  555. declareitem("tcmin_est",&ppft->tcmin_est,-1000.0,50.0,1,CB_NONE,
  556. "Min 20-year coldest month mean temp for establishment (deg C)");
  557. declareitem("tcmax_est",&ppft->tcmax_est,-50.0,1000.0,1,CB_NONE,
  558. "Max 20-year coldest month mean temp for establishment (deg C)");
  559. declareitem("twmin_est",&ppft->twmin_est,-1000.0,50.0,1,CB_NONE,
  560. "Min warmest month mean temp for establishment (deg C)");
  561. declareitem("twminusc",&ppft->twminusc,0,100,1,CB_NONE,
  562. "Stupid larch parameter");
  563. declareitem("gdd5min_est",&ppft->gdd5min_est,0.0,5000.0,1,CB_NONE,
  564. "Min GDD on 5 deg C base for establishment");
  565. declareitem("k_chilla",&ppft->k_chilla,0.0,5000.0,1,CB_NONE,
  566. "Constant in equation for budburst chilling time requirement");
  567. declareitem("k_chillb",&ppft->k_chillb,0.0,5000.0,1,CB_NONE,
  568. "Coefficient in equation for budburst chilling time requirement");
  569. declareitem("k_chillk",&ppft->k_chillk,0.0,1.0,1,CB_NONE,
  570. "Exponent in equation for budburst chilling time requirement");
  571. declareitem("parff_min",&ppft->parff_min,0.0,1.0e7,1,CB_NONE,
  572. "Min forest floor PAR for grass growth/tree estab (J/m2/day)");
  573. declareitem("alphar",&ppft->alphar,0.01,100.0,1,CB_NONE,
  574. "Shape parameter for recruitment-juv growth rate relationship");
  575. declareitem("est_max",&ppft->est_max,1.0e-4,1.0,1,CB_NONE,
  576. "Max sapling establishment rate (indiv/m2/year)");
  577. declareitem("kest_repr",&ppft->kest_repr,1.0,1000.0,1,CB_NONE,
  578. "Constant in equation for tree estab rate");
  579. declareitem("kest_bg",&ppft->kest_bg,0.0,1.0,1,CB_NONE,
  580. "Constant in equation for tree estab rate");
  581. declareitem("kest_pres",&ppft->kest_pres,0.0,1.0,1,CB_NONE,
  582. "Constant in equation for tree estab rate");
  583. declareitem("longevity",&ppft->longevity,0.0,3000.0,1,CB_NONE,
  584. "Expected longevity under lifetime non-stressed conditions (yr)");
  585. declareitem("greff_min",&ppft->greff_min,0.0,1.0,1,CB_NONE,
  586. "Threshold for growth suppression mortality (kgC/m2 leaf/yr)");
  587. declareitem("leaflong",&ppft->leaflong,0.1,100.0,1,CB_NONE,
  588. "Leaf longevity (years)");
  589. declareitem("intc",&ppft->intc,0.0,1.0,1,CB_NONE,"Interception coefficient");
  590. // guess2008 - DLE
  591. declareitem("drought_tolerance",&ppft->drought_tolerance,0.0,1.0,1,CB_NONE,
  592. "Drought tolerance level (0 = very -> 1 = not at all) (unitless)");
  593. // bvoc
  594. declareitem("ga",&ppft->ga,0.0,1.0,1,CB_NONE,
  595. "aerodynamic conductance (m/s)");
  596. declareitem("eps_iso",&ppft->eps_iso,0.,100.,1,CB_NONE,
  597. "isoprene emission capacity (ug C g-1 h-1)");
  598. declareitem("seas_iso",&ppft->seas_iso,1,CB_NONE,
  599. "whether (1) or not (0) isoprene emissions show seasonality");
  600. declareitem("eps_mon",ppft->eps_mon,0.,100.,NMTCOMPOUNDS,CB_MTCOMPOUND,
  601. "monoterpene emission capacity (ug C g-1 h-1)");
  602. declareitem("storfrac_mon",ppft->storfrac_mon,0.0,1.0,NMTCOMPOUNDS,CB_MTCOMPOUND,
  603. "fraction of monoterpene production that goes into storage pool (-)");
  604. declareitem("harv_eff",&ppft->harv_eff,0.0,1.0,1,CB_NONE,"Harvest efficiency");
  605. declareitem("harvest_slow_frac",&ppft->harvest_slow_frac,0.0,1.0,1,CB_NONE,
  606. "Fraction of harvested products that goes into carbon depository for long-lived products like wood");
  607. declareitem("turnover_harv_prod",&ppft->turnover_harv_prod,0.0,1.0,1,CB_NONE,"Harvested products turnover (fraction/year)");
  608. declareitem("res_outtake",&ppft->res_outtake,0.0,1.0,1,CB_NONE,"Fraction of residue outtake at harvest");
  609. declareitem("sdatenh",&ppft->sdatenh,1,365,1,CB_NONE,"sowing day northern hemisphere");
  610. declareitem("sdatesh",&ppft->sdatesh,1,365,1,CB_NONE,"sowing day southern hemisphere");
  611. declareitem("lgp_def",&ppft->lgp_def,1,365,1,CB_NONE,"default lgp");
  612. declareitem("sd_adjust",&ppft->sd_adjust,1,CB_NONE,"whether sowing date adjusting equation is used");
  613. declareitem("sd_adjust_par1",&ppft->sd_adjust_par1,1,365,1,CB_NONE,"parameter 1 in sowing date adjusting equation");
  614. declareitem("sd_adjust_par2",&ppft->sd_adjust_par2,1,365,1,CB_NONE,"parameter 2 in sowing date adjusting equation");
  615. declareitem("sd_adjust_par3",&ppft->sd_adjust_par3,1,365,1,CB_NONE,"parameter 3 in sowing date adjusting equation");
  616. declareitem("hlimitdatenh",&ppft->hlimitdatenh,1,365,1,CB_NONE,"last harvest date in the northern hemisphere");
  617. declareitem("hlimitdatesh",&ppft->hlimitdatesh,1,365,1,CB_NONE,"last harvest date in the southern hemisphere");
  618. declareitem("tb",&ppft->tb,0.0,25.0,1,CB_NONE,"base temperature for heat unit calculation");
  619. declareitem("trg",&ppft->trg,0.0,20.0,1,CB_NONE,"upper temperature limit for vernalisation effect");
  620. declareitem("pvd",&ppft->pvd,0,100,1,CB_NONE,"number of vernalising days required");
  621. declareitem("vern_lag",&ppft->vern_lag,0,100,1,CB_NONE,"lag in days after sowing before vernalization starts");
  622. declareitem("isintercropgrass",&ppft->isintercropgrass,1,CB_NONE,"Whether this pft is allowed to grow in intercrop period");
  623. declareitem("psens",&ppft->psens,0.0,1.0,1,CB_NONE,"sensitivity to the photoperiod effect [0-1]");
  624. declareitem("pb",&ppft->pb,0.0,24.0,1,CB_NONE,"basal photoperiod (h)");
  625. declareitem("ps",&ppft->ps,0.0,24.0,1,CB_NONE,"saturating photoperiod (h)");
  626. declareitem("phu",&ppft->phu,0.0,4000.0,1,CB_NONE,"default potential heat units for crop maturity");
  627. declareitem("phu_calc_quad",&ppft->phu_calc_quad,1,CB_NONE,"whether linear equation used for calculating potential heat units (Bondeau method)");
  628. declareitem("phu_calc_lin",&ppft->phu_calc_lin,1,CB_NONE,"minimum potential heat units required for crop maturity (Bondeau method) (degree-days)");
  629. declareitem("phu_min",&ppft->phu_min,0.0,4000.0,1,CB_NONE,"minimum potential heat units for crop maturity (Bondeau method)");
  630. declareitem("phu_max",&ppft->phu_max,0.0,4000.0,1,CB_NONE,"maximum potential heat units for crop maturity (Bondeau method)");
  631. declareitem("phu_red_spring_sow",&ppft->phu_red_spring_sow,0.0,1.0,1,CB_NONE,"reduction factor of potential heat units in spring crops (Bondeau method)");
  632. declareitem("phu_interc",&ppft->phu_interc,0.0,4000.0,1,CB_NONE,"intercept for the linear phu equation (Bondeau method)");
  633. declareitem("ndays_ramp_phu",&ppft->ndays_ramp_phu,0.0,365.0,1,CB_NONE,"number of days of phu decrease in the linear phu equation (Bondeau method)");
  634. declareitem("fphusen",&ppft->fphusen,0.0,1.0,1,CB_NONE,"growing season fract. when lai starts decreasing");
  635. declareitem("shapesenescencenorm",&ppft->shapesenescencenorm,1,CB_NONE,"Type of senescence curve");
  636. declareitem("flaimaxharvest",&ppft->flaimaxharvest,0.0,1.0,1,CB_NONE,"Fraction of maximum lai when harvest prescribed");
  637. declareitem("aboveground_ho",&ppft->aboveground_ho,1,CB_NONE,"Whether aboveground structures are harvested");
  638. declareitem("harv_eff_ic",&ppft->harv_eff_ic,0.0,1.0,1,CB_NONE,"Harvest efficiency of covercrop grass");
  639. declareitem("ifsdautumn",&ppft->ifsdautumn,1,CB_NONE,"Whether sowing date in autumn is to be calculated");
  640. declareitem("tempautumn",&ppft->tempautumn,0.0,25.0,1,CB_NONE,"Upper temperature limit for winter sowing");
  641. declareitem("tempspring",&ppft->tempspring,0.0,25.0,1,CB_NONE,"Lower temperature limt for spring sowing");
  642. declareitem("maxtemp_sowing",&ppft->maxtemp_sowing,0.0,60.0,1,CB_NONE,"Upper minimum temperature limit for crop sowing");
  643. declareitem("hiopt",&ppft->hiopt,0.0,2.0,1,CB_NONE,"Optimal harvest index");
  644. declareitem("himin",&ppft->himin,0.0,2.0,1,CB_NONE,"Minimal harvest index");
  645. declareitem("frootstart",&ppft->frootstart,0.0,1.0,1,CB_NONE,"Initial root mass fraction of total plant");
  646. declareitem("frootend",&ppft->frootend,0.0,1.0,1,CB_NONE,"Root mass fraction of total plant at harvest");
  647. declareitem("laimax",&ppft->laimax,0.0,10.0,1,CB_NONE,"Maximum lai (crop grass only)");
  648. declareitem("forceautumnsowing",&ppft->forceautumnsowing,0,2,1,CB_NONE,"Whether autumn sowing is forced independent of climate");
  649. declareitem("fertdates",ppft->fertdates,0,365,2,CB_NONE,
  650. "Fertilisation dates, relative to sowing");
  651. declareitem("fertrate",ppft->fertrate,0.0,1.0,2,CB_NONE,
  652. "Fraction of total fertilisation at fertilisation event");
  653. declareitem("N_appfert",&ppft->N_appfert,0.0,300.0,1,CB_NONE,
  654. "Fertilisation rate");
  655. declareitem("T_vn_min",&ppft->T_vn_min,-1000.0,1000.0,1,CB_NONE,
  656. "Min temperature for vernalization");
  657. declareitem("T_vn_opt",&ppft->T_vn_opt,-1000.0,1000.0,1,CB_NONE,
  658. "Opt temperature for vernalization");
  659. declareitem("T_vn_max",&ppft->T_vn_max,-1000.0,1000.0,1,CB_NONE,
  660. "Max temperature for vernalization");
  661. declareitem("T_veg_min",&ppft->T_veg_min,-1000.0,1000.0,1,CB_NONE,
  662. "Min temperature for the vegetative phase");
  663. declareitem("T_veg_opt",&ppft->T_veg_opt,-1000.0,1000.0,1,CB_NONE,
  664. "Opt temperature for the vegetative phase");
  665. declareitem("T_veg_max",&ppft->T_veg_max,-1000.0,1000.0,1,CB_NONE,
  666. "Max temperature for the vegetative phase");
  667. declareitem("T_rep_min",&ppft->T_rep_min,-1000.0,1000.0,1,CB_NONE,
  668. "Min temperature for the reproductive phase");
  669. declareitem("T_rep_opt",&ppft->T_rep_opt,-1000.0,1000.0,1,CB_NONE,
  670. "Opt temperature for the reproductive phase");
  671. declareitem("T_rep_max",&ppft->T_rep_max,-1000.0,1000.0,1,CB_NONE,
  672. "Max temperature for the reproductive phase");
  673. declareitem("photo",ppft->photo,-1000.0,1000.0,3,CB_NONE,
  674. "Parameters for photoperiod");
  675. declareitem("dev_rate_veg",&ppft->dev_rate_veg,-1000.0,1000.0,1,CB_NONE,
  676. "Maximal vegetative develoment rate");
  677. declareitem("dev_rate_rep",&ppft->dev_rate_rep,-1000.0,1000.0,1,CB_NONE,
  678. "Maximal reproductive develoment rate");
  679. declareitem("a1",&ppft->a1,-1000.0,1000.0,1,CB_NONE,
  680. "a1 parameter for allocation with N stress");
  681. declareitem("b1",&ppft->b1,-1000.0,1000.0,1,CB_NONE,
  682. "b1 parameter for allocation with N stress");
  683. declareitem("c1",&ppft->c1,-1000.0,1000.0,1,CB_NONE,
  684. "c1 parameter for allocation with N stress");
  685. declareitem("d1",&ppft->d1,-1000.0,1000.0,1,CB_NONE,
  686. "d1 parameter for allocation with N stress");
  687. declareitem("a2",&ppft->a2,-1000.0,1000.0,1,CB_NONE,
  688. "a2 parameter for allocation with N stress");
  689. declareitem("b2",&ppft->b2,-1000.0,1000.0,1,CB_NONE,
  690. "b2 parameter for allocation with N stress");
  691. declareitem("c2",&ppft->c2,-1000.0,1000.0,1,CB_NONE,
  692. "c2 parameter for allocation with N stress");
  693. declareitem("d2",&ppft->d2,-1000.0,1000.0,1,CB_NONE,
  694. "d2 parameter for allocation with N stress");
  695. declareitem("a3",&ppft->a3,-1000.0,1000.0,1,CB_NONE,
  696. "a3 parameter for allocation with N stress");
  697. declareitem("b3",&ppft->b3,-1000.0,1000.0,1,CB_NONE,
  698. "b3 parameter for allocation with N stress");
  699. declareitem("c3",&ppft->c3,-1000.0,1000.0,1,CB_NONE,
  700. "c3 parameter for allocation with N stress");
  701. declareitem("d3",&ppft->d3,-1000.0,1000.0,1,CB_NONE,
  702. "d3 parameter for allocation with N stress");
  703. callwhendone(CB_CHECKPFT);
  704. break;
  705. case BLOCK_MT:
  706. if (!ifhelp) {
  707. pmt = 0;
  708. // Was this mt already created?
  709. for (size_t p = 0; p < mtlist.nobj; ++p) {
  710. if (mtlist[(unsigned int)p].name == setname) {
  711. pmt = &mtlist[(unsigned int)p];
  712. }
  713. }
  714. if (pmt == 0) {
  715. // Create and initialise a new st object and obtain a reference to it
  716. pmt=&mtlist.createobj();
  717. initmt(*pmt,setname);
  718. includemt_map[setname] = true;
  719. }
  720. }
  721. declareitem("mtinclude",&includemt,1,CB_NONE,"Include ManagementType in analysis");
  722. declareitem("planting_system",&strparam,32,CB_MTPLANTINGSYSTEM,"Planting system");
  723. declareitem("harvest_system",&strparam,32,CB_MTHARVESTSYSTEM,"Harvest system");
  724. declareitem("pft",&strparam,16,CB_MTPFT,"PFT name");
  725. declareitem("selection",&strparam,200,CB_MTSELECTION ,"String of pft names");
  726. declareitem("rottime",&pmt->nyears,0.0,100.0,1,CB_NONE,"Rotation time (years)");
  727. declareitem("hydrology",&strparam,16,CB_MTHYDROLOGY, "Hydrology of crop (\"RAINFED\" or \"IRRIGATED\")");
  728. // declareitem("irrigation",&pmt->firr,0.0,1.0,1,CB_NONE,"Irrigation of crop");
  729. declareitem("sdate",&pmt->sdate,0,364,1,CB_NONE,"Sowing date of crop");
  730. declareitem("hdate",&pmt->hdate,0,364,1,CB_NONE,"Harvest date of crop");
  731. declareitem("nfert",&pmt->nfert,0.0,1000.0,1,CB_NONE,"Fertilization application of crop");
  732. declareitem("fallow",&pmt->fallow,1,CB_NONE,"Fallow in place of crop");
  733. declareitem("multicrop",&pmt->multicrop,1,CB_NONE,"Whether to grow several crops in a year");
  734. callwhendone(CB_CHECKMT);
  735. break;
  736. case BLOCK_ST:
  737. if (!ifhelp) {
  738. pst = 0;
  739. // Was this st already created?
  740. for (size_t p = 0; p < stlist.nobj; ++p) {
  741. if (stlist[(unsigned int)p].name == setname) {
  742. pst = &stlist[(unsigned int)p];
  743. }
  744. }
  745. if (pst == 0) {
  746. // Create and initialise a new st object and obtain a reference to it
  747. pst=&stlist.createobj();
  748. initst(*pst,setname);
  749. includest_map[setname] = true;
  750. }
  751. }
  752. declareitem("stinclude",&includest,1,CB_NONE,"Include StandType in analysis");
  753. declareitem("landcover",&strparam,16,CB_STLANDCOVER,
  754. "Landcovertype (\"URBAN\", \"CROP\", \"PASTURE\", \"FOREST\", \"NATURAL\", \"PEATLAND\" or \"BARREN\")");
  755. declareitem("intercrop",&strparam,16,CB_STINTERCROP,
  756. "Cover crop (\"NOINTERCROP\" or \"NATURALGRASS\")");
  757. declareitem("naturalveg",&strparam,16,CB_STNATURALVEG,
  758. "Natural pfts (\"NONE\", \"GRASSONLY\" or \"ALL\")");
  759. declareitem("reestab",&strparam,16,CB_STREESTAB,
  760. "Re-establishment (\"NONE\", \"RESTRICTED\" or \"ALL\")");
  761. declareitem("firstrotyear",&pst->rotation.firstrotyear,0,3000,1,CB_NONE,"First calender year of rotation");
  762. declareitem("restrictpfts",&pst->restrictpfts,1,CB_NONE,"Whether to only allow pft:s specified in stand type");
  763. declareitem("firstmanageyear",&pst->firstmanageyear,0,3000,1,CB_NONE,"First calender year of management");
  764. for(int i = 0; i < NROTATIONPERIODS_MAX; ++i) {
  765. if(i == 0) {
  766. declareitem("management1",&strparam,16,CB_MANAGEMENT1,"");
  767. declareitem("planting_system",&strparam,32,CB_PLANTINGSYSTEM,"Planting system of management 1");
  768. declareitem("harvest_system",&strparam,32,CB_HARVESTSYSTEM,"Harvest system of management 1");
  769. declareitem("pft",&strparam,16,CB_PFT,"PFT name");
  770. declareitem("selection",&strparam,200,CB_STSELECTION,"String of pft names");
  771. declareitem("rottime",&pst->management.nyears,0.0,100.0,1,CB_NONE,"Rotation time (years)");
  772. declareitem("hydrology",&strparam,16,CB_STHYDROLOGY, "Hydrology of crop 1 (\"RAINFED\" or \"IRRIGATED\")");
  773. // declareitem("irrigation",&pst->management.firr,0.0,1.0,1,CB_NONE,"Irrigation of crop 1");
  774. declareitem("sdate",&pst->management.sdate,0,364,1,CB_NONE,"Sowing date of crop 1");
  775. declareitem("hdate",&pst->management.hdate,0,364,1,CB_NONE,"Harvest date of crop 1");
  776. declareitem("nfert",&pst->management.nfert,0.0,1000.0,1,CB_NONE,"Fertilization application of crop 1");
  777. declareitem("fallow",&pst->management.fallow,1,CB_NONE,"Fallow in place of crop 1");
  778. declareitem("multicrop",&pst->management.multicrop,1,CB_NONE,"Whether to grow several crops in a year in management 1");
  779. }
  780. else if(i == 1) {
  781. declareitem("management2",&strparam,16,CB_MANAGEMENT2,"");
  782. }
  783. else if(i == 2) {
  784. declareitem("management3",&strparam,16,CB_MANAGEMENT3,"");
  785. }
  786. }
  787. callwhendone(CB_CHECKST);
  788. break;
  789. case BLOCK_PARAM:
  790. paramname=setname;
  791. declareitem("str",&strparam,300,CB_STRPARAM,
  792. "String value for custom parameter");
  793. declareitem("num",&numparam,-1.0e38,1.0e38,1,CB_NUMPARAM,
  794. "Numerical value for custom parameter");
  795. break;
  796. }
  797. }
  798. void badins(xtring missing) {
  799. xtring message=(xtring)"Missing mandatory setting: "+missing;
  800. sendmessage("Error",message);
  801. plibabort();
  802. }
  803. void plib_callback(int callback) {
  804. xtring message;
  805. int i;
  806. double numval;
  807. switch (callback) {
  808. case CB_VEGMODE:
  809. if (strparam.upper()=="INDIVIDUAL") vegmode=INDIVIDUAL;
  810. else if (strparam.upper()=="COHORT") vegmode=COHORT;
  811. else if (strparam.upper()=="POPULATION") vegmode=POPULATION;
  812. else {
  813. sendmessage("Error",
  814. "Unknown vegetation mode (valid types: \"INDIVIDUAL\",\"COHORT\", \"POPULATION\")");
  815. plibabort();
  816. }
  817. break;
  818. case CB_WATERUPTAKE:
  819. if (strparam.upper() == "WCONT") wateruptake = WR_WCONT;
  820. else if (strparam.upper() == "ROOTDIST") wateruptake = WR_ROOTDIST;
  821. else if (strparam.upper() == "SMART") wateruptake = WR_SMART;
  822. else if (strparam.upper() == "SPECIESSPECIFIC") wateruptake = WR_SPECIESSPECIFIC;
  823. else {
  824. sendmessage("Error",
  825. "Unknown water uptake mode (valid types: \"WCONT\", \"ROOTDIST\", \"SMART\", \"SPECIESSPECIFIC\")");
  826. }
  827. break;
  828. case CB_LIFEFORM:
  829. if (strparam.upper()=="TREE") ppft->lifeform=TREE;
  830. else if (strparam.upper()=="GRASS") ppft->lifeform=GRASS;
  831. else {
  832. sendmessage("Error",
  833. "Unknown lifeform type (valid types: \"TREE\", \"GRASS\")");
  834. plibabort();
  835. }
  836. break;
  837. case CB_LANDCOVER:
  838. if (strparam.upper()=="NATURAL") ppft->landcover=NATURAL;
  839. else if (strparam.upper()=="URBAN") ppft->landcover=URBAN;
  840. else if (strparam.upper()=="CROPLAND") ppft->landcover=CROPLAND;
  841. else if (strparam.upper()=="PASTURE") ppft->landcover=PASTURE;
  842. else if (strparam.upper()=="FOREST") ppft->landcover=FOREST;
  843. else if (strparam.upper()=="PEATLAND") ppft->landcover=PEATLAND;
  844. else if (strparam.upper()=="BARREN") ppft->landcover=BARREN;
  845. else {
  846. sendmessage("Error",
  847. "Unknown landcover type (valid types: \"URBAN\", \"CROPLAND\", \"PASTURE\", \"FOREST\", \"NATURAL\", \"PEATLAND\" or \"BARREN\")");
  848. plibabort();
  849. }
  850. break;
  851. case CB_SELECTION:
  852. ppft->selection = strparam;
  853. break;
  854. case CB_STLANDCOVER:
  855. if (strparam.upper()=="NATURAL") pst->landcover=NATURAL;
  856. else if (strparam.upper()=="URBAN") pst->landcover=URBAN;
  857. else if (strparam.upper()=="CROPLAND") pst->landcover=CROPLAND;
  858. else if (strparam.upper()=="PASTURE") pst->landcover=PASTURE;
  859. else if (strparam.upper()=="FOREST") pst->landcover=FOREST;
  860. else if (strparam.upper()=="PEATLAND") pst->landcover=PEATLAND;
  861. else if (strparam.upper()=="BARREN") pst->landcover=BARREN;
  862. else {
  863. sendmessage("Error",
  864. "Unknown landcover type (valid types: \"URBAN\", \"CROPLAND\", \"PASTURE\", \"FOREST\", \"NATURAL\", \"PEATLAND\" or \"BARREN\")");
  865. plibabort();
  866. }
  867. break;
  868. case CB_STINTERCROP:
  869. if (strparam.upper()=="NOINTERCROP") pst->intercrop=NOINTERCROP;
  870. else if (strparam.upper()=="NATURALGRASS") pst->intercrop=NATURALGRASS;
  871. else {
  872. sendmessage("Error",
  873. "Unknown intercrop type (valid types: \"NOINTERCROP\", \"NATURALGRASS\")");
  874. plibabort();
  875. }
  876. break;
  877. case CB_STNATURALVEG:
  878. pst->naturalveg = strparam.upper();
  879. break;
  880. case CB_STREESTAB:
  881. pst->reestab = strparam.upper();
  882. break;
  883. case CB_MTPLANTINGSYSTEM:
  884. pmt->planting_system = strparam.upper();
  885. break;
  886. case CB_MTHARVESTSYSTEM:
  887. pmt->harvest_system = strparam.upper();
  888. break;
  889. case CB_MTPFT:
  890. pmt->pftname = strparam;
  891. break;
  892. case CB_MTSELECTION:
  893. pmt->selection = strparam;
  894. break;
  895. case CB_MTHYDROLOGY:
  896. if (strparam.upper()=="RAINFED") pmt->hydrology = RAINFED;
  897. else if (strparam.upper()=="IRRIGATED") pmt->hydrology = IRRIGATED;
  898. else
  899. {
  900. sendmessage("Error",
  901. "Unknown hydrology type (valid types: \"RAINFED\", \"IRRIGATED\")");
  902. plibabort();
  903. }
  904. break;
  905. case CB_MANAGEMENT1:
  906. pst->mtnames[0] = strparam;
  907. break;
  908. case CB_MANAGEMENT2:
  909. pst->mtnames[1] = strparam;
  910. break;
  911. case CB_MANAGEMENT3:
  912. pst->mtnames[2] = strparam;
  913. break;
  914. case CB_PLANTINGSYSTEM:
  915. pst->management.planting_system = strparam.upper();
  916. break;
  917. case CB_HARVESTSYSTEM:
  918. pst->management.harvest_system = strparam.upper();
  919. break;
  920. case CB_PFT:
  921. pst->management.pftname = strparam;
  922. break;
  923. case CB_STSELECTION:
  924. pst->management.selection = strparam;
  925. break;
  926. case CB_STHYDROLOGY:
  927. if (strparam.upper()=="RAINFED") pst->management.hydrology = RAINFED;
  928. else if (strparam.upper()=="IRRIGATED") pst->management.hydrology = IRRIGATED;
  929. else
  930. {
  931. sendmessage("Error",
  932. "Unknown hydrology type (valid types: \"RAINFED\", \"IRRIGATED\")");
  933. plibabort();
  934. }
  935. break;
  936. case CB_PHENOLOGY:
  937. if (strparam.upper()=="SUMMERGREEN") ppft->phenology=SUMMERGREEN;
  938. else if (strparam.upper()=="RAINGREEN") ppft->phenology=RAINGREEN;
  939. else if (strparam.upper()=="EVERGREEN") ppft->phenology=EVERGREEN;
  940. else if (strparam.upper()=="CROPGREEN") ppft->phenology=CROPGREEN;
  941. else if (strparam.upper()=="ANY") ppft->phenology=ANY;
  942. else {
  943. sendmessage("Error",
  944. "Unknown phenology type\n (valid types: \"EVERGREEN\", \"SUMMERGREEN\", \"RAINGREEN\", \"CROPGREEN\" or \"ANY\")");
  945. plibabort();
  946. }
  947. break;
  948. case CB_LEAFPHYSIOGNOMY:
  949. if (strparam.upper()=="NEEDLELEAF") ppft->leafphysiognomy=NEEDLELEAF;
  950. else if (strparam.upper()=="BROADLEAF") ppft->leafphysiognomy=BROADLEAF;
  951. else {
  952. sendmessage("Error",
  953. "Unknown leaf physiognomy (valid types: \"NEEDLELEAF\", \"BROADLEAF\")");
  954. plibabort();
  955. }
  956. break;
  957. case CB_PATHWAY:
  958. if (strparam.upper()=="C3") ppft->pathway=C3;
  959. else if (strparam.upper()=="C4") ppft->pathway=C4;
  960. else {
  961. sendmessage("Error",
  962. "Unknown pathway type\n (valid types: \"C3\" or \"C4\")");
  963. plibabort();
  964. }
  965. break;
  966. case CB_ROOTDIST:
  967. numval=0.0;
  968. for (i=0;i<NSOILLAYER;i++) numval+=ppft->rootdist[i];
  969. if (numval<0.99 || numval>1.01) {
  970. sendmessage("Error","Specified root fractions do not sum to 1.0");
  971. plibabort();
  972. }
  973. ppft->rootdist[NSOILLAYER-1]+=1.0-numval;
  974. break;
  975. case CB_MTCOMPOUND:
  976. // bvoc. Can include some checks for the monoterpene parameters given per compound
  977. break;
  978. case CB_STRPARAM:
  979. param.addparam(paramname,strparam);
  980. break;
  981. case CB_NUMPARAM:
  982. param.addparam(paramname,numparam);
  983. break;
  984. case CB_CHECKGLOBAL:
  985. if (!itemparsed("title")) badins("title");
  986. if (!itemparsed("nyear_spinup")) badins("nyear_spinup");
  987. if (!itemparsed("vegmode")) badins("vegmode");
  988. if (!itemparsed("iffire")) badins("iffire");
  989. if (!itemparsed("ifcalcsla")) badins("ifcalcsla");
  990. if (!itemparsed("ifcalccton")) badins("ifcalccton");
  991. if (!itemparsed("ifcdebt")) badins("ifcdebt");
  992. if (!itemparsed("wateruptake")) badins("wateruptake");
  993. if (!itemparsed("nrelocfrac")) badins("nrelocfrac");
  994. if (!itemparsed("nfix_a")) badins("nfix_a");
  995. if (!itemparsed("nfix_b")) badins("nfix_b");
  996. if (!itemparsed("ifcentury")) badins("ifcentury");
  997. if (!itemparsed("ifnlim")) badins("ifnlim");
  998. if (!itemparsed("freenyears")) badins("freenyears");
  999. if (nyear_spinup <= freenyears) {
  1000. sendmessage("Error", "freenyears must be smaller than nyear_spinup");
  1001. plibabort();
  1002. }
  1003. if (!itemparsed("outputdirectory")) badins("outputdirectory");
  1004. if (!itemparsed("ifsmoothgreffmort")) badins("ifsmoothgreffmort");
  1005. if (!itemparsed("ifdroughtlimitedestab")) badins("ifdroughtlimitedestab");
  1006. if (!itemparsed("ifrainonwetdaysonly")) badins("ifrainonwetdaysonly");
  1007. if (!itemparsed("deforest_method_type")) badins("deforest_method_type");
  1008. if (!itemparsed("deforest_start_year")) badins("deforest_start_year");
  1009. if (!itemparsed("deforest_end_year")) badins("deforest_end_year");
  1010. // bvoc
  1011. if (!itemparsed("ifbvoc")) badins("ifbvoc");
  1012. if (!itemparsed("run_landcover")) badins("run_landcover");
  1013. if (run_landcover) {
  1014. if (!itemparsed("npatch_secondarystand")) badins("npatch_secondarystand");
  1015. if (!itemparsed("reduce_all_stands")) badins("reduce_all_stands");
  1016. if (!itemparsed("age_limit_reduce")) badins("age_limit_reduce");
  1017. if (!itemparsed("minimizecftlist")) badins("minimizecftlist");
  1018. if (!itemparsed("run_natural")) badins("run_natural");
  1019. if (!itemparsed("run_crop")) badins("run_crop");
  1020. if (!itemparsed("run_forest")) badins("run_forest");
  1021. if (!itemparsed("run_urban")) badins("run_urban");
  1022. if (!itemparsed("run_pasture")) badins("run_pasture");
  1023. if (!itemparsed("run_barren")) badins("run_barren");
  1024. if (!itemparsed("ifslowharvestpool")) badins("ifslowharvestpool");
  1025. if (!itemparsed("ifintercropgrass")) badins("ifintercropgrass");
  1026. if (!itemparsed("ifcalcdynamic_phu")) badins("ifcalcdynamic_phu");
  1027. if (!itemparsed("gross_land_transfer")) badins("gross_land_transfer");
  1028. if (!itemparsed("ifprimary_lc_transfer")) badins("ifprimary_lc_transfer");
  1029. if (!itemparsed("ifprimary_to_secondary_transfer")) badins("ifprimary_to_secondary_transfer");
  1030. if (!itemparsed("harvest_secondary_to_new_stand")) badins("harvest_secondary_to_new_stand");
  1031. if (!itemparsed("transfer_level")) badins("transfer_level");
  1032. if (!itemparsed("ifdyn_phu_limit")) badins("ifdyn_phu_limit");
  1033. if (!itemparsed("iftransfer_to_new_stand")) badins("iftransfer_to_new_stand");
  1034. if (!itemparsed("nyear_dyn_phu")) badins("nyear_dyn_phu");
  1035. if (!itemparsed("printseparatestands")) badins("printseparatestands");
  1036. if (!itemparsed("printcrescendo")) badins("printcrescendo");
  1037. if (!itemparsed("printcrescendodaily")) badins("printcrescendodaily");
  1038. if (!itemparsed("printcrescendofacedaily")) badins("printcrescendofacedaily");
  1039. if (!itemparsed("printcmip6")) badins("printcmip6");
  1040. if (!itemparsed("printcmip6daily")) badins("printcmip6daily");
  1041. if (!itemparsed("printifsinputdaily")) badins("printifsinputdaily");
  1042. if (!itemparsed("iftillage")) badins("iftillage");
  1043. }
  1044. if (!itemparsed("pft")) badins("pft");
  1045. if (vegmode==COHORT || vegmode==INDIVIDUAL) {
  1046. if (!itemparsed("ifbgestab")) badins("ifbgestab");
  1047. if (!itemparsed("ifsme")) badins("ifsme");
  1048. if (!itemparsed("ifstochmort")) badins("ifstochmort");
  1049. if (!itemparsed("ifstochestab")) badins("ifstochestab");
  1050. if (itemparsed("ifdisturb") && !itemparsed("distinterval"))
  1051. badins("distinterval");
  1052. if (!itemparsed("npatch")) badins("npatch");
  1053. if (!itemparsed("patcharea")) badins("patcharea");
  1054. if (!itemparsed("estinterval")) badins("estinterval");
  1055. }
  1056. else if (vegmode==POPULATION && npatch!=1) {
  1057. sendmessage("Information",
  1058. "Value specified for npatch ignored in population mode");
  1059. npatch=1;
  1060. }
  1061. if (save_state && restart) {
  1062. sendmessage("Error",
  1063. "Can't save state and restart at the same time");
  1064. plibabort();
  1065. }
  1066. if (!itemparsed("state_year")) {
  1067. state_year = nyear_spinup;
  1068. }
  1069. if (state_path == "" && (save_state || restart)) {
  1070. badins("state_path");
  1071. }
  1072. if (grassforcrop) {
  1073. run[CROPLAND] = 0;
  1074. run[PASTURE] = 1;
  1075. }
  1076. if (!run_landcover)
  1077. printseparatestands = false;
  1078. // delete unused management types from mtlist
  1079. mtlist.firstobj();
  1080. while (mtlist.isobj) {
  1081. ManagementType& mt = mtlist.getobj();
  1082. bool include = includemt_map[mt.name];
  1083. if (!include) {
  1084. // Remove this management type from list
  1085. mtlist.killobj();
  1086. }
  1087. else {
  1088. mtlist.nextobj();
  1089. }
  1090. }
  1091. // delete unused stand types from stlist
  1092. stlist.firstobj();
  1093. while (stlist.isobj) {
  1094. StandType& st = stlist.getobj();
  1095. bool include = includest_map[st.name];
  1096. if (st.landcover != NATURAL) {
  1097. if (!run_landcover || !run[st.landcover])
  1098. include = false;
  1099. }
  1100. else if (run_landcover && !run[NATURAL]) {
  1101. if (st.landcover == NATURAL)
  1102. include = false;
  1103. }
  1104. if (!include) {
  1105. // Remove this stand type from list
  1106. stlist.killobj();
  1107. }
  1108. else {
  1109. stlist.nextobj();
  1110. }
  1111. }
  1112. // delete unused pft:s from pftlist
  1113. // first check if natural pft:s are included in other land cover stand types
  1114. bool include_natural_pfts;
  1115. bool include_natural_grass_pfts;
  1116. if(run_landcover && !run[NATURAL]) {
  1117. include_natural_pfts = false;
  1118. include_natural_grass_pfts = false;
  1119. stlist.firstobj();
  1120. while(stlist.isobj) {
  1121. StandType& st = stlist.getobj();
  1122. if(st.naturalveg == "ALL") {
  1123. include_natural_pfts = true;
  1124. include_natural_grass_pfts = true;
  1125. break;
  1126. }
  1127. if(st.naturalveg == "GRASSONLY")
  1128. include_natural_grass_pfts = true;
  1129. stlist.nextobj();
  1130. }
  1131. }
  1132. else {
  1133. include_natural_pfts = true;
  1134. include_natural_grass_pfts = true;
  1135. }
  1136. pftlist.firstobj();
  1137. while (pftlist.isobj) {
  1138. Pft& pft = pftlist.getobj();
  1139. bool include = includepft_map[pft.name];
  1140. if(pft.landcover == NATURAL) {
  1141. if(!include_natural_grass_pfts && pft.lifeform == GRASS)
  1142. include = false;
  1143. else if(!include_natural_pfts && pft.lifeform != GRASS)
  1144. include = false;
  1145. }
  1146. else {
  1147. if (!run_landcover || !run[pft.landcover])
  1148. include = false;
  1149. }
  1150. if (!include) {
  1151. // Remove this PFT from list
  1152. pftlist.killobj();
  1153. }
  1154. else {
  1155. pftlist.nextobj();
  1156. }
  1157. }
  1158. /// Set ncrops and verify that crop rotations have defined pftnames
  1159. stlist.firstobj();
  1160. while (stlist.isobj) {
  1161. StandType& st = stlist.getobj();
  1162. // management types in ins-file overrides management settings in stand type
  1163. if(st.mtnames[0] != "") {
  1164. for(int rot=0; rot<NROTATIONPERIODS_MAX; rot++) {
  1165. if(st.mtnames[rot] != "") {
  1166. st.rotation.ncrops++;
  1167. if(rot == 0) {
  1168. int mtid = mtlist.getmtid(st.mtnames[rot]);
  1169. if(mtid > -1) {
  1170. ManagementType& mt = mtlist[mtid];
  1171. // Copy management from mtlist to stand type management, used only if ncrops=1
  1172. st.management = mt;
  1173. }
  1174. }
  1175. }
  1176. else {
  1177. break;
  1178. }
  1179. }
  1180. }
  1181. if(!st.rotation.ncrops) {
  1182. // Check if there are management settings in the stand type definition
  1183. if(st.management.is_managed())
  1184. st.rotation.ncrops = 1;
  1185. }
  1186. if(st.landcover == CROPLAND &&
  1187. (st.rotation.ncrops == 0 ||
  1188. st.rotation.ncrops >= 1 && st.get_management(0).pftname == "" && !st.get_management(0).fallow ||
  1189. st.rotation.ncrops >= 2 && st.get_management(1).pftname == "" && !st.get_management(1).fallow ||
  1190. st.rotation.ncrops >= 3 && st.get_management(2).pftname == "" && !st.get_management(2).fallow))
  1191. fail("Check stand type rotation parameter setting, pftname missing\n");
  1192. stlist.nextobj();
  1193. }
  1194. // Remove crop st:s with pft:s that are not found in the pftlist or with mt:s that are not in the mtlist
  1195. dprintf("\n");
  1196. stlist.firstobj();
  1197. while (stlist.isobj) {
  1198. StandType& st = stlist.getobj();
  1199. bool include = true;
  1200. if(st.landcover == CROPLAND) { // Should check this for other land covers too, forest monocultures can have a pftname
  1201. for(int i=0; i<st.rotation.ncrops; i++) {
  1202. if(st.mtnames[i] != "" && mtlist.getmtid(st.mtnames[i]) < 0) {
  1203. include = false;
  1204. dprintf("Stand type %s not used; mt %s not in mtlist !\n", (char*)st.name, (char*)st.mtnames[i]);
  1205. }
  1206. if(st.get_management(i).pftname != "" && pftlist.getpftid(st.get_management(i).pftname) < 0) {
  1207. include = false;
  1208. dprintf("Stand type %s not used; pft %s not in pftlist !\n", (char*)st.name, (char*)st.get_management(i).pftname);
  1209. }
  1210. }
  1211. }
  1212. if (!include) {
  1213. // Remove this stand type from list
  1214. stlist.killobj();
  1215. }
  1216. else {
  1217. stlist.nextobj();
  1218. }
  1219. }
  1220. dprintf("\n");
  1221. // Set ids and npft variable after removing unused pfts ; NB: minimizecftlist may remove more pfts
  1222. npft = 0;
  1223. pftlist.firstobj();
  1224. while (pftlist.isobj) {
  1225. Pft& pft = pftlist.getobj();
  1226. pft.id = npft++;
  1227. pftlist.nextobj();
  1228. }
  1229. // Set ids and nmt variable after removing unused mts
  1230. nmt = 0;
  1231. mtlist.firstobj();
  1232. while (mtlist.isobj) {
  1233. ManagementType& mt = mtlist.getobj();
  1234. mt.id = nmt++;
  1235. mtlist.nextobj();
  1236. }
  1237. // Set ids and nst variable after removing unused sts
  1238. nst = 0;
  1239. for(int i=0;i<NLANDCOVERTYPES;i++)
  1240. nst_lc[i] = 0;
  1241. stlist.firstobj();
  1242. while (stlist.isobj) {
  1243. StandType& st = stlist.getobj();
  1244. st.id = nst++;
  1245. nst_lc[st.landcover]++;
  1246. stlist.nextobj();
  1247. }
  1248. stlist.firstobj();
  1249. while (stlist.isobj) {
  1250. StandType& st = stlist.getobj();
  1251. if(st.intercrop == NATURALGRASS && pftlist[pftlist.getpftid(st.get_management(0).pftname)].phenology != CROPGREEN)
  1252. dprintf("Warning: covercrop grass should not be activated in stand types without true crops\n");
  1253. stlist.nextobj();
  1254. }
  1255. // Check that stand type exists for all active land covers when run_landcover==true.
  1256. if(run_landcover) {
  1257. for(int lc=0; lc<NLANDCOVERTYPES;lc++) {
  1258. if(run[lc] && nst_lc[lc] == 0)
  1259. fail("All active land covers must have at least one stand type in instruction file when run_landcover is true.");
  1260. }
  1261. }
  1262. // Call various init functions on each PFT now that all settings have been read
  1263. pftlist.firstobj();
  1264. while (pftlist.isobj) {
  1265. ppft = &pftlist.getobj();
  1266. if (ifcalcsla) {
  1267. if(!(ppft->phenology == CROPGREEN && run_landcover && ifnlim))
  1268. // Calculate SLA
  1269. ppft->initsla();
  1270. }
  1271. if (ifcalccton) {
  1272. if(!(ppft->phenology == CROPGREEN && run_landcover && ifnlim))
  1273. // Calculate leaf C:N ratio minimum
  1274. ppft->init_cton_min();
  1275. }
  1276. // Calculate C:N ratio limits
  1277. ppft->init_cton_limits();
  1278. // Calculate nitrogen uptake strength dependency on root distribution
  1279. ppft->init_nupscoeff();
  1280. // Calculate regeneration characteristics for population mode
  1281. ppft->initregen();
  1282. pftlist.nextobj();
  1283. }
  1284. break;
  1285. case CB_CHECKPFT:
  1286. if (!checked_pft[ppft->name]) {
  1287. checked_pft[ppft->name] = true;
  1288. if (!itemparsed("lifeform")) badins("lifeform");
  1289. if (!itemparsed("phenology")) badins("phenology");
  1290. if (ppft->phenology==SUMMERGREEN || ppft->phenology==ANY)
  1291. if (!itemparsed("phengdd5ramp")) badins("phengdd5ramp");
  1292. if (ppft->phenology==RAINGREEN || ppft->phenology==ANY)
  1293. if (!itemparsed("wscal_min")) badins("wscal_min");
  1294. if (!itemparsed("leafphysiognomy")) badins("leafphysiognomy");
  1295. if (!itemparsed("pathway")) badins("pathway");
  1296. if (!itemparsed("pstemp_min")) badins("pstemp_min");
  1297. if (!itemparsed("pstemp_low")) badins("pstemp_low");
  1298. if (!itemparsed("pstemp_high")) badins("pstemp_high");
  1299. if (!itemparsed("pstemp_max")) badins("pstemp_max");
  1300. if (!itemparsed("lambda_max")) badins("lambda_max");
  1301. if (!itemparsed("rootdist")) badins("rootdist");
  1302. if (!itemparsed("gmin")) badins("gmin");
  1303. if (!itemparsed("emax")) badins("emax");
  1304. if (!itemparsed("respcoeff")) badins("respcoeff");
  1305. if (!ifcalcsla || (ppft->phenology == CROPGREEN && run_landcover && ifnlim))
  1306. if (!itemparsed("sla")) badins("sla");
  1307. if (!ifcalccton || (ppft->phenology == CROPGREEN && run_landcover && ifnlim))
  1308. if (!itemparsed("cton_leaf_min")) badins("cton_leaf_min");
  1309. if (!itemparsed("cton_root")) badins("cton_root");
  1310. if (!itemparsed("nuptoroot")) badins("nuptoroot");
  1311. if (!itemparsed("km_volume")) badins("km_volume");
  1312. if (!itemparsed("fnstorage")) badins("fnstorage");
  1313. if (!itemparsed("reprfrac")) badins("reprfrac");
  1314. if (!itemparsed("turnover_leaf")) badins("turnover_leaf");
  1315. if (!itemparsed("turnover_root")) badins("turnover_root");
  1316. if (!itemparsed("ltor_max")) badins("ltor_max");
  1317. if (!itemparsed("intc")) badins("intc");
  1318. if (run_landcover) {
  1319. if (!itemparsed("landcover")) badins("landcover");
  1320. if (!itemparsed("turnover_harv_prod")) badins("turnover_harv_prod");
  1321. if (!itemparsed("harvest_slow_frac")) badins("harvest_slow_frac");
  1322. if (!itemparsed("harv_eff")) badins("harv_eff");
  1323. if (!itemparsed("res_outtake")) badins("res_outtake");
  1324. if (ppft->landcover==CROPLAND) {
  1325. if (ppft->phenology==CROPGREEN) {
  1326. if (!itemparsed("sdatenh")) badins("sdatenh");
  1327. if (!itemparsed("sdatesh")) badins("sdatesh");
  1328. if (!itemparsed("lgp_def")) badins("lgp_def");
  1329. if (!itemparsed("sd_adjust")) badins("sd_adjust");
  1330. if (ppft->sd_adjust) {
  1331. if (!itemparsed("sd_adjust_par1")) badins("sd_adjust_par1");
  1332. if (!itemparsed("sd_adjust_par2")) badins("sd_adjust_par2");
  1333. if (!itemparsed("sd_adjust_par3")) badins("sd_adjust_par3");
  1334. }
  1335. if (!itemparsed("hlimitdatenh")) badins("hlimitdatenh");
  1336. if (!itemparsed("hlimitdatesh")) badins("hlimitdatesh");
  1337. if (!itemparsed("tb")) badins("tb");
  1338. if (!itemparsed("trg")) badins("trg");
  1339. if (!itemparsed("pvd")) badins("pvd");
  1340. if (!itemparsed("vern_lag")) badins("vern_lag");
  1341. if (!itemparsed("isintercropgrass")) badins("isintercropgrass");
  1342. if (!itemparsed("psens")) badins("psens");
  1343. if (!itemparsed("pb")) badins("pb");
  1344. if (!itemparsed("ps")) badins("ps");
  1345. if (!itemparsed("phu")) badins("phu");
  1346. if (!itemparsed("phu_calc_quad")) badins("phu_calc_quad");
  1347. if (!itemparsed("phu_calc_lin")) badins("phu_calc_lin");
  1348. if (ppft->phu_calc_quad || ppft->phu_calc_lin) {
  1349. if (!itemparsed("phu_min")) badins("phu_min");
  1350. if (!itemparsed("phu_max")) badins("phu_max");
  1351. }
  1352. if (ppft->phu_calc_quad) {
  1353. if (!itemparsed("phu_red_spring_sow")) badins("phu_red_spring_sow");
  1354. }
  1355. else if (ppft->phu_calc_lin) {
  1356. if (!itemparsed("phu_interc")) badins("phu_interc");
  1357. if (!itemparsed("ndays_ramp_phu")) badins("ndays_ramp_phu");
  1358. }
  1359. if (!itemparsed("fphusen")) badins("fphusen");
  1360. if (!itemparsed("shapesenescencenorm")) badins("shapesenescencenorm");
  1361. if (!itemparsed("flaimaxharvest")) badins("flaimaxharvest");
  1362. if (!itemparsed("aboveground_ho")) badins("aboveground_ho");
  1363. if (!itemparsed("ifsdautumn")) badins("ifsdautumn");
  1364. if (!itemparsed("tempautumn")) badins("tempautumn");
  1365. if (!itemparsed("tempspring")) badins("tempspring");
  1366. if (!itemparsed("maxtemp_sowing")) badins("maxtemp_sowing");
  1367. if (!itemparsed("hiopt")) badins("hiopt");
  1368. if (!itemparsed("himin")) badins("himin");
  1369. if (!itemparsed("res_outtake")) badins("res_outtake");
  1370. if (!itemparsed("frootstart")) badins("frootstart");
  1371. if (!itemparsed("frootend")) badins("frootend");
  1372. if (!itemparsed("turnover_harv_prod")) badins("turnover_harv_prod");
  1373. if(ifnlim) {
  1374. if (!itemparsed("fertrate")) badins("fertrate");
  1375. if (!itemparsed("N_appfert")) badins("N_appfert");
  1376. if (!itemparsed("T_vn_min")) badins("T_vn_min");
  1377. if (!itemparsed("T_vn_opt")) badins("T_vn_opt");
  1378. if (!itemparsed("T_vn_max")) badins("T_vn_max");
  1379. if (!itemparsed("T_veg_min")) badins("T_veg_min");
  1380. if (!itemparsed("T_veg_opt")) badins("T_veg_opt");
  1381. if (!itemparsed("T_veg_max")) badins("T_veg_max");
  1382. if (!itemparsed("T_rep_min")) badins("T_rep_min");
  1383. if (!itemparsed("T_rep_opt")) badins("T_rep_opt");
  1384. if (!itemparsed("T_rep_max")) badins("T_rep_max");
  1385. if (!itemparsed("photo")) badins("photo");
  1386. if (!itemparsed("dev_rate_veg")) badins("dev_rate_veg");
  1387. if (!itemparsed("dev_rate_rep")) badins("dev_rate_rep");
  1388. if (!itemparsed("a1")) badins("a1");
  1389. if (!itemparsed("b1")) badins("b1");
  1390. if (!itemparsed("c1")) badins("c1");
  1391. if (!itemparsed("d1")) badins("d1");
  1392. if (!itemparsed("a2")) badins("a2");
  1393. if (!itemparsed("b2")) badins("b2");
  1394. if (!itemparsed("c2")) badins("c2");
  1395. if (!itemparsed("d2")) badins("d2");
  1396. if (!itemparsed("a3")) badins("a3");
  1397. if (!itemparsed("b3")) badins("b3");
  1398. if (!itemparsed("c3")) badins("c3");
  1399. if (!itemparsed("d3")) badins("d3");
  1400. }
  1401. }
  1402. else if (ppft->phenology==ANY) {
  1403. if(ppft->phenology==ANY)
  1404. if (!itemparsed("laimax")) badins("laimax");
  1405. if(ppft->isintercropgrass)
  1406. if (!itemparsed("harv_eff_ic")) badins("harv_eff_ic");
  1407. }
  1408. }
  1409. }
  1410. // guess2008 - DLE
  1411. if (!itemparsed("drought_tolerance")) badins("drought_tolerance");
  1412. // bvoc
  1413. if(ifbvoc){
  1414. if (!itemparsed("ga")) badins("ga");
  1415. if (!itemparsed("eps_iso")) badins("eps_iso");
  1416. if (!itemparsed("seas_iso")) badins("seas_iso");
  1417. if (!itemparsed("eps_mon")) badins("eps_mon");
  1418. if (!itemparsed("storfrac_mon")) badins("storfrac_mon");
  1419. }
  1420. if (ppft->lifeform==TREE) {
  1421. if (!itemparsed("cton_sap")) badins("cton_sap");
  1422. if (!itemparsed("turnover_sap")) badins("turnover_sap");
  1423. if (!itemparsed("wooddens")) badins("wooddens");
  1424. if (!itemparsed("crownarea_max")) badins("crownarea_max");
  1425. if (!itemparsed("k_allom1")) badins("k_allom1");
  1426. if (!itemparsed("k_allom2")) badins("k_allom2");
  1427. if (!itemparsed("k_allom3")) badins("k_allom3");
  1428. if (!itemparsed("k_rp")) badins("k_rp");
  1429. if (!itemparsed("k_latosa")) badins("k_latosa");
  1430. if (vegmode==COHORT || vegmode==INDIVIDUAL) {
  1431. if (!itemparsed("kest_repr")) badins("kest_repr");
  1432. if (!itemparsed("kest_bg")) badins("kest_bg");
  1433. if (!itemparsed("kest_pres")) badins("kest_pres");
  1434. if (!itemparsed("longevity")) badins("longevity");
  1435. if (!itemparsed("greff_min")) badins("greff_min");
  1436. if (!itemparsed("alphar")) badins("alphar");
  1437. if (!itemparsed("est_max")) badins("est_max");
  1438. }
  1439. }
  1440. if (iffire) {
  1441. if (!itemparsed("litterme")) badins("litterme");
  1442. if (!itemparsed("fireresist")) badins("fireresist");
  1443. }
  1444. if (ifcalcsla) {
  1445. if (!itemparsed("leaflong")) {
  1446. sendmessage("Error",
  1447. "Value required for leaflong when ifcalcsla enabled");
  1448. plibabort();
  1449. }
  1450. if (itemparsed("sla") && !(ppft->phenology == CROPGREEN && ifnlim))
  1451. sendmessage("Warning",
  1452. "Specified sla value not used when ifcalcsla enabled");
  1453. }
  1454. if (vegmode==COHORT || vegmode==INDIVIDUAL) {
  1455. if (!itemparsed("parff_min")) badins("parff_min");
  1456. }
  1457. if (ifcalccton) {
  1458. if (!itemparsed("leaflong")) {
  1459. sendmessage("Error",
  1460. "Value required for leaflong when ifcalccton enabled");
  1461. plibabort();
  1462. }
  1463. if (itemparsed("cton_leaf_min") && !(ppft->phenology == CROPGREEN && ifnlim))
  1464. sendmessage("Warning",
  1465. "Specified cton_leaf_min value not used when ifcalccton enabled");
  1466. }
  1467. }
  1468. else {
  1469. // This PFT has already been parsed once, don't allow changing parameters
  1470. // which would have incurred different checks above.
  1471. if (itemparsed("lifeform") ||
  1472. itemparsed("phenology")) {
  1473. sendmessage("Error",
  1474. "Not allowed to redefine lifeform or phenology in second PFT definition");
  1475. plibabort();
  1476. }
  1477. }
  1478. if (itemparsed("include")) {
  1479. includepft_map[ppft->name] = includepft;
  1480. }
  1481. break;
  1482. case CB_CHECKST:
  1483. if (!checked_st[pst->name]) {
  1484. checked_st[pst->name] = true;
  1485. }
  1486. if (itemparsed("stinclude")) {
  1487. includest_map[pst->name] = includest;
  1488. }
  1489. break;
  1490. case CB_CHECKMT:
  1491. if (!checked_mt[pmt->name]) {
  1492. checked_mt[pmt->name] = true;
  1493. }
  1494. if (itemparsed("mtinclude")) {
  1495. includemt_map[pmt->name] = includemt;
  1496. }
  1497. break;
  1498. }
  1499. }
  1500. void plib_receivemessage(xtring text) {
  1501. // Output of messages to user sent by PLIB
  1502. dprintf((char*)text);
  1503. }
  1504. void read_instruction_file(const char* insfilename) {
  1505. bool exists_getclim_driver_file;
  1506. xtring getclim_driver_file_path;
  1507. if (!fileexists(insfilename)) {
  1508. fail("Error: could not open %s for input", (const char*)insfilename);
  1509. }
  1510. // Initialise PFT count
  1511. npft = 0;
  1512. nst = 0;
  1513. nmt=0;
  1514. checked_pft.clear();
  1515. includepft_map.clear();
  1516. pftlist.killall();
  1517. initsettings();
  1518. // Clear params from previous run, saving needed params before clearing
  1519. if (param.isparam("getclim_driver_file")) {
  1520. exists_getclim_driver_file = true;
  1521. getclim_driver_file_path = param["getclim_driver_file"].str;
  1522. }
  1523. else {
  1524. exists_getclim_driver_file = false;
  1525. }
  1526. param.killall();
  1527. // Initialise simulation settings and PFT parameters from instruction script
  1528. if (!plib(insfilename)) {
  1529. fail("Bad instruction file!");
  1530. }
  1531. // Reinstate params saved from clearing above
  1532. if (exists_getclim_driver_file && getclim_driver_file_path != "")
  1533. param.addparam("getclim_driver_file", getclim_driver_file_path);
  1534. }
  1535. void printhelp() {
  1536. // Calls PLIB to output help text
  1537. ifhelp=true;
  1538. plibhelp();
  1539. ifhelp=false;
  1540. }