commonoutput.cpp 67 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716
  1. ///////////////////////////////////////////////////////////////////////////////////////
  2. /// \file outputmodule.cpp
  3. /// \brief Implementation of the common output module
  4. ///
  5. /// \author Joe Siltberg
  6. /// $Date: 2014-05-13 14:55:59 +0200 (Tue, 13 May 2014) $
  7. ///
  8. ///////////////////////////////////////////////////////////////////////////////////////
  9. #include "config.h"
  10. #include "commonoutput.h"
  11. #include "parameters.h"
  12. #include "guess.h"
  13. // Years between output time points in plot function output (Windows shell only)
  14. const int PLOT_INTERVAL = 1;
  15. // Years between updates of soil water and stand structure plot (Windows shell only)
  16. const int PLOT_UPDATE_INTERVAL = 20;
  17. // Years between updates of 3D vegetation view (Windows shell only)
  18. const int VEG3D_UPDATE_INTERVAL = 5;
  19. // Name of temporary file for output of 3D vegetation structure (Windows shell only)
  20. const char VEG3DFILENAME[] = "xxxtemp0.bin";
  21. // ecev3 - add lpjguess_to_string to avoid problems with std library to_string not being available on NSC platforms
  22. #include <string.h>
  23. #include <sstream>
  24. using namespace std;
  25. std::string lpjguess_int_to_string(int d) {
  26. std::ostringstream os;
  27. os << d;
  28. return os.str();
  29. }
  30. namespace GuessOutput {
  31. REGISTER_OUTPUT_MODULE("common", CommonOutput)
  32. CommonOutput::CommonOutput() {
  33. // Annual output variables
  34. declare_parameter("file_cmass", &file_cmass, 300, "C biomass output file");
  35. declare_parameter("file_anpp", &file_anpp, 300, "Annual NPP output file");
  36. declare_parameter("file_agpp", &file_agpp, 300, "Annual GPP output file");
  37. declare_parameter("file_fpc", &file_fpc, 300, "FPC output file");
  38. declare_parameter("file_aaet", &file_aaet, 300, "Annual AET output file");
  39. declare_parameter("file_lai", &file_lai, 300, "LAI output file");
  40. declare_parameter("file_cflux", &file_cflux, 300, "C fluxes output file");
  41. declare_parameter("file_doc", &file_doc, 300, "DOC output file");
  42. declare_parameter("file_dens", &file_dens, 300, "Tree density output file");
  43. declare_parameter("file_cpool", &file_cpool, 300, "Soil C output file");
  44. declare_parameter("file_clitter", &file_clitter, 300, "Litter C output file");
  45. declare_parameter("file_runoff", &file_runoff, 300, "Runoff output file");
  46. declare_parameter("file_firert", &file_firert, 300, "Fire retrun time output file");
  47. declare_parameter("file_nmass", &file_nmass, 300, "N biomass output file");
  48. declare_parameter("file_cton_leaf", &file_cton_leaf, 300, "Mean leaf C:N output file");
  49. declare_parameter("file_nsources", &file_nsources, 300, "Annual nitrogen sources output file");
  50. declare_parameter("file_npool", &file_npool, 300, "Soil nitrogen output file");
  51. declare_parameter("file_nlitter", &file_nlitter, 300, "Litter nitrogen output file");
  52. declare_parameter("file_nuptake", &file_nuptake, 300, "Annual nitrogen uptake output file");
  53. declare_parameter("file_vmaxnlim", &file_vmaxnlim, 300, "Annual nitrogen limitation on vm output file");
  54. declare_parameter("file_nflux", &file_nflux, 300, "Annual nitrogen fluxes output file");
  55. declare_parameter("file_ngases", &file_ngases, 300, "Annual nitrogen gases output file");
  56. declare_parameter("file_wflux", &file_wflux, 300, "Annual water fluxes output file");
  57. declare_parameter("file_wpool", &file_wpool, 300, "Soil water output file");
  58. declare_parameter("file_speciesheights", &file_speciesheights, 300, "Mean species heights");
  59. // Monthly output variables
  60. declare_parameter("file_mnpp", &file_mnpp, 300, "Monthly NPP output file");
  61. declare_parameter("file_mlai", &file_mlai, 300, "Monthly LAI output file");
  62. declare_parameter("file_mgpp", &file_mgpp, 300, "Monthly GPP-LeafResp output file");
  63. declare_parameter("file_mra", &file_mra, 300, "Monthly autotrophic respiration output file");
  64. declare_parameter("file_maet", &file_maet, 300, "Monthly AET output file");
  65. declare_parameter("file_mpet", &file_mpet, 300, "Monthly PET output file");
  66. declare_parameter("file_mevap", &file_mevap, 300, "Monthly Evap output file");
  67. declare_parameter("file_mrunoff", &file_mrunoff, 300, "Monthly runoff output file");
  68. declare_parameter("file_mintercep", &file_mintercep, 300, "Monthly intercep output file");
  69. declare_parameter("file_mrh", &file_mrh, 300, "Monthly heterotrophic respiration output file");
  70. declare_parameter("file_mnee", &file_mnee, 300, "Monthly NEE output file");
  71. declare_parameter("file_mwcont_upper", &file_mwcont_upper, 300, "Monthly wcont_upper output file");
  72. declare_parameter("file_mwcont_lower", &file_mwcont_lower, 300, "Monthly wcont_lower output file");
  73. // bvoc
  74. declare_parameter("file_aiso", &file_aiso, 300, "annual isoprene flux output file");
  75. declare_parameter("file_miso", &file_miso, 300, "monthly isoprene flux output file");
  76. declare_parameter("file_amon", &file_amon, 300, "annual monoterpene flux output file");
  77. declare_parameter("file_mmon", &file_mmon, 300, "monthly monoterpene flux output file");
  78. declare_parameter("file_amon_mt1", &file_amon_mt1, 300, "annual endocyclic monoterpene flux output file");
  79. declare_parameter("file_amon_mt2", &file_amon_mt2, 300, "annual other monoterpene flux output file");
  80. declare_parameter("file_mmon_mt1", &file_mmon_mt1, 300, "monthly endocyclic monoterpene flux output file");
  81. declare_parameter("file_mmon_mt2", &file_mmon_mt2, 300, "monthly other monoterpene flux output file");
  82. }
  83. CommonOutput::~CommonOutput() {
  84. }
  85. /// Define all output tables and their formats
  86. void CommonOutput::init() {
  87. define_output_tables();
  88. }
  89. /** This function specifies all columns in all output tables, their names,
  90. * column widths and precision.
  91. *
  92. * For each table a TableDescriptor object is created which is then sent to
  93. * the output channel to create the table.
  94. */
  95. void CommonOutput::define_output_tables() {
  96. //Extra number of decimals when output for benchmarks
  97. #ifdef RUN_BENCHMARKS
  98. const int bm_extra_prec = 2;
  99. #else
  100. const int bm_extra_prec =0;
  101. #endif
  102. // create a vector with the pft names
  103. std::vector<std::string> pfts;
  104. // create a vector with the crop pft names
  105. std::vector<std::string> crop_pfts;
  106. pftlist.firstobj();
  107. while (pftlist.isobj) {
  108. Pft& pft=pftlist.getobj();
  109. pfts.push_back((char*)pft.name);
  110. if(pft.landcover==CROPLAND)
  111. crop_pfts.push_back((char*)pft.name);
  112. pftlist.nextobj();
  113. }
  114. // create a vector with the landcover column titles
  115. std::vector<std::string> landcovers;
  116. if (run_landcover) {
  117. const char* landcover_string[]={"Urban_sum", "Crop_sum", "Pasture_sum",
  118. "Forest_sum", "Natural_sum", "Peatland_sum", "Barren_sum"};
  119. for (int i=0; i<NLANDCOVERTYPES; i++) {
  120. if(run[i]) {
  121. landcovers.push_back(landcover_string[i]);
  122. }
  123. }
  124. }
  125. // create a vector with the landcover column titles
  126. std::vector<std::string> soil_layers;
  127. // ecev3 - don't use STD library version of to_string
  128. for (int i = 0; i < NSOILLAYER; i++) {
  129. soil_layers.push_back("lyr" + lpjguess_int_to_string(i+1));
  130. }
  131. // Create the month columns
  132. ColumnDescriptors month_columns;
  133. ColumnDescriptors month_columns_wide;
  134. ColumnDescriptors soil_layer_columns;
  135. xtring months[] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
  136. for (int i = 0; i < 12; i++) {
  137. month_columns += ColumnDescriptor(months[i], 8, 3);
  138. month_columns_wide += ColumnDescriptor(months[i], 10, 3);
  139. }
  140. // Create the columns for each output file
  141. // CMASS
  142. ColumnDescriptors cmass_columns;
  143. cmass_columns += ColumnDescriptors(pfts, 8, 3);
  144. cmass_columns += ColumnDescriptor("Total", 8, 3);
  145. cmass_columns += ColumnDescriptors(landcovers, 13, 3);
  146. // ANPP
  147. ColumnDescriptors anpp_columns = cmass_columns;
  148. // AGPP
  149. ColumnDescriptors agpp_columns = cmass_columns;
  150. // FPC
  151. ColumnDescriptors fpc_columns = cmass_columns;
  152. // ecev3 - add dominant type and fractions to FPC file
  153. fpc_columns += ColumnDescriptor("TYPEH", 8, 0);
  154. fpc_columns += ColumnDescriptor("FRACH", 8, 4);
  155. fpc_columns += ColumnDescriptor("TYPEL", 8, 0);
  156. fpc_columns += ColumnDescriptor("FRACL", 8, 4);
  157. fpc_columns += ColumnDescriptor("AGDD5", 8, 0);
  158. fpc_columns += ColumnDescriptor("AWCONT", 8, 3);
  159. fpc_columns += ColumnDescriptor("URBANFPC", 12, 4);
  160. fpc_columns += ColumnDescriptor("CROPFPC", 12, 4);
  161. fpc_columns += ColumnDescriptor("PASTUREFPC", 12, 4);
  162. fpc_columns += ColumnDescriptor("FORESTFPC", 12, 4);
  163. fpc_columns += ColumnDescriptor("GRASSFPC", 12, 4);
  164. fpc_columns += ColumnDescriptor("TREEFPC", 12, 4);
  165. fpc_columns += ColumnDescriptor("PEATFPC", 12, 4);
  166. fpc_columns += ColumnDescriptor("BARRENFPC", 12, 4);
  167. // AET
  168. ColumnDescriptors aaet_columns;
  169. aaet_columns += ColumnDescriptors(pfts, 8, 2);
  170. aaet_columns += ColumnDescriptor("Total", 8, 2);
  171. aaet_columns += ColumnDescriptors(landcovers, 13, 2);
  172. // DENS
  173. ColumnDescriptors dens_columns;
  174. dens_columns += ColumnDescriptors(pfts, 8, 4);
  175. dens_columns += ColumnDescriptor("Total", 8, 4);
  176. dens_columns += ColumnDescriptors(landcovers, 13, 4);
  177. // LAI
  178. ColumnDescriptors lai_columns = dens_columns;
  179. // CFLUX
  180. ColumnDescriptors cflux_columns;
  181. cflux_columns += ColumnDescriptor("Veg", 8, 3);
  182. cflux_columns += ColumnDescriptor("Repr", 8, 3);
  183. cflux_columns += ColumnDescriptor("Soil", 8, 3);
  184. cflux_columns += ColumnDescriptor("Fire", 8, 3);
  185. cflux_columns += ColumnDescriptor("Est", 8, 3);
  186. if (run_landcover) {
  187. cflux_columns += ColumnDescriptor("Seed", 8, 3);
  188. cflux_columns += ColumnDescriptor("Harvest", 9, 3);
  189. cflux_columns += ColumnDescriptor("LU_ch", 9, 3);
  190. cflux_columns += ColumnDescriptor("Slow_h", 9, 3);
  191. }
  192. cflux_columns += ColumnDescriptor("NEE", 10 + bm_extra_prec, 5 + bm_extra_prec);
  193. ColumnDescriptors doc_columns;
  194. doc_columns += ColumnDescriptor("Total", 10, 3);
  195. doc_columns += ColumnDescriptors(landcovers, 13, 3);
  196. // CPOOL
  197. ColumnDescriptors cpool_columns;
  198. cpool_columns += ColumnDescriptor("VegC", 8, 3);
  199. if (!ifcentury) {
  200. cpool_columns += ColumnDescriptor("LittC", 8, 3);
  201. cpool_columns += ColumnDescriptor("SoilfC", 8, 3);
  202. cpool_columns += ColumnDescriptor("SoilsC", 8, 3);
  203. }
  204. else {
  205. cpool_columns += ColumnDescriptor("LitterC", 8, 3);
  206. cpool_columns += ColumnDescriptor("SoilC", 8, 3);
  207. }
  208. if (run_landcover && ifslowharvestpool) {
  209. cpool_columns += ColumnDescriptor("HarvSlowC", 10, 3);
  210. }
  211. cpool_columns += ColumnDescriptor("Total", 10 + bm_extra_prec, 3 + bm_extra_prec);
  212. // CLITTER
  213. ColumnDescriptors clitter_columns = cmass_columns;
  214. // FIRERT
  215. ColumnDescriptors firert_columns;
  216. firert_columns += ColumnDescriptor("FireRT", 8, 1);
  217. // RUNOFF
  218. ColumnDescriptors runoff_columns;
  219. runoff_columns += ColumnDescriptor("Surf", 8, 1);
  220. runoff_columns += ColumnDescriptor("Drain", 8, 1);
  221. runoff_columns += ColumnDescriptor("Base", 8, 1);
  222. runoff_columns += ColumnDescriptor("Total", 8, 1);
  223. // SPECIESHEIGHTS
  224. ColumnDescriptors speciesheights_columns;
  225. speciesheights_columns += ColumnDescriptors(pfts, 8, 2);
  226. // AISO
  227. ColumnDescriptors aiso_columns;
  228. aiso_columns += ColumnDescriptors(pfts, 10, 3);
  229. aiso_columns += ColumnDescriptor("Total", 10, 3);
  230. aiso_columns += ColumnDescriptors(landcovers, 13, 3);
  231. // MONOTERPENES
  232. ColumnDescriptors amon_columns = aiso_columns;
  233. // CTON
  234. ColumnDescriptors cton_columns;
  235. cton_columns += ColumnDescriptors(pfts, 8, 1);
  236. cton_columns += ColumnDescriptor("Total", 8, 1);
  237. cton_columns += ColumnDescriptors(landcovers, 13, 1);
  238. // NSOURCES
  239. ColumnDescriptors nsources_columns;
  240. nsources_columns += ColumnDescriptor("dep", 8, 2);
  241. nsources_columns += ColumnDescriptor("fix", 8, 2);
  242. nsources_columns += ColumnDescriptor("fert", 8, 2);
  243. nsources_columns += ColumnDescriptor("input", 8, 2);
  244. nsources_columns += ColumnDescriptor("min", 8, 2);
  245. nsources_columns += ColumnDescriptor("imm", 8, 2);
  246. nsources_columns += ColumnDescriptor("netmin", 8, 2);
  247. nsources_columns += ColumnDescriptor("Total", 8, 2);
  248. // NPOOL
  249. ColumnDescriptors npool_columns;
  250. npool_columns += ColumnDescriptor("VegN", 9, 4);
  251. npool_columns += ColumnDescriptor("LitterN", 9, 4);
  252. npool_columns += ColumnDescriptor("SoilN", 9, 4);
  253. if (run_landcover && ifslowharvestpool) {
  254. npool_columns += ColumnDescriptor("HarvSlowN", 10, 4);
  255. }
  256. npool_columns += ColumnDescriptor("Total", 10 + bm_extra_prec, 4 + bm_extra_prec);
  257. // NMASS
  258. ColumnDescriptors nmass_columns;
  259. nmass_columns += ColumnDescriptors(pfts, 8, 2);
  260. nmass_columns += ColumnDescriptor("Total", 8, 2);
  261. nmass_columns += ColumnDescriptors(landcovers, 13, 2);
  262. // NUPTAKE
  263. ColumnDescriptors nuptake_columns = nmass_columns;
  264. // NLITTER
  265. ColumnDescriptors nlitter_columns = nmass_columns;
  266. // VMAXNLIM
  267. ColumnDescriptors vmaxnlim_columns;
  268. vmaxnlim_columns += ColumnDescriptors(pfts, 8, 2);
  269. vmaxnlim_columns += ColumnDescriptor("Total", 8, 2);
  270. vmaxnlim_columns += ColumnDescriptors(landcovers, 13, 2);
  271. // NFLUX
  272. ColumnDescriptors nflux_columns;
  273. nflux_columns += ColumnDescriptor("dep", 8, 2);
  274. nflux_columns += ColumnDescriptor("fix", 8, 2);
  275. nflux_columns += ColumnDescriptor("fert", 8, 2);
  276. nflux_columns += ColumnDescriptor("flux", 8, 2);
  277. nflux_columns += ColumnDescriptor("leach", 8, 2);
  278. if (run_landcover) {
  279. nflux_columns += ColumnDescriptor("seed", 8, 2);
  280. nflux_columns += ColumnDescriptor("harvest", 8, 2);
  281. nflux_columns += ColumnDescriptor("LU_ch", 8, 3);
  282. nflux_columns += ColumnDescriptor("Slow_h", 8, 3);
  283. }
  284. nflux_columns += ColumnDescriptor("NEE", 8 + bm_extra_prec, 2 + bm_extra_prec);
  285. // NGASES
  286. ColumnDescriptors ngases_columns;
  287. ngases_columns += ColumnDescriptor("NH3", 9, 3);
  288. ngases_columns += ColumnDescriptor("NOx", 9, 3);
  289. ngases_columns += ColumnDescriptor("N2O", 9, 3);
  290. ngases_columns += ColumnDescriptor("N2", 9, 3);
  291. ngases_columns += ColumnDescriptor("NSoil", 9, 3);
  292. ngases_columns += ColumnDescriptor("Total", 9, 3);
  293. // WFLUX
  294. ColumnDescriptors wflux_columns;
  295. wflux_columns += ColumnDescriptor("prec", 10, 2);
  296. wflux_columns += ColumnDescriptor("irri", 10, 2);
  297. wflux_columns += ColumnDescriptor("pet", 10, 2);
  298. wflux_columns += ColumnDescriptor("aet", 10, 2);
  299. wflux_columns += ColumnDescriptor("intercep", 10, 2);
  300. wflux_columns += ColumnDescriptor("evap", 10, 2);
  301. wflux_columns += ColumnDescriptor("surfrunoff", 14, 2);
  302. wflux_columns += ColumnDescriptor("drainrunoff", 14, 2);
  303. wflux_columns += ColumnDescriptor("baserunoff", 14, 2);
  304. wflux_columns += ColumnDescriptor("NEE", 10, 4);
  305. // WPOOL
  306. ColumnDescriptors wpool_columns;
  307. wpool_columns += ColumnDescriptor("snow", 8, 2);
  308. wpool_columns += ColumnDescriptors(soil_layers, 8, 2);
  309. // *** ANNUAL OUTPUT VARIABLES ***
  310. create_output_table(out_cmass, file_cmass, cmass_columns);
  311. create_output_table(out_anpp, file_anpp, anpp_columns);
  312. create_output_table(out_agpp, file_agpp, agpp_columns);
  313. create_output_table(out_fpc, file_fpc, fpc_columns);
  314. create_output_table(out_aaet, file_aaet, aaet_columns);
  315. create_output_table(out_dens, file_dens, dens_columns);
  316. create_output_table(out_lai, file_lai, lai_columns);
  317. create_output_table(out_cflux, file_cflux, cflux_columns);
  318. create_output_table(out_doc, file_doc, doc_columns);
  319. create_output_table(out_cpool, file_cpool, cpool_columns);
  320. create_output_table(out_clitter, file_clitter, clitter_columns);
  321. create_output_table(out_firert, file_firert, firert_columns);
  322. create_output_table(out_runoff, file_runoff, runoff_columns);
  323. create_output_table(out_speciesheights, file_speciesheights, speciesheights_columns);
  324. create_output_table(out_aiso, file_aiso, aiso_columns);
  325. create_output_table(out_amon, file_amon, amon_columns);
  326. create_output_table(out_amon_mt1, file_amon_mt1, amon_columns);
  327. create_output_table(out_amon_mt2, file_amon_mt2, amon_columns);
  328. create_output_table(out_nmass, file_nmass, nmass_columns);
  329. create_output_table(out_cton_leaf, file_cton_leaf, cton_columns);
  330. create_output_table(out_nsources, file_nsources, nsources_columns);
  331. create_output_table(out_npool, file_npool, npool_columns);
  332. create_output_table(out_nlitter, file_nlitter, nlitter_columns);
  333. create_output_table(out_nuptake, file_nuptake, nuptake_columns);
  334. create_output_table(out_vmaxnlim, file_vmaxnlim, vmaxnlim_columns);
  335. create_output_table(out_nflux, file_nflux, nflux_columns);
  336. create_output_table(out_ngases, file_ngases, ngases_columns);
  337. create_output_table(out_wflux, file_wflux, wflux_columns);
  338. create_output_table(out_wpool, file_wpool, wpool_columns);
  339. // *** MONTHLY OUTPUT VARIABLES ***
  340. create_output_table(out_mnpp, file_mnpp, month_columns);
  341. create_output_table(out_mlai, file_mlai, month_columns);
  342. create_output_table(out_mgpp, file_mgpp, month_columns);
  343. create_output_table(out_mra, file_mra, month_columns);
  344. create_output_table(out_maet, file_maet, month_columns);
  345. create_output_table(out_mpet, file_mpet, month_columns);
  346. create_output_table(out_mevap, file_mevap, month_columns);
  347. create_output_table(out_mrunoff, file_mrunoff, month_columns_wide);
  348. create_output_table(out_mintercep, file_mintercep, month_columns);
  349. create_output_table(out_mrh, file_mrh, month_columns);
  350. create_output_table(out_mnee, file_mnee, month_columns);
  351. create_output_table(out_mwcont_upper, file_mwcont_upper, month_columns);
  352. create_output_table(out_mwcont_lower, file_mwcont_lower, month_columns);
  353. create_output_table(out_miso, file_miso, month_columns_wide);
  354. create_output_table(out_mmon, file_mmon, month_columns_wide);
  355. create_output_table(out_mmon_mt1, file_mmon_mt1, month_columns_wide);
  356. create_output_table(out_mmon_mt2, file_mmon_mt2, month_columns_wide);
  357. }
  358. /// Function for producing data file used to communicate information on stand structure
  359. /** for 3D vegetation plot in Windows shell
  360. */
  361. void output_vegetation(Gridcell& gridcell, Pftlist& pftlist) {
  362. int ival, p, npft_tree, npft_grass, npft_total;
  363. double grasslai;
  364. const bool FALSCH = false;
  365. const double rgb[3] = { -1, -1, -1 };
  366. xtring file;
  367. char pftname[16];
  368. file = VEG3DFILENAME;
  369. FILE* out = fopen(file, "wb");
  370. if (out)
  371. {
  372. // Loop through Stands
  373. Gridcell::iterator gc_itr = gridcell.begin();
  374. while (gc_itr != gridcell.end())
  375. {
  376. Stand& stand = *gc_itr;
  377. npft_tree = npft_grass = 0;
  378. pftlist.firstobj();
  379. while (pftlist.isobj) {
  380. Pft& pft = pftlist.getobj();
  381. if (pft.lifeform == TREE) npft_tree++;
  382. else if (pft.lifeform == GRASS) npft_grass++;
  383. pftlist.nextobj();
  384. }
  385. npft_total = npft_tree + npft_grass;
  386. fwrite(&npft_total, sizeof(int), 1, out);
  387. fwrite(&npft_tree, sizeof(int), 1, out);
  388. pftlist.firstobj();
  389. while (pftlist.isobj) {
  390. Pft& pft = pftlist.getobj();
  391. if (pft.lifeform == TREE) {
  392. sprintf(pftname, "%s", (char*)(pft.name.left(15)));
  393. fwrite(pftname, sizeof(char), 16, out);
  394. fwrite(&FALSCH, sizeof(bool), 1, out);
  395. fwrite(&rgb, sizeof(double), 3, out);
  396. //fwrite(&pft.ifconifer, sizeof(bool), 1, out);
  397. //fwrite(pft.preferredrgb, sizeof(double), 3, out);
  398. }
  399. pftlist.nextobj();
  400. }
  401. pftlist.firstobj();
  402. while (pftlist.isobj) {
  403. Pft& pft = pftlist.getobj();
  404. if (pft.lifeform == GRASS) {
  405. sprintf(pftname, "%s", (char*)(pft.name.left(15)));
  406. fwrite(pftname, sizeof(char), 16, out);
  407. fwrite(&rgb, sizeof(double), 3, out);
  408. //fwrite(pft.preferredrgb, sizeof(double), 3, out);
  409. }
  410. pftlist.nextobj();
  411. }
  412. int npatch = stand.npatch();
  413. fwrite(&npatch, sizeof(int), 1, out);
  414. fwrite(&patcharea, sizeof(double), 1, out);
  415. for (p = 0; p<npatch; p++) {
  416. Patch& patch = stand[p];
  417. Vegetation& vegetation = patch.vegetation;
  418. grasslai = 0.0;
  419. vegetation.firstobj();
  420. while (vegetation.isobj) {
  421. Individual& indiv = vegetation.getobj();
  422. if (indiv.pft.lifeform == TREE && indiv.alive) {
  423. ival = indiv.pft.id;
  424. fwrite(&ival, sizeof(int), 1, out);
  425. ival = indiv.id;
  426. fwrite(&ival, sizeof(int), 1, out);
  427. fwrite(&indiv.densindiv, sizeof(double), 1, out);
  428. fwrite(&indiv.height, sizeof(double), 1, out);
  429. fwrite(&indiv.crownarea, sizeof(double), 1, out);
  430. }
  431. else if (indiv.pft.lifeform == GRASS) grasslai += indiv.lai;
  432. vegetation.nextobj();
  433. }
  434. ival = -9999;
  435. fwrite(&ival, sizeof(int), 1, out); // indicates no more cohorts in this patch
  436. if (grasslai<0) grasslai = 0.0;
  437. fwrite(&grasslai, sizeof(double), 1, out);
  438. }
  439. ++gc_itr;
  440. } //while (gridcell.isobj)
  441. fclose(out);
  442. } //if(out)
  443. plot3d(file);
  444. }
  445. /// Gets stand age structure to argument densindiv of dimensions [npft,nageclass]
  446. /** First call with havedims=false to allocate memory and return nageclass,
  447. * then with havedims=true to get data into densindiv
  448. * Calling function is responsible for deallocating memory by:
  449. * delete[] densindiv;
  450. */
  451. void get_stand_age_structure(Gridcell& gridcell,double* densindiv,int& nageclass,bool havedims) {
  452. int p, c;
  453. double active_fraction;
  454. if (!(vegmode == COHORT || vegmode == INDIVIDUAL)) {
  455. nageclass = 0;
  456. return;
  457. }
  458. if (havedims) {
  459. for (p = 0; p < npft; p++)
  460. for (c = 0; c < nageclass; c++)
  461. densindiv[p*nageclass + c] = 0.0;
  462. }
  463. else nageclass = 0;
  464. pftlist.firstobj();
  465. while (pftlist.isobj) {
  466. Pft& pft = pftlist.getobj();
  467. // Determine area fraction of stands where this pft is active:
  468. active_fraction = 0.0;
  469. Gridcell::iterator gc_itr = gridcell.begin();
  470. while (gc_itr != gridcell.end()) {
  471. Stand& stand = *gc_itr;
  472. if (stand.pft[pft.id].active) {
  473. active_fraction += stand.get_gridcell_fraction();
  474. }
  475. ++gc_itr;
  476. }
  477. // Loop through Stands
  478. gc_itr = gridcell.begin();
  479. while (gc_itr != gridcell.end()) {
  480. Stand& stand = *gc_itr;
  481. Standpft& standpft = stand.pft[pft.id];
  482. if (standpft.active) {
  483. stand.firstobj();
  484. // Loop through Patches
  485. while (stand.isobj) {
  486. Patch& patch = stand.getobj();
  487. Patchpft& patchpft = patch.pft[pft.id];
  488. Vegetation& vegetation = patch.vegetation;
  489. // Loop through individuals/cohorts
  490. vegetation.firstobj();
  491. while (vegetation.isobj) {
  492. Individual& indiv = vegetation.getobj();
  493. if (indiv.id != -1 && indiv.alive) {
  494. if (indiv.pft.id == pft.id) {
  495. // Age structure
  496. c = (int)(indiv.age / estinterval);
  497. if (havedims && active_fraction > 0.0) { // ecev3 - added active_fraction check
  498. densindiv[pft.id*nageclass + c] += indiv.densindiv / (double)stand.npatch()* stand.get_gridcell_fraction() / active_fraction;
  499. }
  500. else if (c > nageclass) nageclass = c;
  501. }
  502. }
  503. vegetation.nextobj();
  504. }
  505. stand.nextobj();
  506. }
  507. }
  508. ++gc_itr;
  509. }
  510. pftlist.nextobj();
  511. }
  512. }
  513. /// Local analogue of OutputRows::add_value for restricting output
  514. /** Use to restrict output to specified range of years
  515. * (or other user-specified limitation)
  516. *
  517. * If only yearly output between, say 1961 and 1990 is requred, use:
  518. * if (date.get_calendar_year() >= 1961 && date.get_calendar_year() <= 1990)
  519. * (assuming the input module has set the first calendar year in the date object)
  520. */
  521. void outlimit(OutputRows& out, const Table& table, double d) {
  522. if (date.year>=nyear_spinup)
  523. out.add_value(table, d);
  524. }
  525. /// Output of simulation results at the end of each year
  526. /** Output of simulation results at the end of each year, or for specific years in
  527. * the simulation of each stand or grid cell.
  528. * This function does not have to provide any information to the framework.
  529. *
  530. * Restrict output to specific years in the local helper function outlimit().
  531. *
  532. * Changes in the structure of this function should be mirrored in outannual()
  533. * of the other output modules, e.g. MiscOutput::outannual().
  534. */
  535. void CommonOutput::outannual(Gridcell& gridcell) {
  536. int c, m;
  537. double flux_veg, flux_repr, flux_soil, flux_fire, flux_est, flux_debexcc, flux_seed, flux_charvest;
  538. double c_fast, c_slow, c_harv_slow;
  539. double surfsoillitterc, surfsoillittern, cwdc, cwdn, centuryc, centuryn, n_harv_slow, availn;
  540. double flux_nh3, flux_nox, flux_n2o, flux_n2, flux_nsoil, flux_ntot, flux_nharvest, flux_nseed;
  541. // Nitrogen output is in kgN/ha instead of kgC/m2 as for carbon
  542. double m2toha = 10000.0;
  543. // hold the monthly average across patches
  544. double mnpp[12];
  545. double mgpp[12];
  546. double mlai[12];
  547. double maet[12];
  548. double mpet[12];
  549. double mevap[12];
  550. double mintercep[12];
  551. double mrunoff[12];
  552. double mrh[12];
  553. double mra[12];
  554. double mnee[12];
  555. double mwcont_upper[12];
  556. double mwcont_lower[12];
  557. // bvoc
  558. double miso[12];
  559. double mmon[12];
  560. double mmon_mt1[12];
  561. double mmon_mt2[12];
  562. double aprec, airri, aaet, apet, aevap, arunoff, aintercep;
  563. double snow, mois[NSOILLAYER] = { 0.0 };
  564. // yearly output after spinup
  565. // If only yearly output between, say 1961 and 1990 is requred, use:
  566. // if (date.get_calendar_year() >= 1961 && date.get_calendar_year() <= 1990) {
  567. // (assuming the input module has set the first calendar year in the date object)
  568. // if (date.year >= nyear_spinup) {
  569. if (date.year >= 0) { // ecev3 - we want output every year
  570. double lon = gridcell.get_lon();
  571. double lat = gridcell.get_lat();
  572. // The OutputRows object manages the next row of output for each
  573. // output table
  574. OutputRows out(output_channel, lon, lat, date.get_calendar_year());
  575. // guess2008 - reset monthly and annual sums across patches each year
  576. for (m = 0; m < 12; m++)
  577. mnpp[m] = mlai[m] = mgpp[m] = mra[m] = maet[m] = mpet[m] = mevap[m] = mintercep[m] = mrunoff[m] = mrh[m] = mnee[m] = mwcont_upper[m] = mwcont_lower[m] = miso[m] = mmon[m] = mmon_mt1[m] = mmon_mt2[m] = 0.0;
  578. aprec = airri = aaet = apet = aevap = arunoff = aintercep = 0.0;
  579. snow = 0.0;
  580. double landcover_cmass[NLANDCOVERTYPES] = { 0.0 };
  581. double landcover_nmass[NLANDCOVERTYPES] = { 0.0 };
  582. double landcover_cmass_leaf[NLANDCOVERTYPES] = { 0.0 };
  583. double landcover_nmass_leaf[NLANDCOVERTYPES] = { 0.0 };
  584. double landcover_cmass_veg[NLANDCOVERTYPES] = { 0.0 };
  585. double landcover_nmass_veg[NLANDCOVERTYPES] = { 0.0 };
  586. double landcover_clitter[NLANDCOVERTYPES] = { 0.0 };
  587. double landcover_nlitter[NLANDCOVERTYPES] = { 0.0 };
  588. double landcover_anpp[NLANDCOVERTYPES] = { 0.0 };
  589. double landcover_agpp[NLANDCOVERTYPES] = { 0.0 };
  590. double landcover_fpc[NLANDCOVERTYPES] = { 0.0 };
  591. double landcover_aaet[NLANDCOVERTYPES] = { 0.0 };
  592. double landcover_lai[NLANDCOVERTYPES] = { 0.0 };
  593. double landcover_densindiv_total[NLANDCOVERTYPES] = { 0.0 };
  594. double landcover_aiso[NLANDCOVERTYPES] = { 0.0 };
  595. double landcover_amon[NLANDCOVERTYPES] = { 0.0 };
  596. double landcover_amon_mt1[NLANDCOVERTYPES] = { 0.0 };
  597. double landcover_amon_mt2[NLANDCOVERTYPES] = { 0.0 };
  598. double landcover_nuptake[NLANDCOVERTYPES] = { 0.0 };
  599. double landcover_vmaxnlim[NLANDCOVERTYPES] = { 0.0 };
  600. double mean_standpft_cmass = 0.0;
  601. double mean_standpft_nmass = 0.0;
  602. double mean_standpft_cmass_leaf = 0.0;
  603. double mean_standpft_nmass_leaf = 0.0;
  604. double mean_standpft_cmass_veg = 0.0;
  605. double mean_standpft_nmass_veg = 0.0;
  606. double mean_standpft_clitter = 0.0;
  607. double mean_standpft_nlitter = 0.0;
  608. double mean_standpft_anpp = 0.0;
  609. double mean_standpft_agpp = 0.0;
  610. double mean_standpft_fpc = 0.0;
  611. double mean_standpft_aaet = 0.0;
  612. double mean_standpft_lai = 0.0;
  613. double mean_standpft_densindiv_total = 0.0;
  614. double mean_standpft_aiso = 0.0;
  615. double mean_standpft_amon = 0.0;
  616. double mean_standpft_amon_mt1 = 0.0;
  617. double mean_standpft_amon_mt2 = 0.0;
  618. double mean_standpft_nuptake = 0.0;
  619. double mean_standpft_vmaxnlim = 0.0;
  620. double cmass_gridcell = 0.0;
  621. double nmass_gridcell = 0.0;
  622. double cmass_leaf_gridcell = 0.0;
  623. double nmass_leaf_gridcell = 0.0;
  624. double cmass_veg_gridcell = 0.0;
  625. double nmass_veg_gridcell = 0.0;
  626. double clitter_gridcell = 0.0;
  627. double nlitter_gridcell = 0.0;
  628. double anpp_gridcell = 0.0;
  629. double agpp_gridcell = 0.0;
  630. double fpc_gridcell = 0.0;
  631. double aaet_gridcell = 0.0;
  632. double lai_gridcell = 0.0;
  633. double surfrunoff_gridcell = 0.0;
  634. double drainrunoff_gridcell = 0.0;
  635. double baserunoff_gridcell = 0.0;
  636. double runoff_gridcell = 0.0;
  637. double dens_gridcell = 0.0;
  638. double firert_gridcell = 0.0;
  639. double aiso_gridcell = 0.0;
  640. double amon_gridcell = 0.0;
  641. double amon_mt1_gridcell = 0.0;
  642. double amon_mt2_gridcell = 0.0;
  643. double nuptake_gridcell = 0.0;
  644. double vmaxnlim_gridcell = 0.0;
  645. double andep_gridcell = 0.0;
  646. double anfert_gridcell = 0.0;
  647. double anmin_gridcell = 0.0;
  648. double animm_gridcell = 0.0;
  649. double anfix_gridcell = 0.0;
  650. double n_min_leach_gridcell = 0.0;
  651. double n_org_leach_gridcell = 0.0;
  652. double c_org_leach_gridcell = 0.0;
  653. double standpft_cmass = 0.0;
  654. double standpft_nmass = 0.0;
  655. double standpft_cmass_leaf = 0.0;
  656. double standpft_nmass_leaf = 0.0;
  657. double standpft_cmass_veg = 0.0;
  658. double standpft_nmass_veg = 0.0;
  659. double standpft_clitter = 0.0;
  660. double standpft_nlitter = 0.0;
  661. double standpft_anpp = 0.0;
  662. double standpft_agpp = 0.0;
  663. double standpft_fpc = 0.0;
  664. double standpft_aaet = 0.0;
  665. double standpft_lai = 0.0;
  666. double standpft_densindiv_total = 0.0;
  667. double standpft_aiso = 0.0;
  668. double standpft_amon = 0.0;
  669. double standpft_amon_mt1 = 0.0;
  670. double standpft_amon_mt2 = 0.0;
  671. double standpft_nuptake = 0.0;
  672. double standpft_vmaxnlim = 0.0;
  673. // crop fpc based on individual LAI (normally fpc is fixed to 1 for crop individuals)
  674. double gridcell_urbanfpc = 0.0;
  675. double gridcell_cropfpc = 0.0;
  676. double gridcell_pasturefpc = 0.0;
  677. double gridcell_forestfpc = 0.0;
  678. double gridcell_grassfpc = 0.0;
  679. double gridcell_treefpc = 0.0;
  680. double gridcell_peatfpc = 0.0;
  681. double gridcell_barrenfpc = 0.0;
  682. // *** Loop through PFTs ***
  683. pftlist.firstobj();
  684. while (pftlist.isobj) {
  685. Pft& pft = pftlist.getobj();
  686. Gridcellpft& gridcellpft = gridcell.pft[pft.id];
  687. // Sum C biomass, NPP, LAI and BVOC fluxes across patches and PFTs
  688. mean_standpft_cmass = 0.0;
  689. mean_standpft_nmass = 0.0;
  690. mean_standpft_cmass_leaf = 0.0;
  691. mean_standpft_nmass_leaf = 0.0;
  692. mean_standpft_cmass_veg = 0.0;
  693. mean_standpft_nmass_veg = 0.0;
  694. mean_standpft_clitter = 0.0;
  695. mean_standpft_nlitter = 0.0;
  696. mean_standpft_anpp = 0.0;
  697. mean_standpft_agpp = 0.0;
  698. mean_standpft_fpc = 0.0;
  699. mean_standpft_aaet = 0.0;
  700. mean_standpft_lai = 0.0;
  701. mean_standpft_densindiv_total = 0.0;
  702. mean_standpft_aiso = 0.0;
  703. mean_standpft_amon = 0.0;
  704. mean_standpft_amon_mt1 = 0.0;
  705. mean_standpft_amon_mt2 = 0.0;
  706. mean_standpft_nuptake = 0.0;
  707. mean_standpft_vmaxnlim = 0.0;
  708. double heightindiv_total = 0.0;
  709. // Determine area fraction of stands where this pft is active:
  710. double active_fraction = 0.0;
  711. Gridcell::iterator gc_itr = gridcell.begin();
  712. while (gc_itr != gridcell.end()) {
  713. Stand& stand = *gc_itr;
  714. if (stand.pft[pft.id].active) {
  715. active_fraction += stand.get_gridcell_fraction();
  716. }
  717. ++gc_itr;
  718. }
  719. // Loop through Stands
  720. gc_itr = gridcell.begin();
  721. while (gc_itr != gridcell.end()) {
  722. Stand& stand = *gc_itr;
  723. double to_gridcell_average = stand.get_gridcell_fraction() / (double)stand.npatch();
  724. Standpft& standpft = stand.pft[pft.id];
  725. if (standpft.active) {
  726. // Sum C biomass, NPP, LAI and BVOC fluxes across patches and PFTs
  727. standpft_cmass = 0.0;
  728. standpft_nmass = 0.0;
  729. standpft_cmass_leaf = 0.0;
  730. standpft_nmass_leaf = 0.0;
  731. standpft_cmass_veg = 0.0;
  732. standpft_nmass_veg = 0.0;
  733. standpft_clitter = 0.0;
  734. standpft_nlitter = 0.0;
  735. standpft_anpp = 0.0;
  736. standpft_agpp = 0.0;
  737. standpft_fpc = 0.0;
  738. standpft_aaet = 0.0;
  739. standpft_lai = 0.0;
  740. standpft_densindiv_total = 0.0;
  741. standpft_aiso = 0.0;
  742. standpft_amon = 0.0;
  743. standpft_amon_mt1 = 0.0;
  744. standpft_amon_mt2 = 0.0;
  745. standpft_nuptake = 0.0;
  746. standpft_vmaxnlim = 0.0;
  747. stand.firstobj();
  748. // Loop through Patches
  749. while (stand.isobj) {
  750. Patch& patch = stand.getobj();
  751. Patchpft& patchpft = patch.pft[pft.id];
  752. Vegetation& vegetation = patch.vegetation;
  753. double fpc_tree_patch = 0.0;
  754. double fpc_grass_patch = 0.0;
  755. standpft_anpp += patch.fluxes.get_annual_flux(Fluxes::NPP, pft.id);
  756. standpft_agpp += patch.fluxes.get_annual_flux(Fluxes::GPP, pft.id);
  757. standpft_aiso += patch.fluxes.get_annual_flux(Fluxes::ISO, pft.id);
  758. standpft_amon += patch.fluxes.get_annual_flux(Fluxes::MT1, pft.id);
  759. standpft_amon += patch.fluxes.get_annual_flux(Fluxes::MT2, pft.id);
  760. standpft_amon_mt1 += patch.fluxes.get_annual_flux(Fluxes::MT1, pft.id);
  761. standpft_amon_mt2 += patch.fluxes.get_annual_flux(Fluxes::MT2, pft.id);
  762. standpft_clitter += patchpft.litter_leaf + patchpft.litter_root + patchpft.litter_sap + patchpft.litter_heart + patchpft.litter_repr;
  763. standpft_nlitter += patchpft.nmass_litter_leaf + patchpft.nmass_litter_root + patchpft.nmass_litter_sap + patchpft.nmass_litter_heart;
  764. vegetation.firstobj();
  765. while (vegetation.isobj) {
  766. Individual& indiv = vegetation.getobj();
  767. if (indiv.id != -1 && indiv.alive) {
  768. if (indiv.pft.id == pft.id) {
  769. standpft_cmass_leaf += indiv.cmass_leaf;
  770. standpft_cmass += indiv.ccont();
  771. standpft_nmass += indiv.ncont();
  772. standpft_nmass_leaf += indiv.cmass_leaf / indiv.cton_leaf_aavr;
  773. standpft_nmass_veg += indiv.nmass_veg;
  774. standpft_fpc += indiv.fpc;
  775. standpft_aaet += indiv.aaet;
  776. standpft_lai += indiv.lai;
  777. if (pft.lifeform == TREE) {
  778. standpft_densindiv_total += indiv.densindiv;
  779. heightindiv_total += indiv.height * indiv.densindiv;
  780. }
  781. standpft_vmaxnlim += indiv.avmaxnlim * indiv.cmass_leaf;
  782. standpft_nuptake += indiv.anuptake;
  783. if (pft.landcover == URBAN) {
  784. gridcell_urbanfpc += indiv.fpc * to_gridcell_average;
  785. }
  786. if (pft.landcover == CROPLAND) {
  787. standpft_cmass_veg += indiv.cmass_leaf + indiv.cmass_root;
  788. if (indiv.cropindiv) {
  789. standpft_cmass_veg += indiv.cropindiv->cmass_ho + indiv.cropindiv->cmass_agpool + indiv.cropindiv->cmass_stem;
  790. standpft_nmass_leaf += indiv.cropindiv->ynmass_leaf + indiv.cropindiv->ynmass_dead_leaf;
  791. standpft_nmass_veg += indiv.cropindiv->ycmass_leaf + indiv.cropindiv->ynmass_dead_leaf + indiv.cropindiv->ynmass_root + indiv.cropindiv->ynmass_ho + indiv.cropindiv->ynmass_agpool;
  792. }
  793. if (!indiv.pft.isintercropgrass) {
  794. gridcell_cropfpc += max(0.0, 1.0 - exp(-.5 * min(500.0, indiv.lai))) * to_gridcell_average;
  795. }
  796. }
  797. else {
  798. standpft_cmass_veg += indiv.cmass_veg;
  799. }
  800. if (pft.landcover == PASTURE) {
  801. gridcell_pasturefpc += indiv.fpc * to_gridcell_average;
  802. }
  803. if (pft.landcover == FOREST) {
  804. gridcell_forestfpc += indiv.fpc * to_gridcell_average;
  805. }
  806. if (pft.landcover == NATURAL) {
  807. if (pft.lifeform == GRASS)
  808. fpc_grass_patch += indiv.fpc * to_gridcell_average;
  809. else
  810. fpc_tree_patch += indiv.fpc * to_gridcell_average;
  811. }
  812. if (pft.landcover == PEATLAND) {
  813. gridcell_peatfpc += indiv.fpc * to_gridcell_average;
  814. }
  815. if (pft.landcover == BARREN) {
  816. gridcell_barrenfpc += indiv.fpc * to_gridcell_average;
  817. }
  818. }
  819. } // alive?
  820. vegetation.nextobj();
  821. }
  822. // Tree FPC shouldn't be larger than total patch area
  823. if (fpc_tree_patch > to_gridcell_average)
  824. fpc_tree_patch = to_gridcell_average;
  825. // Tree and grass FPC shouldn't be larger than total patch area (trees shade grass)
  826. if (fpc_tree_patch + fpc_grass_patch > to_gridcell_average)
  827. fpc_grass_patch = to_gridcell_average - fpc_tree_patch;
  828. gridcell_treefpc += fpc_tree_patch;
  829. gridcell_grassfpc += fpc_grass_patch;
  830. stand.nextobj();
  831. } // end of patch loop
  832. standpft_cmass /= (double)stand.npatch();
  833. standpft_nmass /= (double)stand.npatch();
  834. standpft_cmass_leaf /= (double)stand.npatch();
  835. standpft_nmass_leaf /= (double)stand.npatch();
  836. standpft_cmass_veg /= (double)stand.npatch();
  837. standpft_nmass_veg /= (double)stand.npatch();
  838. standpft_clitter /= (double)stand.npatch();
  839. standpft_nlitter /= (double)stand.npatch();
  840. standpft_anpp /= (double)stand.npatch();
  841. standpft_agpp /= (double)stand.npatch();
  842. standpft_fpc /= (double)stand.npatch();
  843. standpft_aaet /= (double)stand.npatch();
  844. standpft_lai /= (double)stand.npatch();
  845. standpft_densindiv_total /= (double)stand.npatch();
  846. standpft_aiso /= (double)stand.npatch();
  847. standpft_amon /= (double)stand.npatch();
  848. standpft_amon_mt1 /= (double)stand.npatch();
  849. standpft_amon_mt2 /= (double)stand.npatch();
  850. standpft_nuptake /= (double)stand.npatch();
  851. standpft_vmaxnlim /= (double)stand.npatch();
  852. heightindiv_total /= (double)stand.npatch();
  853. if (!negligible(standpft_cmass_leaf))
  854. standpft_vmaxnlim /= standpft_cmass_leaf;
  855. //Update landcover totals
  856. // ecev3 - remove!!!
  857. double thisstandsLCfrac = stand.get_landcover_fraction();
  858. double thisstandsgridcellfraction = stand.get_gridcell_fraction();
  859. landcover_cmass[stand.landcover] += standpft_cmass*stand.get_landcover_fraction();
  860. landcover_nmass[stand.landcover] += standpft_nmass*stand.get_landcover_fraction();
  861. landcover_cmass_leaf[stand.landcover] += standpft_cmass_leaf*stand.get_landcover_fraction();
  862. landcover_nmass_leaf[stand.landcover] += standpft_nmass_leaf*stand.get_landcover_fraction();
  863. landcover_cmass_veg[stand.landcover] += standpft_cmass_veg*stand.get_landcover_fraction();
  864. landcover_nmass_veg[stand.landcover] += standpft_nmass_veg*stand.get_landcover_fraction();
  865. landcover_clitter[stand.landcover] += standpft_clitter*stand.get_landcover_fraction();
  866. landcover_nlitter[stand.landcover] += standpft_nlitter*stand.get_landcover_fraction();
  867. landcover_anpp[stand.landcover] += standpft_anpp*stand.get_landcover_fraction();
  868. landcover_agpp[stand.landcover] += standpft_agpp*stand.get_landcover_fraction();
  869. if (!pft.isintercropgrass) {
  870. landcover_fpc[stand.landcover] += standpft_fpc*stand.get_landcover_fraction();
  871. landcover_lai[stand.landcover] += standpft_lai*stand.get_landcover_fraction();
  872. }
  873. landcover_aaet[stand.landcover] += standpft_aaet*stand.get_landcover_fraction();
  874. landcover_densindiv_total[stand.landcover] += standpft_densindiv_total*stand.get_landcover_fraction();
  875. landcover_aiso[stand.landcover] += standpft_aiso*stand.get_landcover_fraction();
  876. landcover_amon[stand.landcover] += standpft_amon*stand.get_landcover_fraction();
  877. landcover_amon_mt1[stand.landcover] += standpft_amon_mt1*stand.get_landcover_fraction();
  878. landcover_amon_mt2[stand.landcover] += standpft_amon_mt2*stand.get_landcover_fraction();
  879. landcover_nuptake[stand.landcover] += standpft_nuptake*stand.get_landcover_fraction();
  880. landcover_vmaxnlim[stand.landcover] += standpft_vmaxnlim*standpft_cmass_leaf*stand.get_landcover_fraction();
  881. //Update pft means for active stands
  882. if (active_fraction) {
  883. mean_standpft_cmass += standpft_cmass * stand.get_gridcell_fraction() / active_fraction;
  884. mean_standpft_nmass += standpft_nmass * stand.get_gridcell_fraction() / active_fraction;
  885. mean_standpft_cmass_leaf += standpft_cmass_leaf * stand.get_gridcell_fraction() / active_fraction;
  886. mean_standpft_nmass_leaf += standpft_nmass_leaf * stand.get_gridcell_fraction() / active_fraction;
  887. mean_standpft_cmass_veg += standpft_cmass_veg * stand.get_gridcell_fraction() / active_fraction;
  888. mean_standpft_nmass_veg += standpft_nmass_veg * stand.get_gridcell_fraction() / active_fraction;
  889. mean_standpft_clitter += standpft_clitter * stand.get_gridcell_fraction() / active_fraction;
  890. mean_standpft_nlitter += standpft_nlitter * stand.get_gridcell_fraction() / active_fraction;
  891. mean_standpft_anpp += standpft_anpp * stand.get_gridcell_fraction() / active_fraction;
  892. mean_standpft_agpp += standpft_agpp * stand.get_gridcell_fraction() / active_fraction;
  893. mean_standpft_fpc += standpft_fpc * stand.get_gridcell_fraction() / active_fraction;
  894. mean_standpft_aaet += standpft_aaet * stand.get_gridcell_fraction() / active_fraction;
  895. mean_standpft_lai += standpft_lai * stand.get_gridcell_fraction() / active_fraction;
  896. mean_standpft_densindiv_total += standpft_densindiv_total * stand.get_gridcell_fraction() / active_fraction;
  897. mean_standpft_aiso += standpft_aiso * stand.get_gridcell_fraction() / active_fraction;
  898. mean_standpft_amon += standpft_amon * stand.get_gridcell_fraction() / active_fraction;
  899. mean_standpft_amon_mt1 += standpft_amon_mt1 * stand.get_gridcell_fraction() / active_fraction;
  900. mean_standpft_amon_mt2 += standpft_amon_mt2 * stand.get_gridcell_fraction() / active_fraction;
  901. mean_standpft_nuptake += standpft_nuptake * stand.get_gridcell_fraction() / active_fraction;
  902. mean_standpft_vmaxnlim += standpft_vmaxnlim * standpft_cmass_leaf * stand.get_gridcell_fraction() / active_fraction;
  903. }
  904. //Update stand totals
  905. stand.anpp += standpft_anpp;
  906. stand.cmass += standpft_cmass;
  907. // Update gridcell totals
  908. double fraction_of_gridcell = stand.get_gridcell_fraction();
  909. cmass_gridcell += standpft_cmass*fraction_of_gridcell;
  910. nmass_gridcell += standpft_nmass*fraction_of_gridcell;
  911. cmass_leaf_gridcell += standpft_cmass_leaf*fraction_of_gridcell;
  912. nmass_leaf_gridcell += standpft_nmass_leaf*fraction_of_gridcell;
  913. cmass_veg_gridcell += standpft_cmass_veg*fraction_of_gridcell;
  914. nmass_veg_gridcell += standpft_nmass_veg*fraction_of_gridcell;
  915. clitter_gridcell += standpft_clitter*fraction_of_gridcell;
  916. nlitter_gridcell += standpft_nlitter*fraction_of_gridcell;
  917. anpp_gridcell += standpft_anpp*fraction_of_gridcell;
  918. agpp_gridcell += standpft_agpp*fraction_of_gridcell;
  919. if (!pft.isintercropgrass) {
  920. fpc_gridcell += standpft_fpc*fraction_of_gridcell;
  921. lai_gridcell += standpft_lai*fraction_of_gridcell;
  922. }
  923. aaet_gridcell += standpft_aaet*fraction_of_gridcell;
  924. dens_gridcell += standpft_densindiv_total*fraction_of_gridcell;
  925. aiso_gridcell += standpft_aiso*fraction_of_gridcell;
  926. amon_gridcell += standpft_amon*fraction_of_gridcell;
  927. amon_mt1_gridcell += standpft_amon_mt1*fraction_of_gridcell;
  928. amon_mt2_gridcell += standpft_amon_mt2*fraction_of_gridcell;
  929. nuptake_gridcell += standpft_nuptake*fraction_of_gridcell;
  930. vmaxnlim_gridcell += standpft_vmaxnlim*standpft_cmass_leaf*fraction_of_gridcell;
  931. // Graphical output every PLOT_INTERVAL years
  932. // (Windows shell only - "plot" statements have no effect otherwise)
  933. if (!(date.year%PLOT_INTERVAL)) {
  934. plot("C mass [kgC/m2]", pft.name, date.year, mean_standpft_cmass);
  935. plot("NPP [kgC/m2/yr]", pft.name, date.year, mean_standpft_anpp);
  936. plot("LAI [m2/m2]", pft.name, date.year, mean_standpft_lai);
  937. if (pft.lifeform == TREE) plot("Dens [indiv/ha]", pft.name, date.year, mean_standpft_densindiv_total*m2toha);
  938. if (mean_standpft_cmass_leaf > 0.0 && mean_standpft_nmass_leaf > 0.0 && ifnlim) {
  939. plot("Vmax N lim", pft.name, date.year, mean_standpft_vmaxnlim / mean_standpft_cmass_leaf);
  940. plot("leaf C:N [kgC/kg N]", pft.name, date.year, mean_standpft_cmass_leaf / mean_standpft_nmass_leaf);
  941. }
  942. }
  943. }//if(active)
  944. ++gc_itr;
  945. }//End of loop through stands
  946. // Print PFT sums to files
  947. double standpft_mean_cton_leaf = limited_cton(mean_standpft_cmass_leaf, mean_standpft_nmass_leaf);
  948. if (!negligible(mean_standpft_cmass_leaf))
  949. mean_standpft_vmaxnlim /= mean_standpft_cmass_leaf;
  950. outlimit(out, out_cmass, mean_standpft_cmass);
  951. outlimit(out, out_anpp, mean_standpft_anpp);
  952. outlimit(out, out_agpp, mean_standpft_agpp);
  953. outlimit(out, out_fpc, mean_standpft_fpc);
  954. outlimit(out, out_aaet, mean_standpft_aaet);
  955. outlimit(out, out_clitter, mean_standpft_clitter);
  956. outlimit(out, out_dens, mean_standpft_densindiv_total);
  957. outlimit(out, out_lai, mean_standpft_lai);
  958. outlimit(out, out_aiso, mean_standpft_aiso);
  959. outlimit(out, out_amon, mean_standpft_amon);
  960. outlimit(out, out_amon_mt1, mean_standpft_amon_mt1);
  961. outlimit(out, out_amon_mt2, mean_standpft_amon_mt2);
  962. outlimit(out, out_nmass, (mean_standpft_nmass + mean_standpft_nlitter) * m2toha);
  963. outlimit(out, out_cton_leaf, standpft_mean_cton_leaf);
  964. outlimit(out, out_vmaxnlim, mean_standpft_vmaxnlim);
  965. outlimit(out, out_nuptake, mean_standpft_nuptake * m2toha);
  966. outlimit(out, out_nlitter, mean_standpft_nlitter * m2toha);
  967. // print species heights
  968. double height = 0.0;
  969. if (mean_standpft_densindiv_total > 0.0)
  970. height = heightindiv_total / mean_standpft_densindiv_total;
  971. outlimit(out, out_speciesheights, height);
  972. pftlist.nextobj();
  973. } // *** End of PFT loop ***
  974. flux_veg = flux_repr = flux_soil = flux_fire = flux_est = flux_debexcc = flux_seed = flux_charvest = 0.0;
  975. // guess2008 - carbon pools
  976. c_fast = c_slow = c_harv_slow = 0.0;
  977. surfsoillitterc = surfsoillittern = cwdc = cwdn = centuryc = centuryn = n_harv_slow = availn = 0.0;
  978. andep_gridcell = anfert_gridcell = anmin_gridcell = animm_gridcell = anfix_gridcell = 0.0;
  979. n_org_leach_gridcell = n_min_leach_gridcell = c_org_leach_gridcell = 0.0;
  980. flux_nh3 = flux_nox = flux_n2o = flux_n2 = flux_nsoil = flux_ntot = flux_nharvest = flux_nseed = 0.0;
  981. double c_org_leach_lc[NLANDCOVERTYPES];
  982. for (int i = 0; i < NLANDCOVERTYPES; i++) {
  983. c_org_leach_lc[i] = 0.0;
  984. }
  985. // Sum C fluxes, dead C pools and runoff across patches
  986. Gridcell::iterator gc_itr = gridcell.begin();
  987. // Loop through Stands
  988. while (gc_itr != gridcell.end()) {
  989. Stand& stand = *gc_itr;
  990. stand.firstobj();
  991. //Loop through Patches
  992. while (stand.isobj) {
  993. Patch& patch = stand.getobj();
  994. double to_gridcell_average = stand.get_gridcell_fraction() / (double)stand.npatch();
  995. // Sum C fluxes, dead C pools and runoff across patches
  996. flux_veg += -patch.fluxes.get_annual_flux(Fluxes::NPP)*to_gridcell_average;
  997. flux_repr += -patch.fluxes.get_annual_flux(Fluxes::REPRC)*to_gridcell_average;
  998. flux_soil += patch.fluxes.get_annual_flux(Fluxes::SOILC)*to_gridcell_average;
  999. flux_fire += patch.fluxes.get_annual_flux(Fluxes::FIREC)*to_gridcell_average;
  1000. flux_est += patch.fluxes.get_annual_flux(Fluxes::ESTC)*to_gridcell_average;
  1001. flux_debexcc += patch.fluxes.get_annual_flux(Fluxes::DEBEXCC)*to_gridcell_average;
  1002. flux_seed += patch.fluxes.get_annual_flux(Fluxes::SEEDC)*to_gridcell_average;
  1003. flux_charvest += patch.fluxes.get_annual_flux(Fluxes::HARVESTC)*to_gridcell_average;
  1004. flux_nseed += patch.fluxes.get_annual_flux(Fluxes::SEEDN)*to_gridcell_average;
  1005. flux_nharvest += patch.fluxes.get_annual_flux(Fluxes::HARVESTN)*to_gridcell_average;
  1006. flux_nh3 += patch.fluxes.get_annual_flux(Fluxes::NH3_FIRE)*to_gridcell_average;
  1007. flux_nox += patch.fluxes.get_annual_flux(Fluxes::NOx_FIRE)*to_gridcell_average;
  1008. flux_n2o += patch.fluxes.get_annual_flux(Fluxes::N2O_FIRE)*to_gridcell_average;
  1009. flux_n2 += patch.fluxes.get_annual_flux(Fluxes::N2_FIRE)*to_gridcell_average;
  1010. flux_nsoil += patch.fluxes.get_annual_flux(Fluxes::N_SOIL)*to_gridcell_average;
  1011. flux_ntot += (patch.fluxes.get_annual_flux(Fluxes::NH3_FIRE) +
  1012. patch.fluxes.get_annual_flux(Fluxes::NOx_FIRE) +
  1013. patch.fluxes.get_annual_flux(Fluxes::N2O_FIRE) +
  1014. patch.fluxes.get_annual_flux(Fluxes::N2_FIRE) +
  1015. patch.fluxes.get_annual_flux(Fluxes::N_SOIL)) * to_gridcell_average;
  1016. c_fast += patch.soil.cpool_fast*to_gridcell_average;
  1017. c_slow += patch.soil.cpool_slow*to_gridcell_average;
  1018. //Sum slow pools of harvested products
  1019. if (run_landcover && ifslowharvestpool) {
  1020. for (int q = 0; q < npft; q++) {
  1021. Patchpft& patchpft = patch.pft[q];
  1022. c_harv_slow += patchpft.harvested_products_slow*to_gridcell_average;
  1023. n_harv_slow += patchpft.harvested_products_slow_nmass*to_gridcell_average;
  1024. }
  1025. }
  1026. surfrunoff_gridcell += patch.asurfrunoff*to_gridcell_average;
  1027. drainrunoff_gridcell += patch.adrainrunoff*to_gridcell_average;
  1028. baserunoff_gridcell += patch.abaserunoff*to_gridcell_average;
  1029. runoff_gridcell += patch.arunoff*to_gridcell_average;
  1030. // Fire return time
  1031. if (!patch.has_fires() || patch.fireprob < 0.001)
  1032. firert_gridcell += 1000.0 * to_gridcell_average; // Set a limit of 1000 years
  1033. else
  1034. firert_gridcell += (1.0 / patch.fireprob) * to_gridcell_average;
  1035. andep_gridcell += stand.get_climate().andep * to_gridcell_average;
  1036. anfert_gridcell += patch.anfert * to_gridcell_average;
  1037. anmin_gridcell += patch.soil.anmin * to_gridcell_average;
  1038. animm_gridcell += patch.soil.animmob * to_gridcell_average;
  1039. anfix_gridcell += patch.soil.anfix * to_gridcell_average;
  1040. n_min_leach_gridcell += patch.soil.aminleach * to_gridcell_average;
  1041. n_org_leach_gridcell += patch.soil.aorgNleach * to_gridcell_average;
  1042. c_org_leach_gridcell += patch.soil.aorgCleach * to_gridcell_average;
  1043. availn += (patch.soil.nmass_avail + patch.soil.snowpack_nmass) * to_gridcell_average;
  1044. c_org_leach_lc[stand.landcover] += patch.soil.aorgCleach * to_gridcell_average;
  1045. for (int r = 0; r < NSOMPOOL - 1; r++) {
  1046. if (r == SURFMETA || r == SURFSTRUCT || r == SOILMETA || r == SOILSTRUCT) {
  1047. surfsoillitterc += patch.soil.sompool[r].cmass * to_gridcell_average;
  1048. surfsoillittern += patch.soil.sompool[r].nmass * to_gridcell_average;
  1049. }
  1050. else if (r == SURFFWD || r == SURFCWD) {
  1051. cwdc += patch.soil.sompool[r].cmass * to_gridcell_average;
  1052. cwdn += patch.soil.sompool[r].nmass * to_gridcell_average;
  1053. }
  1054. else {
  1055. centuryc += patch.soil.sompool[r].cmass * to_gridcell_average;
  1056. centuryn += patch.soil.sompool[r].nmass * to_gridcell_average;
  1057. }
  1058. }
  1059. airri += patch.irrigation_y*to_gridcell_average;
  1060. snow += patch.soil.snowpack*to_gridcell_average;
  1061. for (int lyr = 0; lyr < NSOILLAYER; lyr++) {
  1062. mois[lyr] += patch.soil.wcont[lyr] * patch.soil.soiltype.awc[lyr] * to_gridcell_average;
  1063. }
  1064. // Monthly output variables
  1065. for (m = 0; m < 12; m++) {
  1066. maet[m] += patch.maet[m] * to_gridcell_average;
  1067. mpet[m] += patch.mpet[m] * to_gridcell_average;
  1068. mevap[m] += patch.mevap[m] * to_gridcell_average;
  1069. mintercep[m] += patch.mintercep[m] * to_gridcell_average;
  1070. mrunoff[m] += patch.mrunoff[m] * to_gridcell_average;
  1071. mrh[m] += patch.fluxes.get_monthly_flux(Fluxes::SOILC, m)*to_gridcell_average;
  1072. mwcont_upper[m] += patch.soil.mwcont[m][0] * to_gridcell_average;
  1073. mwcont_lower[m] += patch.soil.mwcont[m][1] * to_gridcell_average;
  1074. mgpp[m] += patch.fluxes.get_monthly_flux(Fluxes::GPP, m)*to_gridcell_average;
  1075. mra[m] += patch.fluxes.get_monthly_flux(Fluxes::RA, m)*to_gridcell_average;
  1076. miso[m] += patch.fluxes.get_monthly_flux(Fluxes::ISO, m)*to_gridcell_average;
  1077. mmon[m] += patch.fluxes.get_monthly_flux(Fluxes::MT1, m)*to_gridcell_average;
  1078. mmon[m] += patch.fluxes.get_monthly_flux(Fluxes::MT2, m)*to_gridcell_average;
  1079. mmon_mt1[m] += patch.fluxes.get_monthly_flux(Fluxes::MT1, m)*to_gridcell_average;
  1080. mmon_mt2[m] += patch.fluxes.get_monthly_flux(Fluxes::MT2, m)*to_gridcell_average;
  1081. }
  1082. // Calculate monthly NPP and LAI
  1083. Vegetation& vegetation = patch.vegetation;
  1084. vegetation.firstobj();
  1085. while (vegetation.isobj) {
  1086. Individual& indiv = vegetation.getobj();
  1087. // guess2008 - alive check added
  1088. if (indiv.id != -1 && indiv.alive) {
  1089. for (m = 0; m < 12; m++) {
  1090. mlai[m] += indiv.mlai[m] * to_gridcell_average;
  1091. }
  1092. } // alive?
  1093. vegetation.nextobj();
  1094. } // while/vegetation loop
  1095. stand.nextobj();
  1096. } // patch loop
  1097. ++gc_itr;
  1098. } // stand loop
  1099. aprec = gridcell.climate.aprec;
  1100. // In contrast to annual NEE, monthly NEE does not include fire
  1101. // or establishment fluxes
  1102. for (m = 0; m < 12; m++) {
  1103. mnpp[m] = mgpp[m] - mra[m];
  1104. mnee[m] = mrh[m] - mnpp[m];
  1105. }
  1106. // Print gridcell totals to files
  1107. // Determine total leaf C:N ratio
  1108. double cton_leaf_gridcell = limited_cton(cmass_leaf_gridcell, nmass_leaf_gridcell);
  1109. // Determine total vmax nitrogen limitation
  1110. if (cmass_leaf_gridcell > 0.0) {
  1111. vmaxnlim_gridcell /= cmass_leaf_gridcell;
  1112. }
  1113. outlimit(out, out_cmass, cmass_gridcell);
  1114. outlimit(out, out_anpp, anpp_gridcell);
  1115. outlimit(out, out_agpp, agpp_gridcell);
  1116. outlimit(out, out_fpc, fpc_gridcell);
  1117. outlimit(out, out_aaet, aaet_gridcell);
  1118. outlimit(out, out_dens, dens_gridcell);
  1119. outlimit(out, out_lai, lai_gridcell);
  1120. outlimit(out, out_clitter, clitter_gridcell);
  1121. outlimit(out, out_firert, firert_gridcell);
  1122. outlimit(out, out_runoff, surfrunoff_gridcell);
  1123. outlimit(out, out_runoff, drainrunoff_gridcell);
  1124. outlimit(out, out_runoff, baserunoff_gridcell);
  1125. outlimit(out, out_runoff, runoff_gridcell);
  1126. outlimit(out, out_aiso, aiso_gridcell);
  1127. outlimit(out, out_amon, amon_gridcell);
  1128. outlimit(out, out_amon_mt1, amon_mt1_gridcell);
  1129. outlimit(out, out_amon_mt2, amon_mt2_gridcell);
  1130. outlimit(out, out_nmass, (nmass_gridcell + nlitter_gridcell) * m2toha);
  1131. outlimit(out, out_cton_leaf, cton_leaf_gridcell);
  1132. outlimit(out, out_vmaxnlim, vmaxnlim_gridcell);
  1133. outlimit(out, out_nuptake, nuptake_gridcell * m2toha);
  1134. outlimit(out, out_nlitter, nlitter_gridcell * m2toha);
  1135. outlimit(out, out_nsources, andep_gridcell * m2toha);
  1136. outlimit(out, out_nsources, anfix_gridcell * m2toha);
  1137. outlimit(out, out_nsources, anfert_gridcell * m2toha);
  1138. outlimit(out, out_nsources, (andep_gridcell + anfix_gridcell + anfert_gridcell) * m2toha);
  1139. outlimit(out, out_nsources, anmin_gridcell * m2toha);
  1140. outlimit(out, out_nsources, animm_gridcell * m2toha);
  1141. outlimit(out, out_nsources, (anmin_gridcell - animm_gridcell) * m2toha);
  1142. outlimit(out, out_nsources, (anmin_gridcell - animm_gridcell + andep_gridcell +
  1143. anfix_gridcell + anfert_gridcell) * m2toha);
  1144. // Print landcover totals to files
  1145. if (run_landcover) {
  1146. for (int i = 0; i < NLANDCOVERTYPES; i++) {
  1147. if (run[i]) {
  1148. outlimit(out, out_cmass, landcover_cmass[i]);
  1149. outlimit(out, out_anpp, landcover_anpp[i]);
  1150. outlimit(out, out_agpp, landcover_agpp[i]);
  1151. outlimit(out, out_fpc, landcover_fpc[i]);
  1152. outlimit(out, out_aaet, landcover_aaet[i]);
  1153. outlimit(out, out_dens, landcover_densindiv_total[i]);
  1154. outlimit(out, out_lai, landcover_lai[i]);
  1155. outlimit(out, out_clitter, landcover_clitter[i]);
  1156. outlimit(out, out_aiso, landcover_aiso[i]);
  1157. outlimit(out, out_amon, landcover_amon[i]);
  1158. outlimit(out, out_amon_mt1, landcover_amon_mt1[i]);
  1159. outlimit(out, out_amon_mt2, landcover_amon_mt2[i]);
  1160. // ecev3 - store landcover for LAI and FPC in the gridcell class
  1161. // NB! This does not include the intercropgrass
  1162. gridcell.landcover_fpc[i] = landcover_fpc[i];
  1163. gridcell.landcover_lai[i] = landcover_lai[i];
  1164. double landcover_cton_leaf = limited_cton(landcover_cmass_leaf[i],
  1165. landcover_nmass_leaf[i]);
  1166. if (landcover_cmass_leaf[i] > 0.0) {
  1167. landcover_vmaxnlim[i] /= landcover_cmass_leaf[i];
  1168. }
  1169. outlimit(out, out_nmass, (landcover_nmass[i] + landcover_nlitter[i]) * m2toha);
  1170. outlimit(out, out_cton_leaf, landcover_cton_leaf);
  1171. outlimit(out, out_vmaxnlim, landcover_vmaxnlim[i]);
  1172. outlimit(out, out_nuptake, landcover_nuptake[i] * m2toha);
  1173. outlimit(out, out_nlitter, landcover_nlitter[i] * m2toha);
  1174. }
  1175. }
  1176. }
  1177. else {
  1178. // ecev3 - store landcover for LAI and FPC in the gridcell class, NATURAL only
  1179. gridcell.landcover_fpc[NATURAL] = landcover_fpc[NATURAL];
  1180. gridcell.landcover_lai[NATURAL] = landcover_lai[NATURAL];
  1181. }
  1182. // Print monthly output variables
  1183. for (m = 0; m < 12; m++) {
  1184. outlimit(out, out_mnpp, mnpp[m]);
  1185. outlimit(out, out_mlai, mlai[m]);
  1186. outlimit(out, out_mgpp, mgpp[m]);
  1187. outlimit(out, out_mra, mra[m]);
  1188. outlimit(out, out_maet, maet[m]);
  1189. outlimit(out, out_mpet, mpet[m]);
  1190. outlimit(out, out_mevap, mevap[m]);
  1191. outlimit(out, out_mrunoff, mrunoff[m]);
  1192. outlimit(out, out_mintercep, mintercep[m]);
  1193. outlimit(out, out_mrh, mrh[m]);
  1194. outlimit(out, out_mnee, mnee[m]);
  1195. outlimit(out, out_mwcont_upper, mwcont_upper[m]);
  1196. outlimit(out, out_mwcont_lower, mwcont_lower[m]);
  1197. outlimit(out, out_miso, miso[m]);
  1198. outlimit(out, out_mmon, mmon[m]);
  1199. outlimit(out, out_mmon_mt1, mmon_mt1[m]);
  1200. outlimit(out, out_mmon_mt2, mmon_mt2[m]);
  1201. aaet += maet[m];
  1202. apet += mpet[m];
  1203. aevap += mevap[m];
  1204. arunoff += mrunoff[m];
  1205. aintercep += mintercep[m];
  1206. }
  1207. // ecev3 - add gridcell vegetation output as sent to IFS
  1208. // Rescale if FPC > Land cover fraction
  1209. double natural_frac = gridcell.landcover.frac[NATURAL];
  1210. double cropland_frac = gridcell.landcover.frac[CROPLAND];
  1211. double pasture_frac = gridcell.landcover.frac[PASTURE];
  1212. double urban_frac = gridcell.landcover.frac[URBAN];
  1213. double peatland_frac = gridcell.landcover.frac[PEATLAND];
  1214. // If Natural tree bigger than cover fracton -> tree cover all fraction, grass zero
  1215. if (gridcell_treefpc > natural_frac) {
  1216. gridcell_treefpc = natural_frac;
  1217. gridcell_grassfpc = 0.0;
  1218. }
  1219. double fpc_natural_daily = gridcell_grassfpc + gridcell_treefpc;
  1220. if (fpc_natural_daily > natural_frac) {
  1221. gridcell_grassfpc = natural_frac - gridcell_treefpc; // Trees covers low vegetation
  1222. }
  1223. // Pasture
  1224. if (gridcell_pasturefpc > pasture_frac) {
  1225. gridcell_pasturefpc = pasture_frac;
  1226. }
  1227. // Urban
  1228. if (gridcell_urbanfpc > urban_frac) {
  1229. gridcell_urbanfpc = urban_frac;
  1230. }
  1231. // Peatland
  1232. if (gridcell_peatfpc > peatland_frac) {
  1233. gridcell_peatfpc = peatland_frac;
  1234. }
  1235. // Cropland
  1236. if (gridcell_cropfpc > cropland_frac) {
  1237. gridcell_cropfpc = cropland_frac;
  1238. }
  1239. outlimit(out, out_fpc, gridcell.IFStypehigh);
  1240. outlimit(out, out_fpc, gridcell_forestfpc + gridcell_treefpc);
  1241. outlimit(out, out_fpc, gridcell.IFStypelow);
  1242. outlimit(out, out_fpc, gridcell_urbanfpc + gridcell_cropfpc + gridcell_pasturefpc + gridcell_grassfpc + gridcell_peatfpc);
  1243. outlimit(out, out_fpc, gridcell.climate.agdd5_5.mean());
  1244. outlimit(out, out_fpc, gridcell.awcont_5.mean());
  1245. outlimit(out, out_fpc, gridcell_urbanfpc);
  1246. outlimit(out, out_fpc, gridcell_cropfpc);
  1247. outlimit(out, out_fpc, gridcell_pasturefpc);
  1248. outlimit(out, out_fpc, gridcell_forestfpc);
  1249. outlimit(out, out_fpc, gridcell_grassfpc);
  1250. outlimit(out, out_fpc, gridcell_treefpc);
  1251. outlimit(out, out_fpc, gridcell_peatfpc);
  1252. outlimit(out, out_fpc, gridcell_barrenfpc);
  1253. // Graphical output every PLOT_INTERVAL years
  1254. // (Windows shell only - no effect otherwise)
  1255. if (!(date.year%PLOT_INTERVAL)) {
  1256. if (gridcell.nbr_stands() > 0) //Fixed bug here if no stands were present.
  1257. {
  1258. Stand& stand = gridcell[0];
  1259. plot("C flux [kgC/m2/yr]", "veg", date.year, flux_veg);
  1260. plot("C flux [kgC/m2/yr]", "repr", date.year, flux_repr);
  1261. plot("C flux [kgC/m2/yr]", "soil", date.year, flux_soil);
  1262. plot("C flux [kgC/m2/yr]", "fire", date.year, flux_fire);
  1263. plot("C flux [kgC/m2/yr]", "est", date.year, flux_est);
  1264. plot("C flux [kgC/m2/yr]", "NEE", date.year, flux_veg + flux_repr + flux_soil + flux_fire + flux_est - flux_debexcc);
  1265. if (!ifcentury) {
  1266. plot("Soil C [kgC/m2]", "slow", date.year, stand[0].soil.cpool_slow);
  1267. plot("Soil C [kgC/m2]", "fast", date.year, stand[0].soil.cpool_fast);
  1268. }
  1269. else {
  1270. plot("N flux [kgN/ha/yr]", "fix", date.year, -anfix_gridcell * m2toha);
  1271. plot("N flux [kgN/ha/yr]", "dep", date.year, -andep_gridcell * m2toha);
  1272. plot("N flux [kgN/ha/yr]", "fert", date.year, -anfert_gridcell * m2toha);
  1273. plot("N flux [kgN/ha/yr]", "leach", date.year, (n_min_leach_gridcell + n_org_leach_gridcell) * m2toha);
  1274. plot("N flux [kgN/ha/yr]", "emissions", date.year, flux_ntot * m2toha);
  1275. plot("N flux [kgN/ha/yr]", "NEE", date.year, (flux_ntot + n_min_leach_gridcell + n_org_leach_gridcell -
  1276. (anfix_gridcell + andep_gridcell + anfert_gridcell)) * m2toha);
  1277. plot("N mineralization [kgN/ha/yr]", "N", date.year, (anmin_gridcell - animm_gridcell) * m2toha);
  1278. plot("Soil C [kgC/m2]", "fine litter", date.year, surfsoillitterc);
  1279. plot("Soil C [kgC/m2]", "coarse litter", date.year, cwdc);
  1280. plot("Soil C [kgC/m2]", "soil", date.year, centuryc);
  1281. plot("Soil C [kgC/m2]", "total", date.year, surfsoillitterc + cwdc + centuryc);
  1282. plot("Soil N [kgN/m2]", "fine litter", date.year, surfsoillittern);
  1283. plot("Soil N [kgN/m2]", "coarse litter", date.year, cwdn);
  1284. plot("Soil N [kgN/m2]", "soil", date.year, centuryn);
  1285. plot("Soil N [kgN/m2]", "total", date.year, surfsoillittern + cwdn + centuryn);
  1286. }
  1287. plot("H2O flux [mm/yr]", "transp", date.year, aaet);
  1288. plot("H2O flux [mm/yr]", "intercep", date.year, aintercep);
  1289. plot("H2O flux [mm/yr]", "evap", date.year, aevap);
  1290. plot("H2O flux [mm/yr]", "runoff", date.year, arunoff);
  1291. plot("H2O flux [mm/yr]", "PET", date.year, apet);
  1292. }
  1293. }
  1294. // Write fluxes to file
  1295. Landcover& lc = gridcell.landcover;
  1296. outlimit(out, out_cflux, flux_veg);
  1297. outlimit(out, out_cflux, -flux_repr);
  1298. outlimit(out, out_cflux, flux_soil + c_org_leach_gridcell);
  1299. outlimit(out, out_cflux, flux_fire);
  1300. outlimit(out, out_cflux, flux_est - flux_debexcc);
  1301. if (run_landcover) {
  1302. outlimit(out, out_cflux, flux_seed);
  1303. outlimit(out, out_cflux, flux_charvest);
  1304. outlimit(out, out_cflux, lc.acflux_landuse_change);
  1305. outlimit(out, out_cflux, lc.acflux_harvest_slow);
  1306. }
  1307. outlimit(out, out_cflux, flux_veg - flux_repr + flux_soil + flux_fire + flux_est - flux_debexcc + c_org_leach_gridcell +
  1308. flux_seed + flux_charvest + lc.acflux_landuse_change + lc.acflux_harvest_slow);
  1309. outlimit(out,out_doc, (c_org_leach_gridcell) * m2toha);
  1310. if (run_landcover) {
  1311. for(int i=0;i<NLANDCOVERTYPES;i++) {
  1312. if(run[i]) {
  1313. outlimit(out,out_doc, c_org_leach_lc[i] * m2toha);
  1314. }
  1315. }
  1316. }
  1317. outlimit(out,out_nflux, -andep_gridcell * m2toha);
  1318. outlimit(out,out_nflux, -anfix_gridcell * m2toha);
  1319. outlimit(out,out_nflux, -anfert_gridcell * m2toha);
  1320. outlimit(out,out_nflux, flux_ntot * m2toha);
  1321. outlimit(out,out_nflux, (n_min_leach_gridcell + n_org_leach_gridcell) * m2toha);
  1322. if (run_landcover) {
  1323. outlimit(out,out_nflux, flux_nseed * m2toha);
  1324. outlimit(out,out_nflux, flux_nharvest * m2toha);
  1325. outlimit(out,out_nflux, lc.anflux_landuse_change * m2toha);
  1326. outlimit(out,out_nflux, lc.anflux_harvest_slow * m2toha);
  1327. }
  1328. outlimit(out,out_nflux, (flux_nharvest + lc.anflux_landuse_change +
  1329. lc.anflux_harvest_slow + flux_nseed + flux_ntot +
  1330. n_min_leach_gridcell + n_org_leach_gridcell -
  1331. (andep_gridcell + anfix_gridcell + anfert_gridcell)) * m2toha);
  1332. // CPOOL Write cpool to file
  1333. outlimit(out,out_cpool, cmass_gridcell);
  1334. if (!ifcentury) {
  1335. outlimit(out,out_cpool, clitter_gridcell);
  1336. outlimit(out,out_cpool, c_fast);
  1337. outlimit(out,out_cpool, c_slow);
  1338. }
  1339. else {
  1340. outlimit(out,out_cpool, clitter_gridcell + surfsoillitterc + cwdc);
  1341. outlimit(out,out_cpool, centuryc);
  1342. }
  1343. if (run_landcover && ifslowharvestpool) {
  1344. outlimit(out, out_cpool, c_harv_slow);
  1345. }
  1346. // Calculate total cpool, starting with cmass and litter...
  1347. double cpool_total = cmass_gridcell + clitter_gridcell;
  1348. // Add SOM pools
  1349. if (!ifcentury) {
  1350. cpool_total += c_fast + c_slow;
  1351. }
  1352. else {
  1353. cpool_total += centuryc + surfsoillitterc + cwdc;
  1354. }
  1355. // Add slow harvest pool if needed
  1356. if (run_landcover && ifslowharvestpool) {
  1357. cpool_total += c_harv_slow;
  1358. }
  1359. outlimit(out, out_cpool, cpool_total);
  1360. // NPOOL Write npool to file
  1361. if (ifcentury) {
  1362. outlimit(out,out_npool, nmass_gridcell + nlitter_gridcell);
  1363. outlimit(out,out_npool, surfsoillittern + cwdn);
  1364. outlimit(out,out_npool, centuryn + availn);
  1365. if (run_landcover && ifslowharvestpool) {
  1366. outlimit(out, out_npool, n_harv_slow);
  1367. outlimit(out, out_npool, (nmass_gridcell + nlitter_gridcell + surfsoillittern + cwdn + centuryn + availn + n_harv_slow));
  1368. }
  1369. else {
  1370. outlimit(out, out_npool, (nmass_gridcell + nlitter_gridcell + surfsoillittern + cwdn + centuryn + availn));
  1371. }
  1372. }
  1373. outlimit(out,out_ngases, flux_nh3 * m2toha);
  1374. outlimit(out,out_ngases, flux_nox * m2toha);
  1375. outlimit(out,out_ngases, flux_n2o * m2toha);
  1376. outlimit(out,out_ngases, flux_n2 * m2toha);
  1377. outlimit(out,out_ngases, flux_nsoil * m2toha);
  1378. outlimit(out,out_ngases, flux_ntot * m2toha);
  1379. outlimit(out,out_wflux, -aprec);
  1380. outlimit(out,out_wflux, -airri);
  1381. outlimit(out,out_wflux, apet);
  1382. outlimit(out,out_wflux, aaet);
  1383. outlimit(out,out_wflux, aintercep);
  1384. outlimit(out,out_wflux, aevap);
  1385. outlimit(out,out_wflux, surfrunoff_gridcell);
  1386. outlimit(out,out_wflux, drainrunoff_gridcell);
  1387. outlimit(out,out_wflux, baserunoff_gridcell);
  1388. outlimit(out,out_wflux, aaet + aintercep + aevap + surfrunoff_gridcell + drainrunoff_gridcell + baserunoff_gridcell - (aprec + airri));
  1389. outlimit(out,out_wpool, snow);
  1390. for (int lyr = 0; lyr < NSOILLAYER; lyr++) {
  1391. outlimit(out, out_wpool, mois[lyr]);
  1392. }
  1393. // Output of tree stand age structure, monthly soil water and 3D vegetation view
  1394. // (Windows shell only - no effect otherwise)
  1395. if (vegmode == COHORT || vegmode == INDIVIDUAL) {
  1396. if (!(date.year%PLOT_UPDATE_INTERVAL)) {
  1397. double* densindiv = NULL;
  1398. int nageclass;
  1399. get_stand_age_structure(gridcell, densindiv, nageclass, false);
  1400. if (nageclass) {
  1401. densindiv = new double[npft*nageclass];
  1402. if (densindiv) {
  1403. resetwindow("Age structure [indiv/ha]");
  1404. get_stand_age_structure(gridcell, densindiv, nageclass, true);
  1405. pftlist.firstobj();
  1406. while (pftlist.isobj) {
  1407. Pft& pft = pftlist.getobj();
  1408. if (pft.lifeform == TREE) {
  1409. for (c = 0; c < nageclass; c++)
  1410. plot("Age structure [indiv/ha]", pft.name,
  1411. c * estinterval + estinterval*0.5,
  1412. densindiv[pft.id*nageclass + c] * 1e4); // includes conversion from /m2 --> /ha
  1413. }
  1414. pftlist.nextobj();
  1415. }
  1416. delete[] densindiv;
  1417. }
  1418. }
  1419. }
  1420. }
  1421. if (!(date.year % PLOT_UPDATE_INTERVAL)) {
  1422. resetwindow("Soil water [%AWC]");
  1423. for (m = 0; m < 12; m++) {
  1424. plot("Soil water [%AWC]", "upper", m, mwcont_upper[m]);
  1425. plot("Soil water [%AWC]", "lower", m, mwcont_lower[m]);
  1426. }
  1427. }
  1428. if (vegmode == COHORT) {
  1429. if (!(date.year%VEG3D_UPDATE_INTERVAL)) {
  1430. if (date.year == 0) open3d();
  1431. output_vegetation(gridcell, pftlist);
  1432. }
  1433. }
  1434. //#endif
  1435. }
  1436. }
  1437. /// Output of simulation results at the end of each day
  1438. /** This function does not have to provide any information to the framework.
  1439. */
  1440. void CommonOutput::outdaily(Gridcell& gridcell) {
  1441. }
  1442. } // namespace