parameters.cpp 67 KB

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