1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687 |
- ///////////////////////////////////////////////////////////////////////////////////////
- /// \file guess.h
- /// \brief Framework header file, LPJ-GUESS Combined Modular Framework
- ///
- /// This header file contains:
- /// (1) definitions of all main classes used by the framework and modules. Modules may
- /// require classes to contain certain member variables and functions (see module
- /// source files for details).
- /// (2) other type, constant and function definitions to be accessible throughout the
- /// model code.
- /// (3) a forward declaration of the framework function if this is not the main
- /// function.
- ///
- /// \author Ben Smith
- /// $Date: 2020-06-23 10:44:28 +0200 (mar, 23 jun 2020) $
- ///
- ///////////////////////////////////////////////////////////////////////////////////////
- #ifndef LPJ_GUESS_GUESS_H
- #define LPJ_GUESS_GUESS_H
- #define CRESCENDO_FACE
- #undef CRESCENDO_FACE
- ///////////////////////////////////////////////////////////////////////////////////////
- // #INCLUDES FOR LIBRARY HEADER FILES
- // C/C++ libraries required for member functions of classes defined in this file.
- // These libraries will also be available globally (so omit these #includes from source
- // files). In addition to various standard C/C++ runtime libraries, the framework
- // requires the following libraries (individual modules may use additional libraries)
- //
- // GUTIL
- // Includes class xtring, providing functionality for pointer-free dynamic handling
- // of character strings; wherever possible in LPJ-GUESS, strings are represented as
- // objects of type xtring rather than simple arrays of type char. GUTIL also provides
- // templates for dynamic collection classes (list arrays of various types), argument
- // processing for printf-style functions, timing functions and other utilities.
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <time.h>
- #include "gutil.h"
- #include <vector>
- #include <algorithm>
- #include "shell.h"
- #include "guessmath.h"
- #include "archive.h"
- #include "parameters.h"
- #include "guesscontainer.h"
- #include "lamarquendep.h"
- ///////////////////////////////////////////////////////////////////////////////////////
- // GLOBAL ENUMERATED TYPE DEFINITIONS
- /// Life form class for PFTs (trees, grasses)
- typedef enum {NOLIFEFORM, TREE, GRASS} lifeformtype;
- /// Phenology class for PFTs
- typedef enum {NOPHENOLOGY, EVERGREEN, RAINGREEN, SUMMERGREEN, CROPGREEN, ANY} phenologytype;
- /// Biochemical pathway for photosynthesis (C3 or C4)
- typedef enum {NOPATHWAY, C3, C4} pathwaytype;
- /// Leaf physiognomy types for PFTs
- typedef enum {NOLEAFTYPE, NEEDLELEAF, BROADLEAF} leafphysiognomytype;
- /// Units for insolation driving data
- /** Insolation can be expressed as:
- *
- * - Percentage sunshine
- * - Net instantaneous downward shortwave radiation flux (W/m2)
- * - Total (i.e. with no correction for surface albedo) instantaneous downward
- * shortwave radiation flux (W/m2)
- *
- * Radiation flux can be interpreted as W/m2 during daylight hours, or averaged
- * over the whole time step which it represents (24 hours in daily mode). For
- * this reason there are two enumerators for these insolation types (e.g. SWRAD
- * and SWRAD_TS).
- */
- typedef enum {
- /// No insolation type chosen
- NOINSOL,
- /// Percentage sunshine
- SUNSHINE,
- /// Net shortwave radiation flux during daylight hours (W/m2)
- NETSWRAD,
- /// Total shortwave radiation flux during daylight hours (W/m2)
- SWRAD,
- /// Net shortwave radiation flux during whole time step (W/m2)
- NETSWRAD_TS,
- /// Total shortwave radiation flux during whole time step (W/m2)
- SWRAD_TS
- } insoltype;
- /// CENTURY pool names, NSOMPOOL number of SOM pools
- typedef enum {SURFSTRUCT, SOILSTRUCT, SOILMICRO, SURFHUMUS, SURFMICRO, SURFMETA, SURFFWD, SURFCWD,
- SOILMETA, SLOWSOM, PASSIVESOM, LEACHED, NSOMPOOL} pooltype;
- /// Irrigation type for PFTs
- typedef enum {RAINFED, IRRIGATED} hydrologytype;
- /// Intercrop type for PFTs
- typedef enum {NOINTERCROP, NATURALGRASS} intercroptype;
- /// Seasonality type of gridcell
- /** 0:SEASONALITY_NO No seasonality
- * 1:SEASONALITY_PREC Precipitation seasonality only
- * 2:SEASONALITY_PRECTEMP Both temperature and precipitation seasonality, but "weak" temperature seasonality (coldest month > 10degC)
- * 3:SEASONALITY_TEMP Temperature seasonality only
- * 4:SEASONALITY_TEMPPREC Both temperature and precipitation seasonality, but temperature most important (coldest month < 10degC)
- * 5:SEASONALITY_TEMPWARM Temperature seasonality, always above 10 degrees (currently not used)
- */
- typedef enum {SEASONALITY_NO, SEASONALITY_PREC, SEASONALITY_PRECTEMP, SEASONALITY_TEMP, SEASONALITY_TEMPPREC} seasonality_type;
- /// Precipitation seasonality type of gridcell
- /** 0:DRY (minprec_pet20<=0.5 && maxprec_pet20<=0.5)
- * 1:DRY_INTERMEDIATE (minprec_pet20<=0.5 && maxprec_pet20>0.5 && maxprec_pet20<=1.0)
- * 2:DRY_WET (minprec_pet20<=0.5 && maxprec_pet20>1.0)
- * 3:INTERMEDIATE (minprec_pet20>0.5 && minprec_pet20<=1.0 && maxprec_pet20>0.5 && maxprec_pet20<=1.0)
- * 4:INTERMEDIATE_WET (minprec_pet20>0.5 && minprec_pet20<=1.0 && maxprec_pet20>1.0)
- * 5:WET (minprec_pet20>1.0 && maxprec_pet20>1.0)
- */
- typedef enum {DRY, DRY_INTERMEDIATE, DRY_WET, INTERMEDIATE, INTERMEDIATE_WET, WET} prec_seasonality_type;
- /// Temperature seasonality type of gridcell
- /** 0:COLD (mtemp_max20<=10)
- * 1:COLD_WARM (mtemp_min20<=10 && mtemp_max20>10 && mtemp_max20<=30)
- * 2:COLD_HOT (mtemp_min20<=10 && mtemp_max20>30)
- * 3:WARM (mtemp_min20>10 && mtemp_max20<=30)
- * 4:WARM_HOT (mtemp_min20>10 && mtemp_max20>30)
- * 5:HOT (mtemp_min20>30)
- */
- typedef enum {COLD, COLD_WARM, COLD_HOT, WARM, WARM_HOT, HOT} temp_seasonality_type;
- ///////////////////////////////////////////////////////////////////////////////////////
- // GLOBAL CONSTANTS
- /// number of soil layers modelled
- const int NSOILLAYER = 2;
- /// bvoc: number of monoterpene species used
- const int NMTCOMPOUNDS = NMTCOMPOUNDTYPES;
- // SOIL DEPTH VALUES
- /// soil upper layer depth (mm)
- const double SOILDEPTH_UPPER = 500.0;
- /// soil lower layer depth (mm)
- const double SOILDEPTH_LOWER = 1000.0;
- /// Year at which to calculate equilibrium soil carbon
- const int SOLVESOM_END=400;
- /// Year at which to begin documenting means for calculation of equilibrium soil carbon
- const int SOLVESOM_BEGIN = 350;
- /// Number of years to average growth efficiency over in function mortality
- const int NYEARGREFF = 5;
- /// Coldest day in N hemisphere (January 15)
- /** Used to decide when to start counting GDD's and leaf-on days
- * for summergreen phenology.
- */
- const int COLDEST_DAY_NHEMISPHERE = 14;
- /// Coldest day in S hemisphere (July 15)
- /** Used to decide when to start counting GDD's and leaf-on days
- * for summergreen phenology.
- */
- const int COLDEST_DAY_SHEMISPHERE = 195;
- /// Warmest day in N hemisphere (same as COLDEST_DAY_SHEMISPHERE)
- const int WARMEST_DAY_NHEMISPHERE = COLDEST_DAY_SHEMISPHERE;
- /// Warmest day in S hemisphere (same as COLDEST_DAY_NHEMISPHERE)
- const int WARMEST_DAY_SHEMISPHERE = COLDEST_DAY_NHEMISPHERE;
- /// number of years to average aaet over in function soilnadd
- const int NYEARAAET = 5;
- /// Priestley-Taylor coefficient (conversion factor from equilibrium evapotranspiration to PET)
- const double PRIESTLEY_TAYLOR = 1.32;
- // Solving Century SOM pools
- /// fraction of nyear_spinup minus freenyears at which to begin documenting for calculation of Century equilibrium
- const double SOLVESOMCENT_SPINBEGIN = 0.1;
- /// fraction of nyear_spinup minus freenyears at which to end documentation and start calculation of Century equilibrium
- const double SOLVESOMCENT_SPINEND = 0.3;
- /// Kelvin to deg c conversion
- const double K2degC = 273.15;
- /// Maximum number of crop rotation items
- const int NROTATIONPERIODS_MAX = 3;
- /// Conversion factor for CO2 from ppmv to mole fraction
- const double CO2_CONV = 1.0e-6;
- /// Initial carbon allocated to crop organs at sowing, kg m-2
- const double CMASS_SEED = 0.01;
- /// Precision in land cover fraction input
- const double INPUT_PRECISION = 1.0e-14;
- const double INPUT_ERROR = 0.5e-6;
- const double INPUT_RESOLUTION = INPUT_PRECISION - INPUT_PRECISION * INPUT_ERROR;
- ///////////////////////////////////////////////////////////////////////////////////////
- // FORWARD DECLARATIONS OF CLASSES DEFINED IN THIS FILE
- // Forward declarations of classes used as types (e.g. for reference variables in some
- // classes) before they are actually defined
- class Date;
- class Stand;
- class Patch;
- class Vegetation;
- class Individual;
- class Gridcell;
- class Patchpft;
- ///////////////////////////////////////////////////////////////////////////////////////
- // GLOBAL VARIABLES WITH EXTERNAL LINKAGE
- // These variables are defined in the framework source code file, and are accessible
- // throughout the code
- /// Object describing timing stage of simulation
- extern Date date;
- /// Number of possible PFTs
- extern int npft;
- /// Number of stand types in stlist
- extern int nst;
- /// Number of stand types per land cover
- extern int nst_lc[NLANDCOVERTYPES];
- /// Number of management types in stlist
- extern int nmt;
- /// General purpose object for handling simulation timing.
- /** In general, frameworks should use a single Date object for all simulation
- * timing.
- *
- * Member variables of the class (see below) provide various kinds of calender
- * and timing information, assuming init has been called to initialise the
- * object, and next() has been called at the end of each simulation day.
- */
- class Date {
- // MEMBER VARIABLES
- public:
- /// Maximum number of days in an LPJ-GUESS simulation year
- /** The standard version doesn't yet support leap years. */
- static const int MAX_YEAR_LENGTH = 366; // ecev3
- /// number of days in each month (0=January - 11=December)
- int ndaymonth[12];
- /// julian day of year (0-364; 0=Jan 1)
- int day;
- /// day of current month (0=first day)
- int dayofmonth;
- /// month number (0=January - 11=December)
- int month;
- /// year since start of simulation (0=first simulation year)
- int year;
- /// number of subdaily periods in a day (to be set in IO module)
- int subdaily;
- /// julian day for middle day of each month
- int middaymonth[12];
- /// true if last year of simulation, false otherwise
- bool islastyear;
- /// true if last month of year, false otherwise
- bool islastmonth;
- /// true if last day of month, false otherwise
- bool islastday;
- /// true if middle day of month, false otherwise
- bool ismidday;
- /// The calendar year corresponding to simulation year 0
- int first_calendar_year;
- /// ecev3
- int hour, minute, second;
- private:
- int nyear;
- // MEMBER FUNCTIONS
- public:
- /// Constructor function called automatically when Date object is created
- /** Do not call explicitly. Initialises some member variables. */
- Date() {
- const int data[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
- int month;
- int dayct = 0;
- for (month=0; month<12; month++) {
- ndaymonth[month] = data[month];
- middaymonth[month] = dayct + data[month] / 2;
- dayct += data[month];
- }
- subdaily = 1;
- first_calendar_year = 0;
- }
- /// Initialises date to day 0 of year 0 and sets intended number of simulation years
- /** Intended number of simulation years is only used to set islastyear flag,
- * actual simulation may be longer or shorter.
- *
- * \param nyearsim Intended number of simulation years
- */
- void init(int nyearsim) {
- nyear = nyearsim;
- day = month=year = dayofmonth = 0;
- islastmonth = islastday = ismidday = false;
- if (nyear == 1) islastyear = true;
- else islastyear = false;
-
- hour=minute=second=0; // ecev3
- }
- Date(int y,int m,int d,int h,int n,int s) {
- // Constructor with initialisation to given date and time
- init(1);
- set(y,m,d,h,n,s);
- }
- // ecev3
- void set(int y,int m,int d,int h,int n,int s) {
-
- int i;
- if (y != year || m != month || d != dayofmonth) {
- //timestep = 0;
- }
- year = y;
- // ecev3 - leap year?
- if (is_leap(year))
- ndaymonth[1] = 29;
- else
- ndaymonth[1] = 28;
- month = m;
- dayofmonth = d;
- day = d;
- hour = h;
- minute = n;
- second = s;
- for (i = 0; i < m; i++) {
- day += ndaymonth[i];
- }
- if (dayofmonth == ndaymonth[m] - 1)
- islastday = true;
- else
- islastday = false;
-
- if (m == 11)
- islastmonth = true;
- else
- islastmonth = false;
- if (y == nyear - 1)
- islastyear = true;
- else
- islastyear = false;
- if (dayofmonth == ndaymonth[m] / 2)
- ismidday = true;
- else
- ismidday = false;
- }
- /// Call at end of every simulation day to update member variables.
- void next() {
- if (islastday) {
- if (islastmonth) {
- dayofmonth = 0;
- day = 0;
- month = 0;
- year++;
- if (year == nyear - 1) islastyear = true;
- islastmonth = false;
- }
- else {
- day++;
- dayofmonth = 0;
- month++;
- if (month == 11) islastmonth = true;
- }
- islastday = false;
- }
- else {
- day++;
- dayofmonth++;
- if (dayofmonth == ndaymonth[month] / 2) ismidday = true;
- else {
- ismidday = false;
- if (dayofmonth == ndaymonth[month] - 1) islastday = true;
- }
- }
- }
- // \returns index (0-11) of previous month (11 if currently month 0).
- int prevmonth() {
- if (month > 0) return month - 1;
- return 11;
- }
- /// \returns index of next month (0 if currently month 11)
- int nextmonth() {
- if (month < 11) return month+1;
- return 0;
- }
- /// Check if the year is leap
- /** \param year Calendar year
- * The algorith is as follows: only year that are divisible by 4 could
- * potentially be leap (e.g., 1904), however, not if they're divisible by
- * 100 (e.g., 1900 is not leap), unless they're divisible by 400 (e.g., 2000
- * is still leap).
- */
- static bool is_leap(int year);// {
- // return (!(year % 4) && (year % 100 | !(year % 400)));
- //}
- /// Whether the current mode is diurnal
- bool diurnal() const { return subdaily > 1; }
- /// Sets calendar year for simulation year 0
- /** Astronomical year numbering is used, so year 1 BC is represented by 0,
- * 2 BC = -1 etc. See ISO 8601.
- */
- void set_first_calendar_year(int calendar_year) {
- first_calendar_year = calendar_year;
- }
- /// Returns the calendar year corresponding to the current simulation year
- /** Astronomical year numbering is used, so year 1 BC is represented by 0,
- * 2 BC = -1 etc. See ISO 8601.
- */
- int get_calendar_year() const {
- return year + first_calendar_year;
- }
- /// \returns the number of days in the current simulation year
- /** For this function to work properly in simulations with varying number
- * of days per year, the set_first_calendar_year must have been called first.
- *
- * Currently there is no support for leap years, so this function
- * always returns 365. */
- int year_length() const {
- if (is_leap(year)) // ecev3 - added leap year check
- return 366;
- else
- return 365;
- }
- /// Step n days from a date.
- /** Current implementation does not consider leap days, and the same
- * apply for the current use of the function through-out the model.
- */
- static int stepfromdate(int day, int step) {
- if(day < 0) // a negative value should not be a valid day
- return -1;
- else if(day + step > 0)
- return (day + step) % MAX_YEAR_LENGTH;
- else if(day + step < 0)
- return day + step + MAX_YEAR_LENGTH;
- else
- return 0;
- }
- /// \returns the number of days in a month in the current simulation year
- /** This function returns the number of days in a month
- */
- int month_length(int mth) {
- if (is_leap(year) && mth == 1) // ecev3 - leap year and February
- return 29;
- else
- return ndaymonth[mth];
- }
- };
- /// Object describing sub-daily periods
- class Day {
- public:
- /// Whether sub-daily period first/last within day (both true in daily mode)
- bool isstart, isend;
- /// Ordinal number of the sub-daily period [0, date.subdaily)
- int period;
- /// Constructs beginning of the day period (the only one in daily mode)
- Day() {
- isstart = true;
- isend = !date.diurnal();
- period = 0;
- }
- /// Advances to the next sub-daily period
- void next() {
- period++;
- isstart = false;
- isend = period == date.subdaily - 1;
- }
- };
- /// Object updating gridcell mass balance; currently used in framework()
- class MassBalance : public Serializable {
- int start_year;
- double ccont;
- double ccont_zero;
- double ccont_zero_scaled;
- double cflux;
- double cflux_zero;
- double ncont;
- double ncont_zero;
- double ncont_zero_scaled;
- double nflux;
- double nflux_zero;
- public:
- MassBalance() {
- start_year = nyear_spinup;
- ccont = 0.0;
- ccont_zero = 0.0;
- ccont_zero_scaled = 0.0;
- cflux = 0.0;
- cflux_zero = 0.0;
- ncont = 0.0;
- ncont_zero = 0.0;
- ncont_zero_scaled = 0.0;
- nflux = 0.0;
- nflux_zero = 0.0;
- }
- MassBalance(int start_yearX) {
- start_year = start_yearX;
- ccont = 0.0;
- ccont_zero = 0.0;
- ccont_zero_scaled = 0.0;
- cflux = 0.0;
- cflux_zero = 0.0;
- ncont = 0.0;
- ncont_zero = 0.0;
- ncont_zero_scaled = 0.0;
- nflux = 0.0;
- nflux_zero = 0.0;
- }
- void init(Gridcell& gridcell);
- void check(Gridcell& gridcell);
- // indiv and patch-level functions are for use with true crop stands only
- void init_indiv(Individual& indiv);
- bool check_indiv(Individual& indiv, bool check_harvest = false);
- bool check_indiv_C(Individual& indiv, bool check_harvest = false);
- bool check_indiv_N(Individual& indiv, bool check_harvest = false);
- void init_patch(Patch& patch);
- bool check_patch(Patch& patch, bool check_harvest = false);
- bool check_patch_C(Patch& patch, bool check_harvest = false);
- bool check_patch_N(Patch& patch, bool check_harvest = false);
- void check_year(Gridcell& gridcell);
- void check_period(Gridcell& gridcell);
- void serialize(ArchiveStream& arch);
- };
- /// Struct containing wood harvest information
- struct Wood_harvest_struct {
- double prim_frac;
- double prim_vol;
- double sec_mature_frac;
- double sec_mature_vol;
- double sec_young_frac;
- double sec_young_vol;
- void zero() {
- prim_frac = 0.0;
- prim_vol = 0.0;
- sec_mature_frac = 0.0;
- sec_mature_vol = 0.0;
- sec_young_frac = 0.0;
- sec_young_vol = 0.0;
- }
- };
- /// This struct contains the result of a photosynthesis calculation.
- /** \see photosynthesis */
- struct PhotosynthesisResult {// : public Serializable {
- /// Constructs an empty result
- PhotosynthesisResult() {
- clear();
- }
- /// Clears all members
- /** This is returned by the photosynthesis function when no photosynthesis
- * takes place.
- */
- void clear() {
- agd_g = 0;
- adtmm = 0;
- rd_g = 0;
- vm = 0;
- je = 0;
- nactive_opt = 0.0;
- vmaxnlim = 1.0;
- }
- /// RuBisCO capacity (gC/m2/day)
- double vm;
- /// gross daily photosynthesis (gC/m2/day)
- double agd_g;
- /// leaf-level net daytime photosynthesis
- /** expressed in CO2 diffusion units (mm/m2/day) */
- double adtmm;
- /// leaf respiration (gC/m2/day)
- double rd_g;
- /// PAR-limited photosynthesis rate (gC/m2/h)
- double je;
- /// optimal leaf nitrogen associated with photosynthesis (kgN/m2)
- double nactive_opt;
- /// nitrogen limitation on vm
- double vmaxnlim;
- /// net C-assimilation (gross photosynthesis minus leaf respiration) (kgC/m2/day)
- double net_assimilation() const {
- return (agd_g - rd_g) * 1e-3;
- }
- //void serialize(ArchiveStream& arch);
- };
- /// The Climate for a grid cell
- /** Stores all static and variable data relating to climate parameters, as well as
- * latitude, atmospheric CO2 concentration and daylength for a grid cell. Includes
- * a reference to the parent Gridcell object (defined below). Initialised by a
- * call to initdrivers.
- */
- class Climate : public Serializable {
- // MEMBER VARIABLES
- public:
- /// reference to parent Gridcell object
- Gridcell& gridcell;
- /// mean air temperature today (deg C)
- double temp;
- /// total daily net downward shortwave solar radiation today (J/m2/day)
- double rad;
- /// total daily photosynthetically-active radiation today (J/m2/day)
- double par;
- /// precipitation today (mm)
- double prec;
- /// day length today (h)
- double daylength;
- /// atmospheric ambient CO2 concentration today (ppmv)
- double co2;
- /// monthly atmospheric ambient CO2 concentration (ppmv)
- double mco2[12];
- /// latitude (degrees; +=north, -=south)
- double lat;
- /// Insolation today, see also instype
- double insol;
- /// Type of insolation
- /** This decides how to interpret the variable insol,
- * see also documentation for the insoltype enum.
- */
- insoltype instype;
- /// net LW today. Used to calculate eet
- double netlw;
- /// equilibrium evapotranspiration today (mm/day)
- double eet;
- /// mean temperature for the last 31 days (deg C)
- double mtemp;
- /// mean of lowest mean monthly temperature for the last 20 years (deg C)
- double mtemp_min20;
- /// mean of highest mean monthly temperature for the last 20 years (deg C)
- double mtemp_max20;
- /// highest mean monthly temperature for the last 12 months (deg C)
- double mtemp_max;
- /// accumulated growing degree day sum on 5 degree base
- /** reset when temperatures fall below 5 deg C */
- double gdd5;
- /// total gdd5 (accumulated) for this year (reset 1 January)
- double agdd5;
- /// total gdd5 for this year for each of the last five simulation years
- Historic<double, 5> agdd5_5;
- /// number of days with temperatures <5 deg C
- /** reset when temperatures fall below 5 deg C;
- * maximum value is number of days in the year */
- int chilldays;
- /// true if chill day count may be reset by temperature fall below 5 deg C
- bool ifsensechill;
- /** Respiration response to today's air temperature incorporating damping of Q10
- * due to temperature acclimation (Lloyd & Taylor 1994)
- */
- double gtemp;
- /// daily temperatures for the last 31 days (deg C)
- Historic<double, 31> dtemp_31;
- /// daily precipitation for the last 31 days (deg C)
- Historic<double, 31> dprec_31;
- /// daily eet for the last 31 days (deg C)
- Historic<double, 31> deet_31;
- /// minimum monthly temperatures for the last 20 years (deg C)
- double mtemp_min_20[20];
- /// maximum monthly temperatures for the last 20 years (deg C)
- double mtemp_max_20[20];
- /// minimum monthly temperature for the last 12 months (deg C)
- double mtemp_min;
- /// mean of monthly temperatures for the last 12 months (deg C)
- double atemp_mean;
- /// annual nitrogen deposition (kgN/m2/year)
- double andep;
- /// daily nitrogen deposition (kgN/m2)
- double dndep;
- // ecev3 - needed if we're forcing with IFS soil properties:
- double ifssoiltemp;
- double ifsw_surf;
- double ifsw_deep;
- // Saved parameters used by function daylengthinsoleet
- double sinelat;
- double cosinelat;
- double qo[Date::MAX_YEAR_LENGTH];
- double u[Date::MAX_YEAR_LENGTH];
- double v[Date::MAX_YEAR_LENGTH];
- double hh[Date::MAX_YEAR_LENGTH];
- double sinehh[Date::MAX_YEAR_LENGTH];
- double daylength_save[Date::MAX_YEAR_LENGTH];
- /// indicates whether saved values exist for this day
- bool doneday[Date::MAX_YEAR_LENGTH];
- /// diurnal temperature range, used in daily/monthly BVOC (deg C)
- double dtr;
- // containers for sub-daily values of temperature, short-wave downward
- // radiation, par, rad and gtemp (equivalent to temp, insol, par, rad and gtemp)
- // NB: units of these variable are the same as their daily counterparts,
- // i.e. representing daily averages (e.g. pars [J/m2/day])
- /// Sub-daily temperature (deg C) (\see temp)
- std::vector<double> temps;
- /// Sub-daily insolation (\see insol)
- std::vector<double> insols;
- /// Sub-daily PAR (\see par)
- std::vector<double> pars;
- /// Sub-daily net downward shortwave solar radiation (\see rad)
- std::vector<double> rads;
- /// Sub-daily respiration response (\see gtemp)
- std::vector<double> gtemps;
- /// Variables used for crop sowing date or seasonality calculation
- /// daily precipitations for the last 10 days (mm)
- double dprec_10[10];
- /// daily 10 day-sums of precipitations for today and yesterday (mm)
- double sprec_2[2];
- /// max temperature during the last test period
- double maxtemp;
- /// summer day when we test last year's crossing of sowing temperature limits; NH:June 30(day 180), SH:Dec.31(day 364), set in getgridcell()
- int testday_temp;
- /// last day of dry month when we test last year's crossing of sowing precipitation limits; NH:Dec.31(day 364), SH:June 30(day 180), set in getgridcell()
- int testday_prec;
- /// date used for sowing if no frost or spring occured during the year between the testmonths; NH:14, SH:195, set in getgridcell()
- int coldestday;
- /// used to adapt equations to hemisphere, set in getgridcell()
- int adjustlat;
- /// accumulated monthly pet values for this year
- double mpet_year[12];
- /// past 20 years monthly temperature values
- double mtemp_20[20][12];
- /// past 20 years monthly precipitation values
- double mprec_20[20][12];
- /// past 20 years monthly PET values
- double mpet_20[20][12];
- /// past 20 years monthly precipitation to PET ratios
- double mprec_pet_20[20][12];
- /// past 20 years minimum of monthly precipitation to PET ratios
- double mprec_petmin_20[20];
- /// past 20 years maximum of monthly precipitation to PET ratios
- double mprec_petmax_20[20];
- /// 20-year running average monthly temperature values
- double mtemp20[12];
- /// 20-year running average monthly precipitation values
- double mprec20[12];
- /// 20-year running average monthly PET values
- double mpet20[12];
- /// 20-year running average monthly precipitation to PET ratios
- double mprec_pet20[12];
- /// 20-year running average of minimum monthly precipitation to PET ratios
- double mprec_petmin20;
- /// 20-year running average of maximum monthly precipitation to PET ratios
- double mprec_petmax20;
- Historic<double, 20> hmtemp_20[12];
- Historic<double, 20> hmprec_20[12];
- Historic<double, 20> hmeet_20[12];
- /// seasonality type (SEASONALITY_NO, SEASONALITY_PREC, SEASONALITY_PRECTEMP, SEASONALITY_TEMP, SEASONALITY_TEMPPREC)
- seasonality_type seasonality;
- seasonality_type seasonality_lastyear;
- /// precipitation seasonality type (DRY, DRY_INTERMEDIATE, DRY_WET, INTERMEDIATE, INTERMEDIATE_WET, WET)
- /** based on the extremes of the 20-year monthly means
- */
- prec_seasonality_type prec_seasonality;
- prec_seasonality_type prec_seasonality_lastyear;
- /// precipitation range (DRY, DRY_INTERMEDIATE, DRY_WET, INTERMEDIATE, INTERMEDIATE_WET, WET)
- /** based on the average of the 20-year monthly extremes
- */
- prec_seasonality_type prec_range;
- prec_seasonality_type prec_range_lastyear;
- /// temperature seasonality (COLD, COLD_WARM, COLD_HOT, WARM, WARM_HOT, HOT)
- temp_seasonality_type temp_seasonality;
- temp_seasonality_type temp_seasonality_lastyear;
- /// whether several months with precipitation maxima exists (remains to be implemented)
- bool biseasonal;
- /// variation coefficient of 20-year mean monthly temperatures
- double var_prec;
- /// variation coefficient of 20-year mean monthly precipitation to PET ratios
- double var_temp;
- /// annual precipitation sum
- double aprec;
- /// CRESCENDO physical variables output
- /// Near Surface Air Temperature [K]
- double mtemp_K[12];
- /// Precipitation [kg m-2 s-1]
- double mprec[12];
- /// Daily precipitation [kg m-2 s-1]
- double dprec[366];
- /// Surface Downwelling Shortwave Radiation [W m-2]
- double mrsds[12];
- #ifdef CRESCENDO_FACE
- /// Daily CO2 (mean ppm)
- double co2_daily[366];
- /// Daily PAR (mol day-1)
- double par_daily[366];
- /// Daily Air Temperature (mean oC)
- double at_daily[366];
- /// Daily N deposition (gN m-2 day-1)
- double ndep_daily[366];
- #endif
- public:
- /// constructor function: initialises gridcell member
- Climate(Gridcell& gc):gridcell(gc) {
- for(int m=0;m<12;m++) {
- mtemp20[m] = 0.0;
- mprec20[m] = 0.0;
- mpet20[m] = 0.0;
- mpet_year[m] = 0.0;
- mprec_pet20[m] = 0.0;
- for(int y=0;y<20;y++) {
- mtemp_20[y][m] = 0.0;
- mprec_20[y][m] = 0.0;
- mpet_20[y][m] = 0.0;
- mprec_pet_20[y][m] = 0.0;
- }
- }
- for(int y=0;y<20;y++) {
- mprec_petmin_20[y] = 0.0;
- mprec_petmax_20[y] = 0.0;
- }
- mprec_petmin20=0.0;
- mprec_petmax20=0.0;
- seasonality=SEASONALITY_NO;
- seasonality_lastyear=SEASONALITY_NO;
- prec_seasonality=DRY;
- prec_seasonality_lastyear=DRY;
- prec_range=DRY;
- prec_range_lastyear=DRY;
- temp_seasonality=COLD;
- temp_seasonality_lastyear=COLD;
- biseasonal=false;
- eet=0.0;
- };
- /// Initialises certain member variables
- /** Should be called before Climate object is applied to a new grid cell */
- void initdrivers(double latitude) {
- std::fill_n(mtemp_min_20, 20, 0.0);
- std::fill_n(mtemp_max_20, 20, 0.0);
- mtemp_min20 = 0.0;
- mtemp_max20 = 0.0;
- mtemp = 0.0;
- maxtemp = 0.0;
- gdd5 = 0.0;
- chilldays = 0;
- ifsensechill = true;
- atemp_mean = 0.0;
- lat = latitude;
- std::fill_n(doneday, Date::MAX_YEAR_LENGTH, false);
- sinelat = sin(lat * DEGTORAD);
- cosinelat = cos(lat * DEGTORAD);
- // Set crop-specific members
- if (latitude >= 0) {
- testday_temp = 180; //June 30(day 180)
- testday_prec = 364; //Dec.31(day 364)
- coldestday = COLDEST_DAY_NHEMISPHERE;
- adjustlat = 0;
- }
- else {
- testday_temp = 364; //Dec.31(day 364)
- testday_prec = 180; //June 30(day 180)
- coldestday = COLDEST_DAY_SHEMISPHERE;
- adjustlat = 181;
- }
- // ecev3 - needed if we're forcing with IFS soil properties:
- ifssoiltemp = 0.0;
- ifsw_surf = 0.0;
- ifsw_deep = 0.0;
- }
- /// ecev3 - transfer today's drivers from IFS to Climate
- void setdrivers(double ifstemp, double ifsprec, double ifsrad, double ifslw, double tm5co2, double ifstemp_soil, double ifssoilw_surf, double ifssoilw_deep,
- double dailyndep, double dailynfert);
- void serialize(ArchiveStream& arch);
- };
- /// Stores accumulated monthly and annual fluxes.
- /** This class handles the storage and accounting of fluxes for a single patch.
- * Different fluxes can be stored in different ways, depending on what kind of
- * flux it is and what kind of output we want. The details of whether fluxes
- * are stored per PFT or just as a patch total, or per day, month or only a
- * yearly sum, is hidden from the 'scientific' code, which merely reports the
- * fluxes generated.
- */
- class Fluxes : public Serializable {
- public:
- /// Daily fluxes stored as totals for the whole patch
- enum DailyPerPatchFluxType {
- /// Carbon flux to atmosphere from soil respiration (kgC/m2)
- SOILC,
- /// Carbon flux to atmosphere from burnt vegetation and litter (kgC/m2)
- FIREC,
- /// Flux from atmosphere to vegetation associated with sowing (kgC/m2)
- SEEDC,
- /// Flux to atmosphere from consumed harvested products (kgC/m2)
- HARVESTC,
- /// Number of types, must be last
- NDAILYPERPATCHFLUXTYPES
- };
- /// Fluxes stored as totals for the whole patch
- enum PerPatchFluxType {
- /// Carbon flux to atmosphere from burnt vegetation (kgC/m2)
- FIREVEGC,
- /// Carbon flux to atmosphere from burnt litter (kgC/m2)
- FIRELITTERC,
- /// Carbon flux to atmosphere from litter respiration (kgC/m2)
- LITTERC,
- /// Flux from atmosphere to vegetation associated with establishment (kgC/m2)
- ESTC,
- /// Flux to atmosphere from consumed grazing harvested products (kgC/m2)
- HARVGRAZC,
- /// Flux to slow product pool from grazing (kgC/m2)
- HARVGRAZSLOWC,
- /// Flux to atmosphere from consumed cropping harvested products (kgC/m2)
- HARVCROPC,
- /// Flux to litter from harvested crops (kgC/m2)
- HARVCROPRESC,
- /// Flux to slow product pool from harvested crop (kgC/m2)
- HARVCROPSLOWC,
- /// Reproduction costs
- REPRC,
- /// Carbon leached
- LEACHC,
- /// Total Carbon Flux from Vegetation to Litter
- VEGLITTERC,
- /// Total Carbon Flux from Litter to Soil
- LITTERSOILC,
- /// Total Carbon Flux from excess and debt to atmosphere
- DEBEXCC,
- /// Total Carbon Flux from natural sources to atmosphere (flux seen by TM5)
- CO2NAT,
- /// Total Carbon Flux from anthropogenic sources to atmosphere (flux seen by TM5)
- CO2ANTT,
- /// Nitrogen flux from atmosphere to vegetation associated with sowing (kgC/m2)
- SEEDN,
- /// NH3 flux to atmosphere from fire
- NH3_FIRE,
- /// NOx flux to atmosphere from fire
- NOx_FIRE,
- /// N2O flux to atmosphere from fire
- N2O_FIRE,
- /// N2 flux to atmosphere from fire
- N2_FIRE,
- /// N flux from soil
- N_SOIL,
- /// N deposition
- NDEP,
- /// Biological N fixation
- NFIX,
- /// N fertilisation
- NFERT,
- /// Plant N Uptake
- NUP,
- /// Net N mineralisation
- NMIN,
- /// N leached
- LEACHN,
- /// Total nitrogen Flux from vegetation to litter
- VEGLITTERN,
- /// Total nitrogen Flux from litter to soil
- LITTERSOILN,
- /// Nitrogen flux to atmosphere from consumed harvested products (kgN/m2)
- HARVESTN,
- /// Autotrophic respiration from leaf (kgC/m2)
- RALEAF,
- /// Autotrophic respiration from stem (kgC/m2)
- RASTEM,
- /// Autotrophic respiration from roots (kgC/m2)
- RAROOT,
- /// Autotrophic respiration from growth (kgC/m2)
- RAGROWTH,
- /// Gross primary production for grass (kgC/m2)
- GPPGRASS,
- /// Gross primary production for tree (kgC/m2)
- GPPTREE,
- /// Autotrophic respiration from grass (kgC/m2)
- RAGRASS,
- /// Autotrophic respiration from tree (kgC/m2)
- RATREE,
- /// Number of types, must be last
- NPERPATCHFLUXTYPES
- };
- /// Fluxes stored per pft
- enum PerPFTFluxType {
- /// NPP (kgC/m2)
- NPP,
- /// GPP (kgC/m2)
- GPP,
- /// Autotrophic respiration (kgC/m2)
- RA,
- /// Isoprene (mgC/m2)
- ISO,
- /// Monoterpene (mgC/m2)
- MT1, // MT_APIN, MT_LIMO, MT_TRIC
- MT2, // MT_BPIN, MT_MYRC, MT_SABI, MT_CAMP, MT_TBOC, MT_OTHR
- /// Number of types, must be last
- NPERPFTFLUXTYPES
- };
- #ifdef CRESCENDO_FACE
- /// Daily FACE fluxes stored as totals for the whole patch
- enum DailyPerPatchFACEFluxType {
- /// Reproduction costs
- DREPRC,
- /// Flux from atmosphere to vegetation associated with establishment (kgC/m2)
- DESTC,
- /// Autotrophic respiration from leaf (kgC/m2)
- DRALEAF,
- /// Autotrophic respiration from stem (kgC/m2)
- DRASTEM,
- /// Autotrophic respiration from roots (kgC/m2)
- DRAROOT,
- /// Autotrophic respiration from growth (kgC/m2)
- DRAGROWTH,
- /// Plant leaf N growth
- DNGL,
- /// Plant sapwood N growth
- DNGW,
- /// Plant root N growth
- DNGR,
- /// Leaf nitrogen Flux from vegetation to litter
- DLEAFLITN,
- /// Wood nitrogen Flux from vegetation to litter
- DWOODLITN,
- /// Root nitrogen Flux from vegetation to litter
- DROOTLITN,
- /// Biological N fixation
- DNFIX,
- /// Plant N Uptake
- DNUP,
- /// Gross N mineralisation
- DGNMIN,
- /// Net N mineralisation
- DNMIN,
- /// N leached
- DLEACHN,
- /// N flux from soil
- DN_SOIL,
- /// Leaf Carbon Flux from Vegetation to Litter
- DLEAFLITC,
- /// Wood Carbon Flux from Vegetation to Litter
- DWOODLITC,
- /// Root Carbon Flux from Vegetation to Litter
- DROOTLITC,
- /// Number of types, must be last
- NDAILYPERPATCHFACEFLUXTYPE
- };
- #endif
- // emission ratios from fire (NH3, NOx, N2O, N2) Delmas et al. 1995
- // values in .cpp file
- static const double NH3_FIRERATIO;
- static const double NOx_FIRERATIO;
- static const double N2O_FIRERATIO;
- static const double N2_FIRERATIO;
- /// Reference to patch to which this Fluxes object belongs
- Patch& patch;
- // MEMBER FUNCTIONS
- public:
- /// constructor: initialises members
- Fluxes(Patch& p);
- /// Sets all fluxes to zero (call at the beginning of each year)
- void reset();
- void serialize(ArchiveStream& arch);
- /// Report flux for a certain flux type
- void report_flux(PerPFTFluxType flux_type, int pft_id, double value);
- /// Report flux for a certain flux type
- void report_flux(PerPatchFluxType flux_type, double value);
- /// Report flux for a certain flux type
- void report_flux(DailyPerPatchFluxType flux_type, double value);
- /// \returns flux for a given month and flux type (for all PFTs)
- double get_monthly_flux(PerPFTFluxType flux_type, int month) const;
- /// \returns flux for a given month and flux type
- double get_monthly_flux(PerPatchFluxType flux_type, int month) const;
- /// \returns flux for a given month and flux type
- double get_monthly_flux(DailyPerPatchFluxType flux_type, int month) const;
- /// \returns annual flux for a given PFT and flux type
- double get_annual_flux(PerPFTFluxType flux_type, int pft_id) const;
- /// \returns annual flux for a given flux type (for all PFTs)
- double get_annual_flux(PerPFTFluxType flux_type) const;
- /// \returns annual flux for a given flux type
- double get_annual_flux(PerPatchFluxType flux_type) const;
- /// \returns annual flux for a given flux type
- double get_annual_flux(DailyPerPatchFluxType flux_type) const;
- // ecev3
- /// \returns flux for a given day and flux type (for all PFTs)
- double get_daily_flux(PerPFTFluxType flux_type, int day) const;
- /// \returns flux for a given day and flux type
- double get_daily_flux(DailyPerPatchFluxType flux_type, int day) const;
- #ifdef CRESCENDO_FACE
- /// Report flux for a certain flux type
- void report_flux(DailyPerPatchFACEFluxType flux_type, double value);
- /// \returns flux for a given day and flux type
- double get_daily_flux(DailyPerPatchFACEFluxType flux_type, int day) const;
- #endif
- private:
- /// Stores one flux value per PFT and flux type
- std::vector<std::vector<float> > annual_fluxes_per_pft;
- /// Stores one flux value per month and flux type
- /** For the fluxes only stored as totals for the whole patch */
- float monthly_fluxes_patch[12][NPERPATCHFLUXTYPES];
- /// Stores one flux value per month and flux type
- /** For the fluxes stored per pft for annual values */
- float monthly_fluxes_pft[12][NPERPFTFLUXTYPES];
- // ecev3 also in LPJ-GUESS trunk but 365 instead of 366
- /// Stores one flux value per day for GPP and NPP only
- /** For the fluxes stored per pft for annual values */
- float daily_fluxes_pft[366][NPERPFTFLUXTYPES];
- // ecev3
- /// Stores one flux value per day
- /** For the fluxes only stored as totals for the whole patch */
- float daily_fluxes_patch[366][NDAILYPERPATCHFLUXTYPES];
- #ifdef CRESCENDO_FACE
- /// Stores one flux value per day
- /** For the fluxes only stored as totals for the whole patch */
- float daily_fluxes_patch_FACE[366][NDAILYPERPATCHFACEFLUXTYPE];
- #endif
- };
- /// Storage class of crop management information for one rotation period for a stand type, read from the instruction file.
- class ManagementType {
- public:
- /// id code (should be zero based and sequential, 0...nst-1)
- int id;
- /// name of management type
- xtring name;
- /// type of planting system ("", "MONOCULTURE", "SELECTION", etc.)
- xtring planting_system;
- /// type of harvest system ("", "CLEARCUT", "CONTINUOUS")
- xtring harvest_system;
- /// name of crop pft
- xtring pftname;
- /// identifier of pft selection
- xtring selection;
- /// Rotation period in years
- double nyears;
- /// hydrology (RAINFED,IRRIGATED)
- hydrologytype hydrology;
- /// irrigation efficiency
- // double firr;
- /// forced sowing date, unless sdate_force read from file
- int sdate;
- /// forced harvest date, unless hdate_force read from file
- int hdate;
- /// Harvested forest area fraction, unless woodharv_frac read from file
- double woodharv_frac;
- /// Wood harvest volume, unless woodharv_volume read from file
- double woodharv_vol;
- /// Nitrogen fertilisation amount, unless Nfert_read read from file
- double nfert;
- /// Whether grass is grown in fallow
- bool fallow;
- /// Double cropping of one crop (e.g. rice)
- bool multicrop;
- ManagementType() {
- planting_system = "";
- harvest_system = "";
- pftname = "";
- selection = "";
- nyears = 1.0;
- hydrology = RAINFED;
- // firr = 0.0;
- sdate = -1;
- hdate = -1;
- nfert = -1.0;
- woodharv_frac = -1.0;
- woodharv_vol = -1.0;
- fallow = false;
- multicrop = false;
- }
- // Copy constructor
- ManagementType(const ManagementType& from) {
- name = from.name;
- pftname = from.pftname;
- hydrology = from.hydrology;
- sdate = from.sdate;
- hdate = from.hdate;
- nfert = from.nfert;
- fallow = from.fallow;
- }
- bool is_managed() {
- // Add new management parameters here
- if(pftname != "" || planting_system != "" || selection != ""|| harvest_system != "" || hydrology == IRRIGATED || fallow || nfert > -1.0)
- return true;
- else
- return false;
- }
- /// Returns true if pft is in pftselection.
- int pftinselection(const char* name) {
- bool found = false;
- char *p = NULL, string_copy[200] = {0};
- strcpy(string_copy, selection);
- p = strtok(string_copy, "\t\n ");
- if(p) {
- if(!strcmp(name, p)) {
- found = true;
- }
- }
- do {
- p = strtok(NULL, "\t\n ");
- if(p) {
- if(!strcmp(name, p)) {
- found = true;
- }
- }
- }
- while(p && !found);
- return found;
- }
- };
- /// A list of management types
- /** Functionality for building, maintaining, referencing and destroying a list array of
- * management types objects.
- *
- * Functionality is inherited from the ListArray_id template type in the GUTIL
- * Library. Sequential management type objects can be referenced as array elements by id:
- *
- * ManagementTypelist mtlist;
- * ...
- * for (i=0; i<nst; i++) {
- * ManagementType& thismt=stlist[i];
- * // query or modify object thismt here
- * }
- *
- * or by iteration through the linked list:
- *
- * mtlist.firstobj();
- * while (mtlist.isobj) {
- * ManagementType& thismt=mtlist.getobj();
- * // query or modify object thismt here
- * mtlist.nextobj();
- * }
- */
- class ManagementTypelist : public ListArray_id<ManagementType> {
- public:
- int getmtid(xtring mtname) {
- int id = -1;
- for(unsigned int i=0; i< this->nobj; i++) {
- ManagementType& mt = (*this)[i];
- if(mt.name == mtname) {
- id = mt.id;
- break;
- }
- }
- return id;
- }
- };
- /// The one and only linked list of ManagementType objects
- extern ManagementTypelist mtlist;
- /// Storage class of crop rotation information for a stand type, read from the instruction file.
- struct CropRotation {
- /// Number of crops in rotation
- int ncrops;
- /// First rotation year
- int firstrotyear;
- CropRotation() {
- ncrops = 0;
- firstrotyear = 0;
- }
- };
- /// Stand type class for storing both static parameters, read from the instruction file,
- /* and dynamic variables, updated in landcover_change()
- * Active stand types are stored in the stlist analogous to the pftlist.
- */
- class StandType {
- public:
- /// id code (should be zero based and sequential, 0...nst-1)
- int id;
- /// name of stand type
- xtring name;
- /// specifies type of landcover
- /** \see landcovertype */
- landcovertype landcover; // specifies type of landcover (0 = URBAN, 1 = CROP, 2 = PASTURE, 3 = FOREST, 4 = NATURAL, 5 = PEATLAND)
- /// Rotation information, read from the instruction file
- CropRotation rotation;
- /// Management struct (static)
- ManagementType management;
- /// Management types in a rotation cycle
- xtring mtnames[NROTATIONPERIODS_MAX];
- /// First management year: sets time when common features for managed stands begin, e.g. relaxed establishment rules and absence of disturbance before harvest begins
- /** \this currently only applies for stands with wood havest */
- int firstmanageyear;
- /// intercrop (NOINTERCROP,NATURALGRASS)
- intercroptype intercrop;
- /// whether natural pft:s are allowed to grow in stand type
- xtring naturalveg; // "", "GRASSONLY", "ALL"
- // whether only pft:s defined in management are allowed (plus intercrop or naturalveg/grass)
- bool restrictpfts;
- /// whether planted pft:s or all active pft:s are allowed to established after planting in a forest stand ("", "RESTRICTED", "ALL")
- xtring reestab;
- StandType() {
- intercrop = NOINTERCROP;
- naturalveg = "";
- restrictpfts = false;
- reestab = "ALL";
- firstmanageyear = 100000;
- }
- ManagementType& get_management(int rot = 0) {
- if(rotation.ncrops > 1) {
- return mtlist[mtlist.getmtid(mtnames[rot])];
- }
- else {
- return management;
- }
- }
- /// Returns position of management in rotation list if present. Returns -1 if not.
- int mtinrotation(xtring name) {
- int mtno = -1;
- for(int i=0; i<rotation.ncrops; i++) {
- if(name == mtnames[i])
- mtno = i;
- }
- return mtno;
- }
- /// Returns position of crop in rotation list if present. Returns -1 if not.
- int pftinrotation(xtring name) {
- int cropno = -1;
- for(int i=0; i<rotation.ncrops; i++) {
- if(name == get_management(i).pftname)
- cropno = i;
- }
- return cropno;
- }
- };
- /// A list of stand types
- /** Functionality for building, maintaining, referencing and destroying a list array of
- * stand types objects.
- *
- * Functionality is inherited from the ListArray_id template type in the GUTIL
- * Library. Sequential stand type objects can be referenced as array elements by id:
- *
- * StandTypelist stlist;
- * ...
- * for (i=0; i<nst; i++) {
- * StandType& thisst=stlist[i];
- * // query or modify object thisst here
- * }
- *
- * or by iteration through the linked list:
- *
- * stlist.firstobj();
- * while (stlist.isobj) {
- * StandType& thisst=stlist.getobj();
- * // query or modify object thisst here
- * stlist.nextobj();
- * }
- */
- class StandTypelist : public ListArray_id<StandType> {
- };
- /// The one and only linked list of StandType objects
- extern StandTypelist stlist;
- /// Holds static functional parameters for a plant functional type (PFT).
- /** There should be one Pft object for each potentially occurring PFT. The same Pft object
- * may be referenced (via the pft member of the Individual object; see below) by different
- * average individuals. Member functions are included for initialising SLA given leaf
- * longevity, and for initialising sapling/regen characteristics (required for
- * population mode).
- */
- class Pft {
- // MEMBER VARIABLES
- public:
- /// id code (should be zero based and sequential, 0...npft-1)
- int id;
- /// name of PFT
- xtring name;
- /// life form (tree or grass)
- lifeformtype lifeform;
- /// leaf phenology (raingreen, summergreen, evergreen, rain+summergreen, cropgreen)
- phenologytype phenology;
- /// leaf physiognomy (needleleaf, broadleaf)
- leafphysiognomytype leafphysiognomy;
- /// growing degree sum on 5 degree base required for full leaf cover
- double phengdd5ramp;
- /// water stress threshold for leaf abscission (range 0-1; raingreen PFTs)
- double wscal_min;
- /// biochemical pathway for photosynthesis (C3 or C4)
- pathwaytype pathway;
- /// approximate low temperature limit for photosynthesis (deg C)
- double pstemp_min;
- /// approximate lower range of temperature optimum for photosynthesis (deg C)
- double pstemp_low;
- /// approximate upper range of temperature optimum for photosynthesis (deg C)
- double pstemp_high;
- /// maximum temperature limit for photosynthesis (deg C)
- double pstemp_max;
- /// non-water-stressed ratio of intercellular to ambient CO2 partial pressure
- double lambda_max;
- /// vegetation root profile
- /** array containing fraction of roots in each soil layer, [0=upper layer] */
- double rootdist[NSOILLAYER];
- /// canopy conductance component not associated with photosynthesis (mm/s)
- double gmin;
- /// maximum evapotranspiration rate (mm/day)
- double emax;
- /// maintenance respiration coefficient (0-1)
- double respcoeff;
- /// minimum leaf C:N mass ratio allowed when nitrogen demand is determined
- double cton_leaf_min;
- /// maximum leaf C:N mass ratio allowed when nitrogen demand is determined
- double cton_leaf_max;
- /// average leaf C:N mass ratio (between min and max)
- double cton_leaf_avr;
- /// average fine root C:N mass ratio (connected cton_leaf_avr)
- double cton_root_avr;
- /// maximum fine root C:N mass ratio (used when mass is negligible)
- double cton_root_max;
- /// average sapwood C:N mass ratio (connected cton_leaf_avr)
- double cton_sap_avr;
- /// maximum sapwood C:N mass ratio (used when mass is negligible)
- double cton_sap_max;
- /// reference fine root C:N mass ratio
- double cton_root;
- /// reference sapwood C:N mass ratio
- double cton_sap;
- /// Maximum nitrogen (NH4+ and NO3- seperatly) uptake per fine root [kgN kgC-1 day-1]
- double nuptoroot;
- /// coefficient to compensate for vertical distribution of fine root on nitrogen uptake
- double nupscoeff;
- /// fraction of sapwood (root for herbaceous pfts) that can be used as a nitrogen longterm storage scalar
- double fnstorage;
- /// Michaelis-Menten kinetic parameters
- /** Half saturation concentration for N uptake [kgN l-1] (Rothstein 2000) */
- double km_volume;
- /// fraction of NPP allocated to reproduction
- double reprfrac;
- /// annual leaf turnover as a proportion of leaf C biomass
- double turnover_leaf;
- /// annual fine root turnover as a proportion of fine root C biomass
- double turnover_root;
- /// annual sapwood turnover as a proportion of sapwood C biomass
- double turnover_sap;
- /// sapwood and heartwood density (kgC/m3)
- double wooddens;
- /// maximum tree crown area (m2)
- double crownarea_max;
- /// constant in allometry equations
- double k_allom1;
- /// constant in allometry equations
- double k_allom2;
- /// constant in allometry equations
- double k_allom3;
- /// constant in allometry equations
- double k_rp;
- /// tree leaf to sapwood area ratio
- double k_latosa;
- /// specific leaf area (m2/kgC)
- double sla;
- /// leaf longevity (years)
- double leaflong;
- /// leaf to root mass ratio under non-water-stressed conditions
- double ltor_max;
- /// litter moisture flammability threshold (fraction of AWC)
- double litterme;
- /// fire resistance (0-1)
- double fireresist;
- /// minimum forest-floor PAR level for growth (grasses) or establishment (trees)
- /** J/m2/day, individual and cohort modes */
- double parff_min;
- /** parameter capturing non-linearity in recruitment rate relative to
- * understorey growing conditions for trees (Fulton 1991) (individual and
- * cohort modes)
- */
- double alphar;
- /// maximum sapling establishment rate (saplings/m2/year) (individual and cohort modes)
- double est_max;
- /** constant used in calculation of sapling establishment rate when spatial
- * mass effect enabled (individual and cohort modes)
- */
- double kest_repr;
- /// constant affecting amount of background establishment
- /** \see ifbgestab */
- double kest_bg;
- /** constant used in calculation of sapling establishment rate when spatial
- * mass effect disabled (individual and cohort modes)
- */
- double kest_pres;
- /// expected longevity under non-stressed conditions (individual and cohort modes)
- double longevity;
- /// threshold growth efficiency for imposition of growth suppression mortality
- /** kgC/m2 leaf/year, individual and cohort modes */
- double greff_min;
- // Bioclimatic limits (all temperatures deg C)
- /// minimum 20-year coldest month mean temperature for survival
- double tcmin_surv;
- /// maximum 20-year coldest month mean temperature for establishment
- double tcmax_est;
- /// minimum degree day sum on 5 deg C base for establishment
- double gdd5min_est;
- /// minimum 20-year coldest month mean temperature for establishment
- double tcmin_est;
- /// minimum warmest month mean temperature for establishment
- double twmin_est;
- /// continentality parameter for boreal summergreen trees
- double twminusc;
- /// constant in equation for budburst chilling time requirement (Sykes et al 1996)
- double k_chilla;
- /// coefficient in equation for budburst chilling time requirement
- double k_chillb;
- /// exponent in equation for budburst chilling time requirement
- double k_chillk;
- /// array containing values for GDD0(c) given c=number of chill days
- /** Sykes et al 1996, Eqn 1
- * gdd0 has one element for each possible value for number of chill days
- */
- double gdd0[Date::MAX_YEAR_LENGTH + 1];
- /// interception coefficient (unitless)
- double intc;
- /// the amount of N that is applied (kg N m-2)
- double N_appfert;
- /// 0 - 1 how much of the fertiliser is applied the first date, default 1.
- double fertrate[2];
- /// dates relative to sowing date
- int fertdates[2];
- double fert_stages[2];
- bool fertilised[2];
- double T_vn_min;
- double T_vn_opt;
- double T_vn_max;
- double T_veg_min;
- double T_veg_opt;
- double T_veg_max;
- double T_rep_min;
- double T_rep_opt;
- double T_rep_max;
- double photo[3];
- double dev_rate_veg;
- double dev_rate_rep;
- double a1, b1, c1, d1, a2, b2, c2, d2, a3, b3, c3, d3;
- double cton_stem_avr;
- double cton_stem_max;
- /// Drought tolerance level (0 = very -> 1 = not at all) (unitless)
- /** Used to implement drought-limited establishment */
- double drought_tolerance;
- // bvoc
- /// aerodynamic conductance (m s-1)
- double ga;
- /// isoprene emission capacity (ug C g-1 h-1)
- double eps_iso;
- /// whether (1) or not (1) isoprene emissions show a seasonality
- bool seas_iso;
- /// monoterpene emission capacity (ug C g-1 h-1) per monoterpene species
- double eps_mon[NMTCOMPOUNDS];
- /// fraction of monoterpene production that goes into storage pool (-) per monoterpene species
- double storfrac_mon[NMTCOMPOUNDS];
- /// Sapling/regeneration characteristics (used only in population mode)
- /** For trees, on sapling individual basis (kgC); for grasses, on stand area basis,
- * kgC/m2 */
- struct {
- /// leaf C biomass
- double cmass_leaf;
- /// fine root C biomass
- double cmass_root;
- /// sapwood C biomass
- double cmass_sap;
- /// heartwood C biomass
- double cmass_heart;
- } regen;
- /// specifies type of landcover pft is allowed to grow in (0 = URBAN, 1 = CROP, 2 = PASTURE, 3 = FOREST, 4 = NATURAL, 5 = PEATLAND)
- landcovertype landcover;
- /// pft selection
- xtring selection;
- /// fraction of residue outtake at harvest
- double res_outtake;
- /// harvest efficiency
- double harv_eff;
- /// harvest efficiency of intercrop grass
- double harv_eff_ic;
- /// fraction of harvested products that goes into patchpft.harvested_products_slow
- double harvest_slow_frac;
- /// yearly turnover fraction of patchpft.harvested_products_slow (goes to gridcell.acflux_harvest_slow)
- double turnover_harv_prod;
- /// whether pft may grow as cover crop
- bool isintercropgrass;
- /// whether autumn temperature dependent sowing date is calculated
- bool ifsdautumn;
- /// upper temperature limit for autumn sowing
- double tempautumn;
- /// lower temperature limit for spring sowing
- double tempspring;
- /// default length of growing period
- int lgp_def;
- /// upper minimum temperature limit for crop sowing
- double maxtemp_sowing;
- /// default sowing date in the northern hemisphere (julian day)
- int sdatenh;
- /// default sowing date in the southern hemisphere
- int sdatesh;
- /// whether sowing date adjusting equation is used
- bool sd_adjust;
- /// parameter 1 in sowing date adjusting equation
- double sd_adjust_par1;
- /// parameter 2 in sowing date adjusting equation
- double sd_adjust_par2;
- /// parameter 3 in sowing date adjusting equation
- double sd_adjust_par3;
- /// latest date for harvesting in the northern hemisphere
- int hlimitdatenh;
- /// latest date for harvesting in the southern hemisphere
- int hlimitdatesh;
- /// default base temperature (°C) for heat unit (hu) calculation
- double tb;
- /// temperature under which vernalisation is possible (°C)
- double trg;
- /// default number of vernalising days required
- int pvd;
- /// sensitivity to the photoperiod effect [0-1]
- double psens;
- /// basal photoperiod (h) (pb<ps for longer days plants)
- double pb;
- /// lag in days after sowing before vernalization starts
- int vern_lag;
- /// saturating photoperiod (h) (ps<pb for shorter days plants)
- double ps;
- /// default potential heat units required for crop maturity (degree-days)
- double phu;
- /// whether quadratic equation used for calculating potential heat units (Bondeau method)
- bool phu_calc_quad;
- /// whether linear equation used for calculating potential heat units (Bondeau method)
- bool phu_calc_lin;
- /// minimum potential heat units required for crop maturity (Bondeau method) (degree-days)
- double phu_min;
- /// maximum potential heat units required for crop maturity (Bondeau method) (degree-days)
- double phu_max;
- /// reduction factor of potential heat units in spring crops (Bondeau method) (degree-days)
- double phu_red_spring_sow;
- /// number of days of phu decrease in the linear phu equation (Bondeau method)
- double ndays_ramp_phu;
- /// intercept for the linear phu equation (Bondeau method)
- double phu_interc;
- /// fraction of growing season (phu) at which senescence starts [0-1]
- double fphusen;
- /// type of senescence curve (see Bondeau et al. 2007)
- bool shapesenescencenorm;
- /// fraction of maximal LAI still present at harvest [0-1]
- double flaimaxharvest;
- /// default maximum LAI (only used for intercrop grass in the case where no pasture is present in any stand)
- double laimax;
- /// whether harvestable organs are above ground
- bool aboveground_ho;
- /// optimum harvest index
- double hiopt;
- /// minimum harvest index
- double himin;
- /// initial fraction of growing season's npp allocated to roots
- double frootstart;
- /// final fraction of growing season's npp allocated to roots
- double frootend;
- /// autumn/spring sowing of pft:s with tempautumn = 1
- int forceautumnsowing; //0 = NOFORCING, 1 = AUTUMNSOWING, 2 = SPRINGSOWING
- /// N limited version of pft
- bool nlim;
- double avg_cton(const double& min, const double& max) {
- return 2.0 / (1. / min + 1. / max);
- }
- // MEMBER FUNCTIONS
- public:
- /// Constructor (initialises array gdd0)
- Pft() {
- std::fill_n(gdd0, Date::MAX_YEAR_LENGTH + 1, -1.0); // value<0 signifies "unknown"; see function phenology()
- // guess2008 - DLE
- drought_tolerance = 0.0; // Default, means that the PFT will never be limited by drought.
- res_outtake = 0.0;
- harv_eff = 0.0;
- harv_eff_ic = 0.0;
- turnover_harv_prod = 1.0; // default 1 year turnover time
- harvest_slow_frac = 0.0; // ecev3
- isintercropgrass = false;
- ifsdautumn = false;
- maxtemp_sowing = 60;
- sdatenh = -1;
- sdatesh = -1;
- sd_adjust = 0; // ecev3 - prevent SIGFPE for PFT CC4G_ic in set_sdatecalc_temp(), sd_adjust_par.. are set to bogus values
- lgp_def = 190;
- hlimitdatenh = -1;
- hlimitdatesh = -1;
- tb = -999.9;
- trg = -999.9;
- pvd = -1;
- psens = -1.0;
- pb = -1.0;
- vern_lag=0;
- ps = -1.0;
- phu = -1.0;
- phu_red_spring_sow = 1.0;
- fphusen = -1.0;
- shapesenescencenorm = 0;
- flaimaxharvest = -1.0;
- laimax = 0.0;
- aboveground_ho = true;
- frootstart = 0.0;
- frootend = 0.0;
- forceautumnsowing = 0;
- nlim = false;
- fertrate[0] = 0.0;
- fertrate[1] = 1.0;
- fertdates[0] = 0;
- fertdates[1] = 30;
- fert_stages[0] = 0.5;
- fert_stages[1] = 0.9;
- fertilised[0] = false;
- fertilised[1] = false;
- N_appfert = 0.0;
- T_vn_min=0.0;
- T_vn_opt=0.0;
- T_vn_max=0.0;
- T_veg_min=0.0;
- T_veg_opt=0.0;
- T_veg_max=0.0;
- T_rep_min=0.0;
- T_rep_opt=0.0;
- T_rep_max=0.0;
- a1=0.0;
- b1=0.0;
- c1=0.0;
- d1=0.0;
- a2=0.0;
- b2=0.0;
- c2=0.0;
- d2=0.0;
- a3=0.0;
- b3=0.0;
- c3=0.0;
- d3=0.0;
- // ecev3 - extra initialisation
- harvest_slow_frac = 0.0;
- for (int i=0; i<3; i++)
- photo[i]=0.0;
- }
- /// Calculates SLA given leaf longevity
- void initsla() {
- // SLA has to be supplied in the insfile for crops with N limitation
- if (!(phenology == CROPGREEN && ifnlim)) {
- // Reich et al 1992, Table 1 (includes conversion x2.0 from m2/kg_dry_weight to
- // m2/kgC)
- if (leafphysiognomy == BROADLEAF) {
- if (phenology == RAINGREEN) {
- sla = 0.2 * pow(10.0, 2.51 - 0.36 * log10(12.0 * leaflong));
- }
- else {
- sla = 0.2 * pow(10.0, 2.41 - 0.38 * log10(12.0 * leaflong));
- }
- }
- else if (leafphysiognomy == NEEDLELEAF) {
- sla = 0.2 * pow(10.0, 2.32 - 0.4 * log10(12.0 * leaflong));
- }
- }
- }
- /// Calculates minimum leaf C:N ratio given leaf longevity
- void init_cton_min() {
- // cton_leaf_min has to be supplied in the insfile for crops with N limitation
- if (!(phenology == CROPGREEN && ifnlim)) {
- // Reich et al 1992, Table 1 (includes conversion x500 from mg/g_dry_weight to
- // kgN/kgC)
- if (leafphysiognomy == BROADLEAF) {
- if (phenology == RAINGREEN) {
- cton_leaf_min = 500.0 / pow(10.0, 1.93 - 0.3 * log10(12.0 * leaflong));
- }
- else {
- cton_leaf_min = 500.0 / pow(10.0, 1.75 - 0.33 * log10(12.0 * leaflong));
- }
- }
- else if (leafphysiognomy == NEEDLELEAF) {
- cton_leaf_min = 500.0 / pow(10.0, 1.57 - 0.27 * log10(12.0 * leaflong));
- }
- }
- }
- void init_cton_limits() {
- // Fraction between min and max C:N ratio White et al. 2000
- double frac_mintomax = (phenology == CROPGREEN && ifnlim) ? 5.0 : 2.78; // Use value also without nlim ?
- // Fraction between leaf and root C:N ratio
- double frac_leaftoroot = 1.16; // Friend et al. 1997
- // Fraction between leaf and sap wood C:N ratio
- double frac_leaftosap = 6.9; // Friend et al. 1997
- // Max leaf C:N ratio
- cton_leaf_max = cton_leaf_min * frac_mintomax;
- // Average leaf C:N ratio
- cton_leaf_avr = avg_cton(cton_leaf_min, cton_leaf_max);
- // Tighter C:N ratio range for roots and sapwood: picked out thin air
- double frac_maxtomin = .9;
- // Maximum fine root C:N ratio
- cton_root_max = cton_leaf_max * frac_leaftoroot;
- double cton_root_min = cton_root_max * frac_maxtomin;
- // Average fine root C:N ratio
- cton_root_avr = avg_cton(cton_root_min, cton_root_max);
- // Maximum sap C:N ratio
- cton_sap_max = cton_leaf_max * frac_leaftosap;
- double cton_sap_min = cton_sap_max * frac_maxtomin;
- // Average sap C:N ratio
- cton_sap_avr = avg_cton(cton_sap_min, cton_sap_max);
- if (lifeform == GRASS) {
- respcoeff /= 2.0 * cton_root / (cton_root_avr + cton_root_min);
- } else {
- respcoeff /= cton_root / (cton_root_avr + cton_root_min) +
- cton_sap / (cton_sap_avr + cton_sap_min);
- }
- cton_stem_max = 1.0/(2.0*0.0034); //Maize params
- cton_stem_avr = 1.0/(2.0*0.0068);
- }
- /// Calculates coefficient to compensate for different vertical distribution of fine root on nitrogen uptake
- void init_nupscoeff() {
- // Fraction fine root in upper soil layer should have higher possibility for mineralized nitrogen uptake
- // Soil nitrogen profile is considered to have a exponential decline (Franzluebbers et al. 2009) giving
- // an approximate advantage of 2 of having more roots in the upper soil layer
- const double upper_adv = 2.0;
- nupscoeff = rootdist[0] * upper_adv + rootdist[1];
- }
- /// Initialises sapling/regen characteristics in population mode following LPJF formulation
- void initregen() {
- // see function allometry in growth module.
- // Note: primary PFT parameters, including SLA, must be set before this
- // function is called
- const double REGENLAI_TREE = 1.5;
- const double REGENLAI_GRASS = 0.001;
- const double SAPLINGHW = 0.2;
- if (lifeform == TREE) {
- // Tree sapling characteristics
- regen.cmass_leaf = pow(REGENLAI_TREE * k_allom1 * pow(1.0 + SAPLINGHW, k_rp) *
- pow(4.0 * sla / PI / k_latosa, k_rp * 0.5) / sla, 2.0 / (2.0 - k_rp));
- regen.cmass_sap = wooddens * k_allom2 * pow((1.0 + SAPLINGHW) *
- sqrt(4.0 * regen.cmass_leaf * sla / PI / k_latosa), k_allom3) *
- regen.cmass_leaf * sla / k_latosa;
- regen.cmass_heart = SAPLINGHW * regen.cmass_sap;
- }
- else if (lifeform == GRASS) {
- // Grass regeneration characteristics
- regen.cmass_leaf = REGENLAI_GRASS / sla;
- }
- regen.cmass_root = 1.0 / ltor_max * regen.cmass_leaf;
- }
- };
- /// A list of PFTs
- /** Functionality for building, maintaining, referencing and destroying a list array of
- * Pft objects. In general, there should be a single Pftlist object containing
- * a single list of PFTs. Pft objects within the list are then referenced by the pft
- * member of each Individual object.
- *
- * Functionality is inherited from the ListArray_id template type in the GUTIL
- * Library. Sequential Pft objects can be referenced as array elements by id:
- *
- * Pftlist pftlist;
- * ...
- * for (i=0; i<npft; i++) {
- * Pft& thispft=pftlist[i];
- * // query or modify object thispft here
- * }
- *
- * or by iteration through the linked list:
- *
- * pftlist.firstobj();
- * while (pftlist.isobj) {
- * Pft& thispft=pftlist.getobj();
- * // query or modify object thispft here
- * pftlist.nextobj();
- * }
- */
- class Pftlist : public ListArray_id<Pft> {
- public:
- int getpftid(xtring pftname) {
- int id = -1;
- for(unsigned int i=0; i< this->nobj; i++) {
- Pft& pft = (*this)[i];
- if(pft.name == pftname) {
- id = pft.id;
- break;
- }
- }
- return id;
- }
- };
- /// The one and only linked list of Pft objects
- extern Pftlist pftlist;
- /// Container for crop-specific data at the individual level
- struct cropindiv_struct : public Serializable {
- //Plant carbon biomass variables are all on patch area basis (kgC/m2)
- /// year's harvestable organ C biomass (= ycmass_plant)
- double cmass_ho;
- /// above-ground pool C biomass (when calculating daily cmass_leaf from lai_crop) (= ycmass_agpool)
- double cmass_agpool;
- double cmass_stem;
- /// year's maximum value of leaf C biomass
- double cmass_leaf_max;
- /// grs_cmass_leaf value saved at day before senescence (for LAI-calculation in allometry)
- double cmass_leaf_sen;
- /// today's increase of whole plant C biomass
- double dcmass_plant;
- /// today's increase of leaf C biomass
- double dcmass_leaf;
- /// today's increase of root C biomass
- double dcmass_root;
- /// today's increase of harvestable organ C biomass
- double dcmass_ho;
- /// today's increase of above-ground pool C biomass
- double dcmass_agpool;
- double dcmass_stem;
- /// today's increase of leaf N biomass
- double dnmass_leaf;
- /// today's increase of root N biomass
- double dnmass_root;
- /// today's increase of harvestable organ N biomass
- double dnmass_ho;
- /// today's increase of above-ground pool N biomass
- double dnmass_agpool;
- ///CARBON
- /// daily updated whole plant C biomass, reset at harvest day
- double grs_cmass_plant;
- /// daily updated leaf C biomass, reset at harvest day
- double grs_cmass_leaf;
- /// daily updated root C biomass, reset at harvest day
- double grs_cmass_root;
- /// daily updated harvestable organ C biomass, reset at harvest day
- double grs_cmass_ho;
- /// daily updated above-ground pool C biomass, reset at harvest day
- double grs_cmass_agpool;
- /// daily updated dead leaf C biomass, reset at harvest day
- double grs_cmass_dead_leaf;
- /// daily updated stem pool C biomass, reset at harvest day
- double grs_cmass_stem;
- /// carbon content of harvestable organs saved on first day of land use change year
- double grs_cmass_leaf_luc;
- /// carbon content of harvestable organs saved on first day of land use change year
- double grs_cmass_root_luc;
- /// carbon content of harvestable organs saved on first day of land use change year
- double grs_cmass_ho_luc;
- /// carbon content of above-ground pool saved on first day of land use change year
- double grs_cmass_agpool_luc;
- /// carbon content of dead leaves saved on first day of land use change year
- double grs_cmass_dead_leaf_luc;
- /// carbon content of stem saved on first day of land use change year
- double grs_cmass_stem_luc;
- /// daily updated whole plant C biomass, reset at day 0
- double ycmass_plant;
- /// daily updated leaf C biomass, reset at day 0
- double ycmass_leaf;
- /// daily updated root C biomass, reset at day 0
- double ycmass_root;
- /// daily updated harvestable organ C biomass, reset at day 0
- double ycmass_ho;
- /// daily updated above-ground pool C biomass, reset at day 0
- double ycmass_agpool;
- /// daily updated dead leaf C biomass, reset at day 0
- double ycmass_dead_leaf;
- /// daily updated stem C biomass, reset at day 0
- double ycmass_stem;
- /// year's whole plant C biomass at time of harvest (cumulative if several harvest events)
- double harv_cmass_plant;
- /// year's leaf C biomass at time of harvest (cumulative if several harvest events)
- double harv_cmass_leaf;
- /// year's root C biomass at time of harvest (cumulative if several harvest events)
- double harv_cmass_root;
- /// year's harvestable organ C biomass at time of harvest (cumulative if several harvest events)
- double harv_cmass_ho;
- /// year's above-ground pool C biomass at time of harvest (cumulative if several harvest events)
- double harv_cmass_agpool;
- /// year's stem C biomass at time of harvest (cumulative if several harvest events)
- double harv_cmass_stem;
- ///NITROGEN
- /// nitrogen content of harvestable organs
- double nmass_ho;
- /// nitrogen content of above-ground pool
- double nmass_agpool;
- /// nitrogen content of dead leaves
- double nmass_dead_leaf;
- /// nitrogen content of harvestable organs saved on first day of land use change year
- double nmass_ho_luc;
- /// nitrogen content of above-ground pool saved on first day of land use change year
- double nmass_agpool_luc;
- /// nitrogen content of dead leaves saved on first day of land use change year
- double nmass_dead_leaf_luc;
- /// daily updated leaf N biomass, reset at day 0
- double ynmass_leaf;
- /// daily updated root N biomass, reset at day 0
- double ynmass_root;
- /// daily updated harvestable organ N biomass, reset at day 0
- double ynmass_ho;
- /// daily updated above-ground pool N biomass, reset at day 0
- double ynmass_agpool;
- /// daily updated dead leaf N biomass, reset at day 0
- double ynmass_dead_leaf;
- /// year's leaf N biomass at time of harvest (cumulative if several harvest events)
- double harv_nmass_leaf;
- /// year's root N biomass at time of harvest (cumulative if several harvest events)
- double harv_nmass_root;
- /// year's harvestable organ N biomass at time of harvest (cumulative if several harvest events)
- double harv_nmass_ho;
- /// year's above-ground pool N biomass at time of harvest (cumulative if several harvest events)
- double harv_nmass_agpool;
- /// dry weight crop yield harvested this year (cumulative if several harvest events), based on harv_cmass_xx
- double harv_yield;
- /// harvestable organ C biomass at the last two harvest events this year
- double cmass_ho_harvest[2];
- /// harvestable organ N biomass at the last two harvest events this year
- double nmass_ho_harvest[2];
- /// dry weight crop yield at the last two harvest events this year
- double yield_harvest[2];
- /// dry weight crop yield grown this year (cumulative if several harvest events), based on ycmass_xx
- double yield;
- /// whether this pft is the main crop in the stand (pft.id==stand.pftid)
- bool isprimarycrop;
- /// whether this pft is allowed to compete with the main crop during the same growing period (for future use)
- bool isprimarycovegetation;
- /// whether this pft is grown during a second growing period, different from the primary (main) crop (for future use)
- // bool issecondarycrop;
- /// set to true if pft.isintercropgrass is true and the stand's main crop pft.intercrop is "naturalgrass"
- bool isintercropgrass;
- cropindiv_struct() {
- cmass_ho=0.0;
- cmass_agpool=0.0;
- cmass_stem = 0.0;
- cmass_leaf_max=0.0;
- cmass_leaf_sen=0.0;
- yield=0.0;
- yield_harvest[0]=0.0;
- yield_harvest[1]=0.0;
- dcmass_leaf=0.0;
- dcmass_root=0.0;
- dcmass_plant=0.0;
- dcmass_ho=0.0;
- dcmass_agpool=0.0;
- grs_cmass_leaf=0.0;
- grs_cmass_root=0.0;
- grs_cmass_plant=0.0;
- grs_cmass_ho=0.0;
- grs_cmass_agpool=0.0;
- grs_cmass_stem = 0.0;
- grs_cmass_dead_leaf = 0.0;
- grs_cmass_leaf_luc=0.0;
- grs_cmass_root_luc=0.0;
- grs_cmass_ho_luc=0.0;
- grs_cmass_agpool_luc=0.0;
- grs_cmass_dead_leaf_luc = 0.0;
- grs_cmass_stem_luc = 0.0;
- nmass_ho=0.0;
- nmass_agpool=0.0;
- nmass_dead_leaf = 0.0;
- ycmass_leaf=0.0;
- ycmass_root=0.0;
- ycmass_plant=0.0;
- ycmass_ho=0.0;
- ycmass_agpool=0.0;
- ycmass_stem = 0.0;
- ycmass_dead_leaf = 0.0;
- harv_cmass_leaf=0.0;
- harv_cmass_root=0.0;
- harv_cmass_root=0.0;
- harv_cmass_ho=0.0;
- harv_yield=0.0;
- harv_cmass_agpool=0.0;
- harv_cmass_stem = 0.0;
- cmass_ho_harvest[0]=0.0;
- cmass_ho_harvest[1]=0.0;
- //Nitrogen
- dnmass_leaf=0.0;
- dnmass_root=0.0;
- dnmass_ho=0.0;
- dnmass_agpool=0.0;
- ynmass_leaf=0.0;
- ynmass_root=0.0;
- ynmass_ho=0.0;
- ynmass_agpool=0.0;
- ynmass_dead_leaf = 0.0;
- harv_nmass_leaf=0.0;
- harv_nmass_root=0.0;
- harv_nmass_root=0.0;
- harv_nmass_ho=0.0;
- harv_nmass_agpool=0.0;
- nmass_dead_leaf_luc = 0.0;
- nmass_ho_harvest[0]=0.0;
- nmass_ho_harvest[1]=0.0;
- // ecev3
- nmass_ho_luc=0.0;
- nmass_agpool_luc = 0.0;
- isprimarycrop=false;
- isprimarycovegetation=false;
- // issecondarycrop=false;
- isintercropgrass=false;
- }
- void serialize(ArchiveStream& arch);
- };
- /// A vegetation individual.
- /** In population mode this is the average individual of a PFT population;
- * in cohort mode: the average individual of a cohort;
- * in individual mode: an individual plant. Each grass PFT is represented as a single
- * individual in all modes. Individual objects are collected within list arrays of
- * class Vegetation (defined below), of which there is one for each patch, and include
- * a reference to their 'parent' Vegetation object. Use the createobj member function
- * of class Vegetation to add new individuals.
- */
- class Individual : public Serializable {
- public:
- /// reference to Pft object containing static parameters for this individual
- Pft& pft;
- /// reference to Vegetation object to which this Individual belongs
- Vegetation& vegetation;
- /// id code (0-based, sequential)
- int id;
- /// leaf C biomass on modelled area basis (kgC/m2)
- double cmass_leaf;
- /// fine root C biomass on modelled area basis (kgC/m2)
- double cmass_root;
- /// sapwood C biomass on modelled area basis (kgC/m2)
- double cmass_sap;
- /// heartwood C biomass on modelled area basis (kgC/m2)
- double cmass_heart;
- /// C "debt" (retrospective storage) (kgC/m2)
- double cmass_debt;
- /// Total C mass at land use change (kgC/m2)
- double cmass_tot_luc;
- /// leaf C mass after tunrnover
- double cmass_leaf_post_turnover;
- /// root C mass after turnover
- double cmass_root_post_turnover;
- /// Latest tunover day for this individual
- int last_turnover_day;
- /// leaf N biomass on modelled area basis (kgN/m2)
- double nmass_leaf;
- /// root N biomass on modelled area basis (kgN/m2)
- double nmass_root;
- /// sap N biomass on modelled area basis (kgN/m2)
- double nmass_sap;
- /// heart N biomass on modelled area basis (kgN/m2)
- double nmass_heart;
- /// leaf N biomass on modelled area basis saved on first day of land use change year
- double nmass_leaf_luc;
- /// root N biomass on modelled area basis on first day of land use change year
- double nmass_root_luc;
- /// sap N biomass on modelled area basis on first day of land use change year
- double nmass_sap_luc;
- /// heart N biomass on modelled area basis on first day of land use change year
- double nmass_heart_luc;
- /// total N biomass on modelled area basis on first day of land use change year
- double nmass_tot_luc;
- /// foliar projective cover (FPC) under full leaf cover as fraction of modelled area
- double fpc;
- /// foliar projective cover (FPC) this day as fraction of modelled area
- double fpc_daily;
- /// monthly average daily foliar projective cover (FPC) as fraction of modelled area
- double mfpc[12];
- /// fraction of PAR absorbed by foliage over projective area today, taking account of leaf phenological state
- double fpar;
- /// monthly average fraction of PAR absorbed by foliage over projective area, taking account of leaf phenological state
- double mfpar[12];
- /// average density of individuals over patch (indiv/m2)
- double densindiv;
- /// vegetation phenological state (fraction of potential leaf cover)
- double phen;
- /// annual sum of daily fractional leaf cover
- /** Equivalent number of days with full leaf cover
- * (population mode only; reset on expected coldest day of year)
- */
- double aphen;
- /// annual number of days with full leaf cover) (raingreen PFTs only; reset on 1 January)
- int aphen_raingreen;
- /// Photosynthesis values for this individual under non-water-stress conditions
- PhotosynthesisResult photosynthesis;
- /// sub-daily version of the above variable (NB: daily units)
- std::vector<PhotosynthesisResult> phots;
- /// accumulated NPP over modelled area (kgC/m2/year);
- /** annual NPP following call to growth module on last day of simulation year */
- double anpp;
- /// actual evapotranspiration over projected area (mm/day)
- double aet;
- /// annual actual evapotranspiration over projected area (mm/year)
- double aaet;
- /// leaf to root mass ratio
- double ltor;
- /// plant height (m)
- double height;
- /// plant crown area (m2)
- double crownarea;
- /// increment in fpc since last simulation year
- double deltafpc;
- /// bole height, i.e. height above ground of bottom of crown cylinder (m)
- /** (individual and cohort modes only) */
- double boleht;
- /// patch-level lai for this individual or cohort (function fpar)
- double lai;
- /// patch-level lai for cohort in current vertical layer (function fpar)
- double lai_layer;
- /// individual leaf area index (individual and cohort modes only)
- double lai_indiv;
- /// patch-level individual leaf area index (individual and cohort modes only)
- double lai_daily;
- /// daily individual leaf area index (individual and cohort modes only)
- double lai_indiv_daily;
- /// growth efficiency (NPP/leaf area) for each of the last five simulation years (kgC/m2/yr)
- Historic<double, NYEARGREFF> greff_5;
- /// increment of wood C for each of the last five simulation years (kgC/m2/yr)
- Historic<double, 10> cmass_wood_inc_5;
- /// individual/cohort age (years)
- double age;
- /// monthly LAI (including phenology component)
- double mlai[12];
- /// monthly maximum LAI (including phenology component)
- double mlai_max[12];
- /// FPAR assuming full leaf cover for all vegetation
- double fpar_leafon;
- /// LAI for current layer in canopy (cohort/individual mode; see function fpar)
- double lai_leafon_layer;
- /// non-water-stressed canopy conductance on FPC basis (mm/s)
- double gpterm;
- /// sub-daily version of the above variable (mm/s)
- std::vector<double> gpterms;
- /// interception associated with this individual today (patch basis)
- double intercep;
- /// accumulated mean fraction of potential leaf cover
- double phen_mean;
- /// whether individual subject to water stress
- bool wstress;
- /// leaf nitrogen that is photosyntetic active
- double nactive;
- /// Nitrogen extinction scalar
- /** Scalar to account for leaf nitrogen not following the optimal light
- * extinction, but is shallower.
- */
- double nextin;
- /// long-term storage of labile nitrogen
- double nstore_longterm;
- /// storage of labile nitrogen
- double nstore_labile;
- /// long-term storage of labile nitrogen saved on first day of land use change year
- double nstore_longterm_luc;
- /// storage of labile nitrogen saved on first day of land use change year
- double nstore_labile_luc;
- /// daily total nitrogen demand
- double ndemand;
- /// fraction of individual nitrogen demand available for uptake
- double fnuptake;
- /// annual nitrogen uptake
- double anuptake;
- /// maximum size of nitrogen storage
- double max_n_storage;
- /// scales annual npp to maximum nitrogen storage
- double scale_n_storage;
- /// annual nitrogen limitation on vmax
- double avmaxnlim;
- /// annual optimal leaf C:N ratio
- double cton_leaf_aopt;
- /// annual average leaf C:N ratio
- double cton_leaf_aavr;
- /// plant mobile nitrogen status
- double cton_status;
- /// total carbon in compartments before growth
- double cmass_veg;
- /// total nitrogen in compartments before growth
- double nmass_veg;
- /// whether individual subject to nitrogen stress
- bool nstress;
- /// daily leaf nitrogen demand calculated from Vmax (kgN/m2)
- double leafndemand;
- /// daily root nitrogen demand based on leafndemand
- double rootndemand;
- /// daily sap wood nitrogen demand based on leafndemand
- double sapndemand;
- /// daily labile nitrogen demand based on npp
- double storendemand;
- /// daily harvestable organ nitrogen demand
- double hondemand;
- /// leaf fraction of total nitrogen demand
- double leaffndemand;
- /// root fraction of total nitrogen demand
- double rootfndemand;
- /// sap fraction of total nitrogen demand
- double sapfndemand;
- /// store fraction of total nitrogen demand
- double storefndemand;
- /// daily leaf nitrogen demand over possible uptake (storage demand)
- double leafndemand_store;
- /// daily root nitrogen demand over possible uptake (storage demand)
- double rootndemand_store;
- /// The daily C lossed from leaves due to senescense, only crops.
- double daily_cmass_leafloss;
- /// The daily N lossed from leaves due to senescense, only crops.
- double daily_nmass_leafloss;
- /// The daily C lossed from roots due to senescense, only crops.
- double daily_cmass_rootloss;
- /// The daily N lossed from roots due to senescense, only crops.
- double daily_nmass_rootloss;
- /// Number of days with non-negligible phenology this month
- int nday_leafon;
- // Whether this individual is truly alive.
- /** Set to false for first year after the Individual object is created, then true. */
- bool alive;
- /// NPP this day
- double dnpp;
- // bvoc
- /// isoprene production (mg C m-2 d-1)
- double iso;
- /// monoterpene production (mg C m-2 d-1) per monoteprene species
- double mon[NMTCOMPOUNDS];
- /// monoterpene storage pool (mg C m-2) per monoterpene species
- double monstor[NMTCOMPOUNDS];
- /// isoprene seasonality factor (-)
- double fvocseas;
- // Lambda output
- /// monthly lambda (Ci/Ca)
- double mlambda_gpp[12];
- /// monthly gpp
- double mgpp[12];
- /// Pointer to struct with crop-specific data
- cropindiv_struct *cropindiv;
- // MEMBER FUNCTIONS
- public:
- // Constructor function for objects of class Individual
- // Initialisation of certain member variables
- Individual(int i,Pft& p,Vegetation& v);
- ~Individual();
- /// Access functions for cropindiv:
- cropindiv_struct* get_cropindiv() const;
- cropindiv_struct* set_cropindiv();
- void serialize(ArchiveStream& arch);
- /// Report a flux associated with this Individual
- /** Fluxes from 'new' Individuals (alive == false) will not be reported */
- void report_flux(Fluxes::PerPFTFluxType flux_type, double value);
- /// Report a flux associated with this Individual
- /** Fluxes from 'new' Individuals (alive == false) will not be reported */
- void report_flux(Fluxes::PerPatchFluxType flux_type, double value);
- /// Report a flux associated with this Individual
- /** Fluxes from 'new' Individuals (alive == false) will not be reported */
- void report_flux(Fluxes::DailyPerPatchFluxType flux_type, double value);
- #ifdef CRESCENDO_FACE
- /// Report a flux associated with this Individual
- /** Fluxes from 'new' Individuals (alive == false) will not be reported */
- void report_flux(Fluxes::DailyPerPatchFACEFluxType flux_type, double value);
- #endif
- /// Whether an individual is either a true crop or a cover crop grass
- inline bool istruecrop_or_intercropgrass() const {
- return (pft.landcover==CROPLAND && (pft.phenology==CROPGREEN || cropindiv->isintercropgrass));
- }
- /// Whether harvest and turnover is done on actual C and N on harvest or turnover day, which can occur any day of the year.
- bool has_daily_turnover() const;
- /// Whether resetting of grs_cmass and turnover (if has_daily_turnover() returns true) of continuous grass is to be done this day.
- /** This should occur at the very end of the growing period */
- bool is_turnover_day() const;
- /// Reduce current biomass due to mortality and/or fire
- /** The removed biomass is put into litter pools and/or goes to fire fluxes.
- *
- * \param mortality fraction of Individual's biomass killed due to
- * mortality (including fire)
- * \param mortality_fire fraction of Individual's biomass killed due to
- * fire only
- */
- void reduce_biomass(double mortality, double mortality_fire);
- /// Total storage of nitrogen
- double nstore() const {
- return nstore_longterm + nstore_labile;
- }
- /// Total carbon wood biomass
- double cmass_wood() const {
- return cmass_sap + cmass_heart - cmass_debt;
- }
- /// Total nitrogen wood biomass
- double nmass_wood() const {
- return nmass_sap + nmass_heart;
- }
- /// Total carbon biomass
- double ccont(double scale_indiv = 1.0, bool luc = false) const;
- /// Total nitrogen biomass
- double ncont(double scale_indiv = 1.0, bool luc = false) const;
- /// Leaf carbon biomass
- double cleafcont(double scale_indiv = 1.0, bool luc = false) const;
- /// Leaf nitrogen biomass
- double nleafcont(double scale_indiv = 1.0, bool luc = false) const;
- /// Root carbon biomass
- double crootcont(double scale_indiv = 1.0, bool luc = false) const;
- /// Root nitrogen biomass
- double nrootcont(double scale_indiv = 1.0, bool luc = false) const;
- /// Whether grass growth is uninterrupted by crop growth.
- bool continous_grass() const;
- /// Checks whether any grs_cmass is negative, in which case it is zeroed and fluxes are corrected (only cropland).
- double check_C_mass();
- /// Checks whether any nmass is negative, in which case it is zeroed and fluxes are corrected (only cropland).
- double check_N_mass();
- /// Save cmass-values on first day of the year of land cover change in expanding stands
- void save_cmass_luc();
- /// Save nmass-values on first day of the year of land cover change in expanding stands
- void save_nmass_luc();
- /// Current leaf C:N ratio
- /**
- * \param use_phen Set to false if indiv.phen shouldn't be considered
- * when calculating C:N ratio
- */
- double cton_leaf(bool use_phen = true) const;
- /// Current fine root C:N ratio
- /**
- * \param use_phen Set to false if indiv.phen shouldn't be considered
- * when calculating C:N ratio
- */
- double cton_root(bool use_phen = true) const;
- /// Current sap C:N ratio
- double cton_sap() const;
- /// Gets the individual's Patchpft
- Patchpft& patchpft() const;
- /// Transfers the individual's biomass (C and N) to litter and harvest pools/fluxes
- /**
- * \param harvest Set to true if some of the biomass should be harvested,
- * harvest will be done according to the PFT's harvest efficiency
- * and residue outtake.
- */
- void kill(bool harvest = false);
- /// Annual mean wscal - water stress parameter (0-1 range; 1 = minimum stress)
- /** Value only valid at end of year, after call to canopy_exchange().
- *
- * Currently, all Individuals belonging to a Patchpft share the same water stress.
- */
- double wscal_mean() const;
- /// Gets the individual's daily cmass_leaf value
- double cmass_leaf_today() const;
- /// Gets the individual's daily cmass_root value
- double cmass_root_today() const;
- /// Gets the individual's daily LAI value (patch-level)
- /** Based on total leaf area for whatever the individual represents
- * (individual, cohort, population), over the whole patch.
- */
- double lai_today() const;
- /// Gets the individual's daily LAI value (individual-level)
- /** Based on the leaf area for the average individual and
- * the average individual's crown area.
- */
- double lai_indiv_today() const;
- /// Gets the Nitrogen limited LAI, Eq. 8 Olin 2015
- double lai_nitrogen_today() const;
- /// Gets the individual's daily fpc value
- double fpc_today() const;
- /// Gets the growingseason status for crop individual. Non-crop individuals always return true.
- bool growingseason() const;
- /// The N demand of the storage, only used for PNV.
- double ndemand_storage(double cton_leaf_opt);
- };
- /// The vegetation in a patch - a list of individuals
- /** Functionality for building, maintaining, referencing and destroying a list array of
- * Individual objects. A single Vegetation object is defined for each patch. A
- * reference to the parent Patch object (defined below) is included as a member
- * variable.
- *
- * Functionality is inherited from the ListArray_idin1 template type in the GUTIL
- * Library. Sequential Individual objects can be referenced as array elements by id,
- * or by iteration through the linked list:
- *
- * Vegetation vegetation
- * ...
- * vegetation.firstobj();
- * while (vegetation.isobj) {
- * Individual& thisindiv=vegetation.getobj();
- * // query or modify object thisindiv here
- * vegetation.nextobj();
- * }
- */
- class Vegetation : public ListArray_idin2<Individual,Pft,Vegetation>, public Serializable {
- public:
- // MEMBER VARIABLES
- /// reference to parent Patch object
- Patch& patch;
- // MEMBER FUNCTIONS
- /// constructor (initialises member variable patch)
- Vegetation(Patch& p):patch(p) {};
- void serialize(ArchiveStream& arch);
- };
- /// Soiltype stores static parameters for soils and the snow pack.
- /** One Soiltype object is defined for each Gridcell. State variables for soils
- * are held by objects of class Soil, of which there is one for each patch
- * (see below).
- */
- class Soiltype {
- // MEMBER VARIABLES
- public:
- /// available water holding capacity as fraction of soil volume
- double awc_frac;
- /// available water holding capacity of soil layers [0=upper layer] (mm)
- double awc[NSOILLAYER];
- /// coefficient in percolation calculation (K in Eqn 31, Haxeltine & Prentice 1996)
- double perc_base;
- /// exponent in percolation calculation (=4 in Eqn 31, Haxeltine & Prentice 1996)
- double perc_exp;
- /// thermal diffusivity at 0% WHC (mm2/s)
- double thermdiff_0;
- /// thermal diffusivity at 15% WHC (mm2/s)
- double thermdiff_15;
- /// thermal diffusivity at 100% WHC (mm2/s)
- double thermdiff_100;
- /// wilting point of soil layers [0=upper layer] (mm) Cosby et al 1984
- double wp[NSOILLAYER];
- /// saturation point. Cosby et al 1984
- double wsats[NSOILLAYER];
- /// year at which to calculate equilibrium soil carbon
- int solvesom_end;
- /// year at which to begin documenting means for calculation of equilibrium soil carbon
- int solvesom_begin;
- /// water holding capacity plus wilting point for whole soil volume
- double wtot;
- // For CENTURY ...
- /// fraction of soil that is sand
- double sand_frac;
- /// fraction of soil that is clay
- double clay_frac;
- /// fraction of soil that is silt
- double silt_frac;
- // ecev3
- // New volumetric soil moisture parameters from H-TESSEL/IFS - see Balsamo et al.
- // Units: m3 m-3
- double wilt_point;
- // Wilting point
- double field_cap;
- // Field capacity
- double whcap;
- // Water holding capacity (field_cap - wilt_point)
- // MEMBER FUNCTIONS
- public:
- /// Constructor: initialises certain member variables
- Soiltype() {
- solvesom_end = SOLVESOM_END;
- solvesom_begin = SOLVESOM_BEGIN;
- }
- /// Override the default SOM years with 70-80% of the spin-up period length
- void updateSolveSOMvalues(const int& nyrspinup) {
- solvesom_end = static_cast<int>(0.8 * nyrspinup);
- solvesom_begin = static_cast<int>(0.7 * nyrspinup);
- }
- };
- /// CENTURY SOIL POOL
- class Sompool : public Serializable {
- public:
- /// Constructor
- Sompool() {
- // Initialise pool
- cmass = 0.0;
- nmass = 0.0;
- ligcfrac = 0.0;
- delta_cmass = 0.0;
- delta_nmass = 0.0;
- fracremain = 0.0;
- litterme = 0.0;
- fireresist = 0.0;
- ntoc = 0.0; // ecev3
- cdec = 0.0; // ecev3
- ndec = 0.0; // ecev3
- // ecev3 - extra initialisation
- ntoc = 0.0;
- cdec = 0.0;
- ndec = 0.0;
- for (int m = 0; m < 12; m++) {
- mfracremain_mean[m] = 0.0;
- }
- }
- /// C mass in pool kgC/m2
- double cmass;
- /// Nitrogen mass in pool kgN/m2
- double nmass;
- /// (potential) decrease in C following decomposition today (kgC/m2)
- double cdec;
- /// (potential) decrease in nitrogen following decomposition today (kgN/m2)
- double ndec;
- /// daily change in carbon and nitrogen
- double delta_cmass,delta_nmass;
- /// lignin fractions
- double ligcfrac;
- /// fraction of pool remaining after decomposition
- double fracremain;
- /// nitrogen to carbon ratio
- double ntoc;
- // Fire
- /// soil litter moisture flammability threshold (fraction of AWC)
- double litterme;
- /// soil litter fire resistance (0-1)
- double fireresist;
- // Fast SOM spinup variables
- /// monthly mean fraction of carbon pool remaining after decomposition
- double mfracremain_mean[12];
- void serialize(ArchiveStream& arch);
- };
- /// This struct contains litter for solving Century SOM pools.
- /** \see equilsom() */
- struct LitterSolveSOM {// : public Serializable {
- /// Constructs an empty result
- LitterSolveSOM() {
- clear();
- }
- /// Clears all members
- void clear() {
- for (int p = 0; p < NSOMPOOL; p++) {
- clitter[p] = 0.0;
- nlitter[p] = 0.0;
- }
- }
- /// Add litter
- void add_litter(double cvalue, double nvalue, int pool) {
- clitter[pool] += cvalue;
- nlitter[pool] += nvalue;
- }
- double get_clitter(int pool) {
- return clitter[pool];
- }
- double get_nlitter(int pool) {
- return nlitter[pool];
- }
- //void serialize(ArchiveStream& arch);
- private:
- /// Carbon litter
- double clitter[NSOMPOOL];
- /// Nitrogen litter
- double nlitter[NSOMPOOL];
- };
- /// Soil stores state variables for soils and the snow pack.
- /** Initialised by a call to initdrivers. One Soil object is defined for each patch.
- * A reference to the parent Patch object (defined below) is included as a member
- * variable. Soil static parameters are stored as objects of class Soiltype, of which
- * there is one for each grid cell. A reference to the Soiltype object holding the
- * static parameters for this soil is included as a member variable.
- */
- class Soil : public Serializable {
- // MEMBER VARIABLES
- public:
- /// reference to parent Patch object
- Patch& patch;
- /// reference to Soiltype object holding static parameters for this soil
- Soiltype& soiltype;
- /// water content of soil layers [0=upper layer] as fraction of available water holding capacity;
- double wcont[NSOILLAYER];
- /// DLE - the average wcont over the growing season, for each soil layer
- double awcont[NSOILLAYER];
- /// water content of sublayer of upper soil layer for which evaporation from the bare soil surface is possible
- /** fraction of available water holding capacity */
- double wcont_evap;
- /// daily water content in upper soil layer for each day of year
- double dwcontupper[Date::MAX_YEAR_LENGTH];
- /// mean water content in upper soil layer for last month
- /** (valid only on last day of month following call to daily_accounting_patch) */
- double mwcontupper;
- /// stored snow as average over modelled area (mm rainfall equivalents)
- double snowpack;
- /// total runoff today (mm/day)
- double runoff;
- /// soil temperature today at 0.25 m depth (deg C)
- double temp;
- /// daily temperatures for the last month (deg C)
- /** (valid only on last day of month following call to daily_accounting_patch) */
- double dtemp[31];
- /// mean soil temperature for the last month (deg C)
- /** (valid only on last day of month following call to daily_accounting_patch) */
- double mtemp;
- /// mean top soil temperature for every month (deg K)
- double mtemp_K[12];
- /// Carbon transfer between litter and soil (kg C m-2)
- double litter2soilc;
- /// Nitrogen transfer between litter and soil (kg N m-2)
- double litter2soiln;
- /** respiration response to today's soil temperature at 0.25 m depth
- * incorporating damping of Q10 due to temperature acclimation (Lloyd & Taylor 1994)
- */
- double gtemp;
- /// soil organic matter (SOM) pool with c. 1000 yr turnover (kgC/m2)
- double cpool_slow;
- /// soil organic matter (SOM) pool with c. 33 yr turnover (kgC/m2)
- double cpool_fast;
- // Running sums (converted to long term means) maintained by SOM dynamics module
- /// mean annual litter decomposition (kgC/m2/yr)
- double decomp_litter_mean;
- /// mean value of decay constant for fast SOM fraction
- double k_soilfast_mean;
- /// mean value of decay constant for slow SOM fraction
- double k_soilslow_mean;
- // Parameters used by function soiltemp and updated monthly
- double alag, exp_alag;
- /// water content of soil layers [0=upper layer] as fraction of available water holding capacity
- double mwcont[12][NSOILLAYER];
- /// daily water content in lower soil layer for each day of year
- double dwcontlower[Date::MAX_YEAR_LENGTH];
- double dwcontlower_today; // ecev3 use a daily value to minimize memory issues
- /// mean water content in lower soil layer for last month
- /** (valid only on last day of month following call to daily_accounting_patch) */
- // double mwcontlower; // ecev3 - no longer needed
- /// rainfall and snowmelt today (mm)
- double rain_melt;
- /// upper limit for percolation (mm)
- double max_rain_melt;
- /// whether to percolate today
- bool percolate;
-
- /// CRESCENDO
- /// Monthly averaged depth of snow layer (m rainfall equivalents)
- double msnd[12];
- // Snow density (kg m-3), value from Ling and Zhang, 2006
- double snowdens;
- /// C4MIP / CRESCENDO
- double mcLitter[12];
- double mcLitterCwd[12];
- double mcLitterSurf[12];
- double mcLitterSubSurf[12];
- double mcLitterAbove[12];
- double mcLitterBelow[12];
- double mcSoil[12];
- double mcMedium[12];
- double mcSlow[12];
- double mnLitter[12];
- double mnLitterCwd[12];
- double mnLitterSurf[12];
- double mnLitterSubSurf[12];
- double mnSoil[12];
- double mnMineralNH4[12];
- double mnMineralNO3[12];
- double dtsl[366][NSOILLAYER];
- double dmrsol[366][NSOILLAYER];
- #ifdef CRESCENDO_FACE
- // CRESCENDO FACE only variables
- // daily carbon Fine Litter above [kg C m-2]
- double dcflita[366];
- // daily nitrogen litter aboveground [kg N m-2]
- double dnlit[366];
- // daily carbon Fine Litter below [kg C m-2]
- double dcflitb[366];
- // daily nitrogen litter belowground [kg N m-2]
- double dnrlit[366];
- // daily carbon Coarse Litter [kg C m-2]
- double dcclitb[366];
- // daily nitrogen dead wood [kg N m-2]
- double dndw[366];
- // daily carbon Soil [kg C m-2]
- double dcsoil[366];
- // daily nitrogen soil total [kg N m-2]
- double dnsoil[366];
- // daily mineral soil nitrogen [kg N m-2]
- double dnmineral[366];
- #endif
- //////////////////////////////////////////////////////////////////////////////////
- // CENTURY SOM pools and other variables
- Sompool sompool[NSOMPOOL];
- /// daily percolation (mm)
- double dperc;
- /// fraction of decayed organic nitrogen leached each day;
- double orgleachfrac;
- /// soil mineral nitrogen pool (kgN/m2)
- double nmass_avail;
- /// soil nitrogen input (kgN/m2)
- double ninput;
- /// annual sum of nitrogen mineralisation
- double anmin;
- /// annual sum of nitrogen immobilisation
- double animmob;
- /// annual leaching from available nitrogen pool
- double aminleach;
- /// annual leaching of organics nitrogen from the active nitrogen pool
- double aorgNleach;
- /// total annual nitrogen fixation
- double anfix;
- /// calculated annual mean nitrogen fixation
- double anfix_calc;
- /// annual leaching of organics carbon from the active carbon pool
- double aorgCleach;
- // Variables for fast spinup of SOM pools
- /// monthly fraction of available mineral nitrogen taken up
- double fnuptake_mean[12];
- /// monthly fraction of organic carbon/nitrogen leached
- double morgleach_mean[12];
- /// monthly fraction of available mineral nitrogen leached
- double mminleach_mean[12];
- /// annual nitrogen fixation
- double anfix_mean;
- // Solving Century SOM pools
- /// years at which to begin documenting for calculation of Century equilibrium
- int solvesomcent_beginyr;
- /// years at which to end documentation and start calculation of Century equilibrium
- int solvesomcent_endyr;
- /// Cumulative litter pools for one year.
- LitterSolveSOM litterSolveSOM;
- std::vector<LitterSolveSOM> solvesom;
- /// stored nitrogen deposition in snowpack
- double snowpack_nmass;
- // MEMBER FUNCTIONS
- public:
- /// constructor (initialises member variable patch)
- Soil(Patch& p,Soiltype& s):patch(p),soiltype(s) {
- initdrivers();
- }
- void initdrivers() {
- // Initialises certain member variables
- alag = 0.0;
- exp_alag = 1.0;
- cpool_slow = 0.0;
- cpool_fast = 0.0;
- decomp_litter_mean = 0.0;
- k_soilfast_mean = 0.0;
- k_soilslow_mean = 0.0;
- wcont[0] = 0.0;
- wcont[1] = 0.0;
- wcont_evap = 0.0;
- snowpack = 0.0;
- orgleachfrac = 0.0;
- snowdens = 362.0;
- mwcontupper = 0.0;
- //mwcontlower = 0.0;
- for (int mth=0; mth<12; mth++) {
- mwcont[mth][0] = 0.0;
- mwcont[mth][1] = 0.0;
- fnuptake_mean[mth] = 0.0;
- morgleach_mean[mth] = 0.0;
- mminleach_mean[mth] = 0.0;
- msnd[mth] = 0.0;
- mcLitter[mth] = 0.0;
- mcLitterCwd[mth] = 0.0;
- mcLitterSurf[mth] = 0.0;
- mcLitterSubSurf[mth] = 0.0;
- mcSoil[mth] = 0.0;
- mcMedium[mth] = 0.0;
- mcSlow[mth] = 0.0;
- mnLitter[mth] = 0.0;
- mnLitterCwd[mth] = 0.0;
- mnLitterSurf[mth] = 0.0;
- mnLitterSubSurf[mth] = 0.0;
- mnSoil[mth] = 0.0;
- mnMineralNH4[mth] = 0.0;
- mnMineralNO3[mth] = 0.0;
- }
- std::fill_n(dwcontupper, Date::MAX_YEAR_LENGTH, 0.0);
- // std::fill_n(dwcontlower, Date::MAX_YEAR_LENGTH, 0.0); // ecev3
- dwcontlower_today = 0.0;
- /////////////////////////////////////////////////////
- // Initialise CENTURY pools
- // Set initial CENTURY pool N:C ratios
- // Parton et al 1993, Fig 4
- sompool[SOILMICRO].ntoc = 1.0 / 15.0;
- sompool[SURFHUMUS].ntoc = 1.0 / 15.0;
- sompool[SLOWSOM].ntoc = 1.0 / 20.0;
- sompool[SURFMICRO].ntoc = 1.0 / 20.0;
- // passive has a fixed value
- sompool[PASSIVESOM].ntoc = 1.0 / 9.0;
- nmass_avail = 0.0;
- ninput = 0.0;
- anmin = 0.0;
- animmob = 0.0;
- aminleach = 0.0;
- aorgNleach = 0.0;
- aorgCleach = 0.0;
- anfix = 0.0;
- anfix_calc = 0.0;
- anfix_mean = 0.0;
- snowpack_nmass = 0.0;
- dperc = 0.0;
- solvesomcent_beginyr = (int)(SOLVESOMCENT_SPINBEGIN * (nyear_spinup - freenyears) + freenyears);
- solvesomcent_endyr = (int)(SOLVESOMCENT_SPINEND * (nyear_spinup - freenyears) + freenyears);
- }
- void serialize(ArchiveStream& arch);
- };
- /// Container for crop-specific data at patchpft level
- struct cropphen_struct : public Serializable {
- /// latest sowing date
- int sdate;
- /// sowing date of growing period ending in latest harvest this year
- int sdate_harv;
- /// sowing dates of growing periods ending in the two latest harvests this year
- int sdate_harvest[2];
- /// sowing dates of growing periods starting this year
- int sdate_thisyear[2];
- /// number of sowings this year
- int nsow;
- /// latest harvest date
- int hdate;
- /// two latest harvest dates this year
- int hdate_harvest[2];
- /// last date for harvest
- int hlimitdate;
- /// last day of heat unit sampling period, set in Crop_sowing_date_new()
- int hucountend;
- /// number of harvests this year
- int nharv;
- /// whether sdate_harvest[0] happened last year
- bool sownlastyear;
- /// latest senescence start date this year
- int sendate;
- /// latest beginning of intercropseason (2 weeks after the harvest date)
- int bicdate;
- /// latest end of intercropseason (2 weeks before the sowing date)
- int eicdate;
- /// number of growing days this growing period
- int growingdays;
- /// number of growing days this year (used for wscal_mean calculation)
- int growingdays_y;
- /// length of growingseason ending in last harvest
- int lgp;
- /// base temp for heat unit calculation (°C)
- double tb;
- /// number of vernalising days required
- int pvd;
- /// number of accumulated vernalizing days
- int vdsum;
- /// heat unit reduction factor due to vernalization [0-1]
- double vrf;
- /// heat unit reduction factor due to photoperiodism [0-1]
- double prf;
- /// potential heat units required for crop maturity (°Cd)
- double phu;
- /// potential heat units that would have been used without dynamic phu calculation
- double phu_old;
- /// heat unit sum aquired during last growing period (°Cd)
- double husum;
- /// heat unit sum aquired durin sampling period, starting with sdate
- double husum_sampled;
- /// this year's heat unit sum aquired from sdate to hucountend
- double husum_max;
- /// running mean of recent past's husum_max
- double husum_max_10;
- /// number of heat units sampling years
- int nyears_hu_sample;
- /// fraction of growing season [0-1] (husum/phu)
- double fphu;
- /// fraction of growing season at latest harvest
- double fphu_harv;
- /// whether in period of heat unit sampling
- bool hu_samplingperiod;
- /// number of heat unit sampling days
- int hu_samplingdays;
- /// harvest index today [0-1, >1 if below-ground ho], harvestable organ/above-ground C for above-ground harvestable organs, dependent on fphu, reduced by water stress
- double hi;
- /// fraction of harvest index today
- double fhi;
- /// phenology (fphu) contribution of fraction of harvest index today
- double fhi_phen; //Phenology (fPHU) compoment of fhi
- /// water stress contribution of fraction of harvest index today
- double fhi_water;
- /// fraction of harvest index at latest harvest
- double fhi_harv;
- /// sum of crop patch demand (patch.wdemand) during crop growing period, reset on harvest day
- double demandsum_crop;
- /// sum of crop supply (patchpft.wsupply) during crop growing period, reset on harvest day
- double supplysum_crop;
- /// whether inside crop/intercrop grass growing period
- bool growingseason;
- /// whether yesterday was inside crop/intercrop grass growing period
- bool growingseason_ystd;
- /// whether inside crop senescence
- bool senescence;
- /// whether yesterday was inside crop senescence
- bool senescence_ystd;
- /// whether inside intercrop crass growing period (main crop pft variable)
- bool intercropseason;
- double vdsum_alloc;
- double vd;
- /// The fraction of the daily assimilates allocated to roots.
- double f_alloc_root;
- /// The fraction of the daily assimilates allocated to leaves.
- double f_alloc_leaf;
- /// The fraction of the daily assimilates allocated to harvestable organs, seeds.
- double f_alloc_horg;
- /// The fraction of the daily assimilates allocated to stem.
- double f_alloc_stem;
- /// Development stage from Wang & Engel 1998
- double dev_stage;
- // A variable holding the memory of whether this field was fertilised or not.
- bool fertilised[3];
- cropphen_struct() {
- sdate=-1;
- sdate_harv=-1;
- nsow=0;
- sownlastyear=false;
- sendate=-1;
- hdate=-1;
- hlimitdate=-1;
- hucountend=-1;
- nharv=0;
- tb=0.0;
- pvd=0;
- vdsum=0;
- vrf=1.0;
- phu=0.0;
- phu_old=0.0;
- husum_max=0.0;
- husum_sampled=0.0;
- husum_max_10=0.0;
- nyears_hu_sample = 0;
- prf=1.0;
- husum=0.0;
- fphu=0.0;
- fphu_harv=0.0;
- hu_samplingdays=0;
- hu_samplingperiod=false;
- hi=0.0;
- fhi=0.0;
- fhi_phen=0.0;
- fhi_water=1.0;
- fhi_harv=0.0;
- demandsum_crop=0.0;
- supplysum_crop=0.0;
- growingseason=false; //Initialized to true for normal grass growth (CC3G & CC4G) in establishment
- growingseason_ystd=false;
- senescence=false;
- senescence_ystd=false;
- intercropseason=false;
- bicdate=-1;
- eicdate=-1;
- growingdays=0;
- growingdays_y=0;
- lgp=0;
- for(int j=0;j<2;j++) {
- sdate_harvest[j]=-1;
- hdate_harvest[j]=-1;
- sdate_thisyear[j]=-1;
- }
- vdsum_alloc=0.0;
- vd = 0.0;
- f_alloc_root=0.0;
- f_alloc_leaf=0.0;
- f_alloc_horg=0.0;
- f_alloc_stem=0.0;
- dev_stage = 0.0;
- fertilised[0] = false;
- fertilised[1] = false;
- fertilised[2] = false;
- }
- void serialize(ArchiveStream& arch);
- };
- /// State variables common to all individuals of a particular PFT in a particular patch
- /** Used in individual and cohort modes only. */
- class Patchpft : public Serializable {
- // MEMBER VARIABLES:
- public:
- /// id code (equal to value of member variable id in corresponding Pft object)
- int id;
- /// reference to corresponding Pft object in PFT list
- Pft& pft;
- /// potential annual net assimilation (leaf-level net photosynthesis) at forest floor (kgC/m2/year)
- double anetps_ff;
- /// water stress parameter (0-1 range; 1=minimum stress)
- double wscal;
- /// running sum (converted to annual mean) for wscal
- double wscal_mean;
- /// potential annual net assimilation at forest floor averaged over establishment interval (kgC/m2/year)
- double anetps_ff_est;
- /// first-year value of anetps_ff_est
- double anetps_ff_est_initial;
- /// annual mean wscal averaged over establishment interval
- double wscal_mean_est;
- /// vegetation phenological state (fraction of potential leaf cover), updated daily
- double phen;
- /// annual sum of daily fractional leaf cover
- /** equivalent number of days with full leaf cover
- * (reset on expected coldest day of year)
- */
- double aphen;
- /// whether PFT can establish in this patch under current conditions
- bool establish;
- /// running total for number of saplings of this PFT to establish (cohort mode)
- double nsapling;
- /// leaf-derived litter for PFT on modelled area basis (kgC/m2)
- double litter_leaf;
- /// fine root-derived litter for PFT on modelled area basis (kgC/m2)
- double litter_root;
- /// remaining sapwood-derived litter for PFT on modelled area basis (kgC/m2)
- double litter_sap;
- /// year's sapwood-derived litter for PFT on modelled area basis (kgC/m2)
- double litter_sap_year;
- /// remaining heartwood-derived litter for PFT on modelled area basis (kgC/m2)
- double litter_heart;
- /// year's heartwood-derived litter for PFT on modelled area basis (kgC/m2)
- double litter_heart_year;
- /// litter derived from allocation to reproduction for PFT on modelled area basis (kgC/m2)
- double litter_repr;
- /// leaf-derived nitrogen litter for PFT on modelled area basis (kgN/m2)
- double nmass_litter_leaf;
- /// root-derived nitrogen litter for PFT on modelled area basis (kgN/m2)
- double nmass_litter_root;
- /// remaining sapwood-derived nitrogen litter for PFT on modelled area basis (kgN/m2)
- double nmass_litter_sap;
- /// year's sapwood-derived nitrogen litter for PFT on modelled area basis (kgN/m2)
- double nmass_litter_sap_year;
- /// remaining heartwood-derived nitrogen litter for PFT on modelled area basis (kgN/m2)
- double nmass_litter_heart;
- /// year's heartwood-derived nitrogen litter for PFT on modelled area basis (kgN/m2)
- double nmass_litter_heart_year;
- /// non-FPC-weighted canopy conductance value for PFT under water-stress conditions (mm/s)
- double gcbase;
- /// daily value of the above variable (mm/s)
- double gcbase_day;
- /// evapotranspirational "supply" function for this PFT today (mm/day)
- double wsupply;
- double wsupply_leafon;
- /// fractional uptake of water from each soil layer today
- double fwuptake[NSOILLAYER];
- /// whether water-stress conditions for this PFT
- bool wstress;
- /// daily version of the above variable
- bool wstress_day;
- /// carbon depository for long-lived products like wood
- double harvested_products_slow;
- /// nitrogen depository for long-lived products like wood
- double harvested_products_slow_nmass;
- /// first and last day of crop sowing window, calculated in crop_sowing_patch() or Crop_sowing_date_new()
- int swindow[2];
- /// daily value of water deficit, calculated in irrigated_water_uptake()
- double water_deficit_d;
- /// yearly sum of water deficit
- double water_deficit_y;
- /// Struct for crop-specific variables
- cropphen_struct *cropphen;
- // MEMBER FUNCTIONS:
- /// Constructor: initialises id, pft and data members
- Patchpft(int i,Pft& p):id(i),pft(p) {
- litter_leaf = 0.0;
- litter_root = 0.0;
- litter_sap = 0.0;
- litter_sap_year = 0.0;
- litter_heart = 0.0;
- litter_heart_year = 0.0;
- litter_repr = 0.0;
- nmass_litter_leaf = 0.0;
- nmass_litter_root = 0.0;
- nmass_litter_sap = 0.0;
- nmass_litter_sap_year = 0.0;
- nmass_litter_heart = 0.0;
- nmass_litter_heart_year = 0.0;
- wscal = 1.0;
- wscal_mean = 1.0;
- anetps_ff = 0.0;
- aphen = 0.0;
- phen = 0.0;
- wsupply = 0.0;
- wsupply_leafon = 0.0;
- anetps_ff_est = 0.0;
- anetps_ff_est_initial = 0.0;
- wscal_mean_est = 0.0;
- nsapling = 0;
- for(int i=0;i<NSOILLAYER;i++)
- fwuptake[i]=0.0;
- cropphen = NULL;
- harvested_products_slow = 0.0;
- harvested_products_slow_nmass = 0.0;
- swindow[0]=-1;
- swindow[1]=-1;
- if(pft.landcover==CROPLAND)
- {
- cropphen=new cropphen_struct;
- }
- // ecev3 - more initialisation
- phen = 0.0;
- anetps_ff_est = 0.0;
- anetps_ff_est_initial = 0.0;
- wscal_mean_est = 0.0;
- }
- ~Patchpft() {
- if(cropphen) {
- delete cropphen;
- }
- }
- /// safe method to obtain cropphen_struct pointer
- cropphen_struct* get_cropphen();
- /// safe method to set cropphen_struct variables
- cropphen_struct* set_cropphen();
- bool growingseason() const;
- void serialize(ArchiveStream& arch);
- };
- /// Stores data for a patch.
- /** In cohort and individual modes, replicate patches are
- * required in each stand to accomodate stochastic variation; in population mode there
- * should be just one Patch object, representing average conditions for the entire
- * stand. A reference to the parent Stand object (defined below) is included as a
- * member variable.
- */
- class Patch : public Serializable {
- public:
- // MEMBER VARIABLES
- /// id code in range 0-npatch for patch
- int id;
- /// reference to parent Stand object
- Stand& stand;
- /// list array [0...npft-1] of Patchpft objects (initialised in constructor)
- ListArray_idin1<Patchpft,Pft> pft;
- /// vegetation for this patch
- Vegetation vegetation;
- /// soil for this patch
- Soil soil;
- /// fluxes for this patch
- Fluxes fluxes;
- /// FPAR at top of grass canopy today
- double fpar_grass;
- /// FPAR at soil surface today
- double fpar_ff;
- /// mean growing season PAR at top of grass canopy (J/m2/day)
- double par_grass_mean;
- /// number of days in growing season, estimated from mean vegetation leaf-on fraction
- /** \see function fpar in canopy exchange module */
- int nday_growingseason;
- /// total patch FPC
- double fpc_total;
- /// whether patch was disturbed last year
- bool disturbed;
- /// patch age (years since last disturbance)
- int age;
- /// probability of fire this year
- double fireprob;
- /// whether management has started on this patch
- bool managed;
- /// cutting intensity (initial percent of trees cut, further selection at individual level has to be done in a separate function)
- double man_strength;
- bool managed_this_year;
- bool plant_this_year;
- /// DLE - the number of days over which wcont is averaged for this patch
- /** i.e. those days for which daily temp > 5.0 degC */
- int growingseasondays;
- // Variables used by new hydrology (Dieter Gerten 2002-07)
- /// interception by vegetation today on patch basis (mm)
- double intercep;
- /// annual sum of AET (mm/year)
- double aaet;
- /// annual sum of AET (mm/year) for each of the last five simulation years
- Historic<double, NYEARAAET> aaet_5;
- /// annual sum of soil evaporation (mm/year)
- double aevap;
- /// annual sum of interception (mm/year)
- double aintercep;
- /// annual sum of runoff (mm/year)
- double asurfrunoff;
- /// annual sum of runoff (mm/year)
- double adrainrunoff;
- /// annual sum of runoff (mm/year)
- double abaserunoff;
- /// annual sum of runoff (mm/year)
- double arunoff;
- /// annual sum of potential evapotranspiration (mm/year)
- double apet;
- /// equilibrium evapotranspiration today, deducting interception (mm)
- double eet_net_veg;
- /// transpirative demand for patch, patch vegetative area basis (mm/day)
- double wdemand;
- /// daily average of the above variable (mm/day)
- double wdemand_day;
- /// transpirative demand for patch assuming full leaf cover today
- /** mm/day, patch vegetative area basis */
- double wdemand_leafon;
- /// rescaling factor to account for spatial overlap between individuals/cohorts populations
- double fpc_rescale;
- /// monthly AET (mm/month)
- double maet[12];
- /// monthly soil evaporation (mm/month)
- double mevap[12];
- /// monthly interception (mm/month)
- double mintercep[12];
- /// monthly runoff (mm/month)
- double mrunoff[12];
- /// monthly surface runoff (mm/month)
- double mrunoff_surf[12];
- /// monthly PET (mm/month)
- double mpet[12];
- /// daily nitrogen demand
- double ndemand;
- /// annual nitrogen fertilization (kgN/m2/year)
- double anfert;
- /// daily nitrogen fertilization (kgN/m2/day)
- double dnfert;
- /// daily value of irrigation water (mm), set in irrigation(), derived from water_deficit_d
- double irrigation_d;
- /// monthly sum of irrigation water (mm)
- double irrigation_m[12];
- /// yearly sum of irrigation water (mm)
- double irrigation_y;
- /// whether litter is to be sent to the soil today
- bool is_litter_day;
- /// number of harvests and/or cover-crop killing or turnover events
- int nharv;
- /// whether today is a harvest day and/or cover-crop killing or turnover day
- bool isharvestday;
- // C4MIP / CRESCENDO
- /// monthly vegetation carbon (kg C m-2)
- double mcVeg[12];
- /// monthly vegetation nitrogen (kg N m-2)
- double mnVeg[12];
- /// monthly leaf carbon (kg C m-2)
- double mcLeaf[12];
- /// monthly leaf nitrogen (kg N m-2)
- double mnLeaf[12];
- /// monthly root carbon (kg C m-2)
- double mcRoot[12];
- /// monthly root nitrogen (kg N m-2)
- double mnRoot[12];
- /// monthly stem carbon (kg C m-2)
- double mcStem[12];
- /// monthly stem nitrogen (kg N m-2)
- double mnStem[12];
- /// monthly other plant parts carbon (kg C m-2)
- double mcOther[12];
- /// monthly other plant parts carbon (Phen) (kg C m-2)
- double mcOtherPhen[12];
- /// monthly other plant parts nitrogen (kg N m-2)
- double mnOther[12];
- /// monthly product carbon (kg C m-2)
- double mcProduct[12];
- /// monthly product nitrogen (kg N m-2)
- double mnProduct[12];
- /// monthly total land carbon (kg C m-2)
- double mcLand[12];
- /// monthly total land nitrogen (kg N m-2)
- double mnLand[12];
- /// daily total LAI (m2 m-2)
- double dlai[366];
- /// daily PET (mm day-1)
- double dpet[366];
- /// daily AET (mm day-1)
- double daet[366];
- /// daily soil evaporation (mm day-1)
- double devap[366];
- /// daily interception by vegetation (mm day-1)
- double dintercep[366];
- /// daily runoff (mm day-1)
- double dmrro[366];
- /// LUMIP deforest_glob: Whether for this patch a deforestation is active
- bool deforest_active;
- #ifdef CRESCENDO_FACE
- /// CRESCENDO FACE only variables
- /// daily runoff (mm day-1)
- double drunoff[366];
- /// daily drainage (mm day-1)
- double ddrain[366];
- /// daily leaf carbon (kg C m-2)
- double dcLeaf[366];
- /// daily leaf nitrogen (kg N m-2)
- double dnLeaf[366];
- /// daily root carbon (kg C m-2)
- double dcRoot[366];
- /// daily root nitrogen (kg N m-2)
- double dnRoot[366];
- /// daily stem carbon (kg C m-2)
- double dcStem[366];
- /// daily stem nitrogen (kg N m-2)
- double dnStem[366];
- /// daily other plant parts carbon (kg C m-2)
- double dcOther[366];
- /// daily other plant parts nitrogen (kg N m-2)
- double dnOther[366];
- /// Leaf carbon growth (kg C m-2)
- double gl;
- /// Wood carbon growth
- double gw;
- /// Root carbon growth
- double gr;
- #endif
- // MEMBER FUNCTIONS
- /// Constructor: initialises various members and builds list array of Patchpft objects.
- Patch(int i,Stand& s,Soiltype& st);
- void serialize(ArchiveStream& arch);
- /// Returns the Climate for this Patch
- /** This function returns a const reference to prevent code which operates
- * on a patch basis to modify the climate and thereby affect other
- * patches/stands.
- */
- const Climate& get_climate() const;
- /// Returns whether we should model fire in this patch
- bool has_fires() const;
- /// Returns whether we should model disturbances in this patch
- bool has_disturbances() const;
- /// Total patch carbon biomass and litter
- double ccont(double scale_indiv = 1.0, bool luc = false);
- /// Total patch nitrogen biomass and litter
- double ncont(double scale_indiv = 1.0, bool luc = false);
- /// Total patch carbon fluxes so far this year
- double cflux();
- /// Total patch nitrogen fluxes so far this year
- double nflux();
-
- /// Get 5-year mean of wood C mass increase (periodic annual increment)
- double get_cmass_wood_inc_5() {
- double cmass_wood_inc_5_mean = 0.0;
- for (unsigned int i=0; i<vegetation.nobj; i++) {
- // Disregard shrubs (crownarea_max = 10)
- Individual& indiv = vegetation[i];
- if(indiv.pft.lifeform == TREE && indiv.pft.crownarea_max > 10) {
- if(indiv.cmass_wood_inc_5.size())
- cmass_wood_inc_5_mean += indiv.cmass_wood_inc_5.mean();
- }
- }
- return cmass_wood_inc_5_mean;
- }
-
- /// Get cmass_wood of all individuals in patch
- double cmass_wood() {
- double cmass_wood = 0.0;
- for (unsigned int i=0; i<vegetation.nobj; i++) {
- Individual& indiv = vegetation[i];
- cmass_wood += indiv.cmass_wood();
- }
- return cmass_wood;
- }
- };
- /// Container for variables common to individuals of a particular PFT in a stand.
- /** Used in individual and cohort modes only
- */
- class Standpft : public Serializable {
- public:
- // MEMBER VARIABLES
- int id;
- Pft& pft;
- /// net C allocated to reproduction for this PFT in all patches of this stand this year (kgC/m2)
- double cmass_repr;
- /// maximum value of Patchpft::anetps_ff for this PFT in this stand so far in the simulation (kgC/m2/year)
- double anetps_ff_max;
- /// FPC sum for this PFT as average for stand
- double fpc_total;
- /// Photosynthesis values for this PFT under non-water-stress conditions
- PhotosynthesisResult photosynthesis;
- /// Whether this PFT is allowed to grow in this stand
- bool active;
- /// Whether this PFT is planted in this stand
- bool plant;
- /// Whether this PFT is allowed to establish (after planting) in this stand
- bool reestab;
- /// Whether this PFT is irrigated in this stand
- bool irrigated;
- /// sowing date specified in stand type or read from input file
- int sdate_force;
- /// harvest date specified in stand type or read from input file
- int hdate_force;
- // MEMBER FUNCTIONS
- /// Constructor: initialises various data members
- Standpft(int i,Pft& p):id(i),pft(p) {
- anetps_ff_max = 0.0;
- active = !run_landcover;
- plant = false;
- reestab = false;
- irrigated = false;
- sdate_force = -1;
- hdate_force = -1;
- }
- void serialize(ArchiveStream& arch);
- };
- /// The stand class corresponds to a modelled area of a specific landcover type in a grid cell.
- /** There may be several stands of the same landcover type (but with different settings).
- */
- class Stand : public ListArray_idin2<Patch,Stand,Soiltype>, public Serializable {
- public:
- // MEMBER VARIABLES
- /// list array [0...npft-1] of Standpft (initialised in constructor)
- ListArray_idin1<Standpft,Pft> pft;
- /// A number identifying this Stand within the grid cell
- int id;
- /// stand type id
- int stid;
- /// pft id of main crop, updated during rotation
- int pftid;
- /// current crop rotation item
- int current_rot;
- /// number of days passed in current rotation item
- int ndays_inrotation;
- /// Returns true if stand is in fallow (with cover crop grass)
- bool infallow;
- /// Returns true if crop rotation item is to be updated today
- bool isrotationday;
- /// Returns true if current crop management hydrology == irrigated, updated during rotation
- bool isirrigated;
- /// Returns true if the stand's main crop pft intercrop==naturalgrass and a pft with isintercrop==true is in the pftlist.
- bool hasgrassintercrop;
- /// gdd5-value at first intercrop grass growth
- double gdd0_intercrop;
- /// old fraction of this stand relative to the gridcell before update
- double frac_old;
- /// used during land cover change involving several calls to reveiving_stand_change()
- /** Set to frac_old in reduce_stands(), then modified in donor_stand_change() and receiving_stand_change().
- */
- double frac_temp;
- /// fraction unavailable for transfer to other stand types
- double protected_frac;
- /// net stand fraction change
- double frac_change;
- /// gross fraction increase
- double gross_frac_increase;
- /// gross fraction decrease
- double gross_frac_decrease;
- /// fraction that has been cloned from another stand
- double cloned_fraction;
- /// Returns true if this stand is cloned from another stand
- bool cloned;
- /// pointer to array of fractions transferred from this stand to other stand types
- double *transfer_area_st;
- /// land cover origin of this stand
- landcovertype origin;
- /// used for output from separate stands
- double anpp;
- /// used for output from separate stands
- double cmass;
- /// Seed for generating random numbers within this Stand
- /** The reason why Stand has its own seed, rather than using for instance
- * a single global seed is to make it easier to compare results when using
- * different land cover types.
- *
- * Randomness not associated with a specific stand, but rather a whole
- * grid cell should instead use the seed in the Gridcell class.
- *
- * \see randfrac()
- */
- long seed;
- /// type of landcover
- /** \see landcovertype
- * initialised in constructor
- */
- landcovertype landcover;
- /// The year when this stand was created.
- /** Will typically be year zero unless running with dynamic
- * land cover.
- *
- * Needed to set patchpft.anetps_ff_est_initial
- */
- int first_year;
- // The year this stand was cloned from another stand
- int clone_year;
- /// scaling factor for stands that have grown in area this year (old fraction/new fraction)
- double scale_LC_change;
- // ecev3 - NEW MEMBER VARIABLES
- /// Integer type identifying the IFS high vegetation type (0-20). 0 for low vegetation
- //int typehigh;
- /// Fraction of the gridcell covered by the dominant vegetation type
- //double frachigh;
- /// grass LAI on stand basis
- //float laiphen_grass[366];
- /// total LAI on stand basis
- //float laiphen_total[366];
- /// total daily natural cflux on stand basis (kg C m-2)
- float dcfluxnat_today;
- /// total daily anthropogenic cflux on stand basis (kg C m-2)
- float dcfluxant_today;
- /// total daily NPP on stand basis (kg C m-2)
- float dnpp_today;
- /// Sum of natural fluxes. Updated on Dec 31
- double previousyearsCfluxNat; // was previousyearsCflux
- /// Sum of anthropogenic fluxes. Updated on Dec 31
- float previousyearsCfluxAnt; // was previousyearsCfireflux, now a float since it took the place of dnpp_today
- /// Total land C pool on 1st of Jan
- double cLand;
- /// Total land C flux during the year
- double cFlux;
-
- // MEMBER FUNCTIONS
- /// Constructs a Stand
- /** \param i The id for the stand within the grid cell
- * \param gc The parent grid cell
- * \param st The soil type to be used within this Stand
- * \param landcover The type of landcover to use for this stand
- */
- Stand(int i, Gridcell* gc, Soiltype& st, landcovertype landcover, int no_patch = 0);
- ~Stand();
- /// Gives the fraction of this Stand relative to the whole grid cell
- double get_gridcell_fraction() const;
- /// Gives the fraction of this Stand relative to its land cover type; NB: unsafe to use within landcover_dynamics() !
- double get_landcover_fraction() const;
- /// Set the fraction of this Stand relative to the gridcell
- void set_gridcell_fraction(double fraction);
- /// Returns the number of patches in this Stand
- unsigned int npatch() const { return nobj; }
- /// Returns true if stand is true crop stand, as opposed to pasture grass grown on cropland or other land cover
- inline bool is_true_crop_stand() {
- return landcover==CROPLAND && pft[pftid].pft.phenology==CROPGREEN; // OK also for fallow (pftid always cropgreen)
- }
- /// Moves crop rotation forward
- void rotate();
- /// Returns area transferred to other land cover during land cover change
- double transfer_area_lc(landcovertype to);
- /// Initiates new stand land cover settings
- void init_stand_lu(StandType& st, double fraction);
- /// Total stand carbon biomass and litter
- double ccont(double scale_indiv = 1.0);
- /// Total stand nitrogen biomass and litter
- double ncont(double scale_indiv = 1.0);
- /// Total stand carbon fluxes so far this year
- double cflux();
- /// Total stand nitrogen fluxes so far this year
- double nflux();
- /// Creates a duplicate stand with a new landcovertype
- /** The new stand is added to this stand's gridcell.
- *
- * \returns reference to the new stand
- */
- Stand& clone(StandType& st, double fraction);
- void serialize(ArchiveStream& arch);
- /// Returns the Climate for this Stand
- /** This function returns a const reference to prevent code which operates
- * on a stand basis to modify the climate and thereby affect other
- * stands.
- */
- const Climate& get_climate() const;
- /// Returns the Gridcell containing this Stand
- Gridcell& get_gridcell() const;
- private:
- /// Pointer to parent object, could be a null pointer
- /** Prefer to access the gridcell through get_gridcell(), even internally
- * within the Stand class.
- */
- Gridcell* gridcell;
- /// Soil type to be used in this Stand
- Soiltype& soiltype;
- /// Fraction of this stand relative to the gridcell
- /** used by crop stands; initialized in constructor to 1,
- * set in landcover_init()
- */
- double frac;
- };
- /// State variables common to all individuals of a particular PFT in a GRIDCELL.
- class Gridcellpft : public Serializable {
- public:
- // MEMBER VARIABLES
- /// A number identifying this object within its list array
- int id;
- /// A reference to the Pft object for this Gridcellpft
- Pft& pft;
- /// annual degree day sum above threshold damaging temperature
- /** used in calculation of heat stess mortality; Sitch et al 2000, Eqn 55
- */
- double addtw;
- /// Michaelis-Menten kinetic parameters
- /** Half saturation concentration for N uptake (Rothstein 2000, Macduff 2002)
- */
- double Km;
- ///Crop-specific variables:
- /// whether the daily temperature has fallen below the autumn temperature limit (tempautumn) this year
- bool autumnoccurred;
- /// whether the daily temperature has risen above the spring temperature limit (tempspring) this year
- bool springoccurred;
- /// whether the daily temperature has fallen below the vernalization limit (trg) this year
- bool vernstartoccurred;
- /// whether the daily temperature rises over the vernalization limit (trg) this year
- bool vernendoccurred;
- /// first day when temperature fell below the autumn temperature limit (tempautumn) this year
- int first_autumndate;
- /// 20-year mean
- int first_autumndate20;
- /// memory of the last 20 years' values
- int first_autumndate_20[20];
- /// last day when temperature rose above the spring temperature limit (tempspring) this year
- int last_springdate;
- /// 20-year mean
- int last_springdate20;
- /// memory of the last 20 years' values
- int last_springdate_20[20];
- /// last day when temperature has fallen below the vernilisation temperature limit (trg) this year (if vernstartoccurred==true)
- int last_verndate;
- /// 20-year mean
- int last_verndate20;
- /// memory of the last 20 years' values
- int last_verndate_20[20];
- /// default sowing date (pft.sdatenh/sdatesh)
- int sdate_default;
- /// calculated sowing date from temperature limits
- int sdatecalc_temp;
- /// calculated sowing date from precipitation limits
- int sdatecalc_prec;
- /// sowing date from input file
- int sdate_force;
- /// harvest date from input file
- int hdate_force;
- /// N fertilization from input file
- double Nfert_read;
- /// default harvest date (pft.hlimitdatenh/hlimitdatesh)
- int hlimitdate_default;
- /// whether autumn sowing is either calculated or prescribed
- bool wintertype;
- /// first and last day of crop sowing window, calculated in calc_sowing_windows()
- int swindow[2];
- /// first and last day of crop sowing window for irrigated crops, calculated in calc_sowing_windows()
- int swindow_irr[2];
- /// temperature limits precludes crop sowing
- bool sowing_restriction;
- // MEMBER FUNCTIONS
- /// Constructs a Gridcellpft object
- /** \param i The id for this object
- * \param p A reference to the Pft for this Gridcellpft
- */
- Gridcellpft(int i,Pft& p):id(i),pft(p) {
- addtw = 0.0;
- Km = 0.0;
- autumnoccurred=false;
- springoccurred=false;
- vernstartoccurred=false;
- vernendoccurred=false;
- first_autumndate=-1;
- first_autumndate20=-1;
- last_springdate=-1;
- last_springdate20=-1;
- last_verndate=-1;
- last_verndate20=-1;
- for (int year=0;year<20;year++) {
- first_autumndate_20[year]=-1;
- last_springdate_20[year]=-1;
- last_verndate_20[year]=-1;
- }
- sdate_default=-1;
- sdate_force=-1;
- hdate_force=-1;
- Nfert_read=-1;
- sdatecalc_temp=-1;
- sdatecalc_prec=-1;
- hlimitdate_default=-1;
- wintertype=false;
- swindow[0]=-1;
- swindow[1]=-1;
- sowing_restriction = false;
- }
- void serialize(ArchiveStream& arch);
- };
- /// State variables common to all individuals of a particular STANDTYPE in a GRIDCELL.
- class Gridcellst : public Serializable {
- public:
- // MEMBER VARIABLES
- /// A number identifying this object within its list array
- int id;
- /// A reference to the StandType object for this Gridcellst
- StandType& st;
- /// fraction of this stand type relative to the gridcell
- double frac;
- /// old fraction of this stand type relative to the gridcell before update
- double frac_old;
- /// original input value of old fraction of this stand type before rescaling
- double frac_old_orig;
- /// fraction unavailable for transfer to other stand types
- double protected_frac;
- /// net fraction change
- double frac_change;
- /// gross fraction increase
- double gross_frac_increase;
- /// gross fraction decrease
- double gross_frac_decrease;
- // current number of stands of this stand type
- int nstands;
- /// Nitrogen fertilisation amount
- double nfert;
- /// Harvested forest area fraction
- double woodharv_frac;
- /// Wood harvest volume
- double woodharv_vol;
- // MEMBER FUNCTIONS
- /// Constructs a Gridcellst object
- /** \param i The id for this object
- * \param s A reference to the StandType for this Gridcellst
- */
- Gridcellst(int i,StandType& s):id(i),st(s) {
- frac = 1.0;
- frac_old = 0.0;
- frac_old_orig = 0.0;
- protected_frac = 0.0;
- frac_change = 0.0;
- gross_frac_increase = 0.0;
- gross_frac_decrease = 0.0;
- nstands = 0;
- nfert = -1.0;
- woodharv_frac = -1.0;
- woodharv_vol = -1.0;
- }
- void serialize(ArchiveStream& arch);
- };
- struct forest_lc_frac_transfer {
- double primary[NLANDCOVERTYPES][NLANDCOVERTYPES];
- double secondary_young[NLANDCOVERTYPES][NLANDCOVERTYPES];
- forest_lc_frac_transfer() {
- for(int i=0;i<NLANDCOVERTYPES;i++) {
- for(int j=0;j<NLANDCOVERTYPES;j++) {
- primary[i][j] = 0.0;
- secondary_young[i][j] = 0.0;
- }
- }
- };
- };
- struct forest_st_frac_transfer {
- double* primary;
- double* secondary_young;
- forest_st_frac_transfer(int nst) {
- primary = new double[nst * nst];
- secondary_young = new double[nst * nst];
- for(int i=0;i<nst*nst;i++) {
- primary[i] = 0.0;
- secondary_young[i] = 0.0;
- }
- };
- ~forest_st_frac_transfer(){
- if(primary)
- delete[] primary;
- if(secondary_young)
- delete[] secondary_young;
- }
- };
- /// Storage of land cover fraction data and some land cover change-related pools and fluxes
- struct Landcover : public Serializable {
- Landcover();
- /// The fractions of the different land cover types.
- /** landcoverfrac is read in from land cover input file or from
- * instruction file in getlandcover().
- */
- double frac[NLANDCOVERTYPES];
- /// The land cover fractions from the previous year
- /** Used to keep track of the changes when running with dynamic
- * land cover.
- */
- double frac_old[NLANDCOVERTYPES];
- double frac_change[NLANDCOVERTYPES];
- /// Wood harvest information read from input file.
- Wood_harvest_struct wood_harvest;
- /// Transfer matrices
- double frac_transfer[NLANDCOVERTYPES][NLANDCOVERTYPES];
- forest_lc_frac_transfer forest_lc_frac_transfer_s;
- /// Whether the land cover fractions changed for this grid cell this year
- /** \see landcover_dynamics
- */
- bool updated;
- /// ecev3 - Gridcell-level C flux from slow harvested products TODAY
- double dcflux_harvest_slow;
- /// Gridcell-level C flux from harvest associated with landcover change TODAY
- double dcflux_landuse_change;
- /// Gridcell-level C flux from slow harvested products
- double acflux_harvest_slow;
- /// Gridcell-level C products from harvest associated with landcover change
- double harvest_product;
- /// Gridcell-level N products from harvest associated with landcover change
- double harvest_product_nmass;
- /// Gridcell-level C residue input to litter from harvest associated with landcover change
- double acflux_harvest_wood_res;
- /// Gridcell-level C flux from harvest associated with landcover change
- double acflux_landuse_change;
- /// Gridcell-level N flux from slow harvested products
- double anflux_harvest_slow;
- /// Gridcell-level N flux from harvest associated with landcover change
- double anflux_landuse_change;
- /// Landcover-level C flux from slow harvested products (donating landcover)
- double acflux_harvest_slow_lc[NLANDCOVERTYPES];
- /// Landcover-level C products from harvest associated with landcover change
- double harvest_product_lc[NLANDCOVERTYPES];
- /// Landcover-level N products from harvest associated with landcover change
- double harvest_product_nmass_lc[NLANDCOVERTYPES];
- /// Landcover-level C residue input to litter from harvest associated with landcover change (donating landcover)
- double acflux_harvest_wood_res_lc[NLANDCOVERTYPES];
- /// Landcover-level C flux from harvest associated with landcover change (donating landcover)
- double acflux_landuse_change_lc[NLANDCOVERTYPES];
- /// Landcover-level N flux from slow harvested products (donating landcover)
- double anflux_harvest_slow_lc[NLANDCOVERTYPES];
- /// Landcover-level N flux from harvest associated with landcover change (donating landcover)
- double anflux_landuse_change_lc[NLANDCOVERTYPES];
- /// Which landcover types create new stands when area increases.
- bool expand_to_new_stand[NLANDCOVERTYPES];
- /// Whether to pool all transferred land from a donor landcover (overrides different landcover targets of different stand types and stands in a landcover)
- bool pool_to_all_landcovers[NLANDCOVERTYPES];
- /// Whether to pool transferred land to a receptor landcover (crop and pasture stands to new natural stand: pool!)
- bool pool_from_all_landcovers[NLANDCOVERTYPES];
- void serialize(ArchiveStream& arch);
- };
- /// The Gridcell class corresponds to a modelled locality or grid cell.
- /** Member variables include an object of type Climate (holding climate, insolation and
- * CO2 data), a object of type Soiltype (holding soil static parameters) and a list
- * array of Stand objects. Soil objects (holding soil state variables) are associated
- * with patches, not gridcells. A separate Gridcell object must be declared for each modelled
- * locality or grid cell.
- */
- class Gridcell : public GuessContainer<Stand>, public Serializable {
- public:
- // MEMBER VARIABLES
- /// climate, insolation and CO2 for this grid cell
- Climate climate;
- /// soil static parameters for this grid cell
- Soiltype soiltype;
- /// landcover fractions and landcover-specific variables
- Landcover landcover;
- /// Total gridcell C mass on first day of each month including accumulated NPP [kg C m-2]
- double mcLand1[12];
- /// Total gridcell C mass on Jan 1 including yearly fluxes happening on Dec 31 previous year [kg C m-2]
- double cLand;
- /// Total gridcell C flux (including organic C leaching) over current year but with previous years Dec 31 yearly fluxes [kg C m-2]
- double cFlux;
- /// Previous years Dec 31 yearly natural fluxes [kg C m-2]
- double previousyearsCfluxNat; // was previousyearsCflux
- /// Previous years Dec 31 yearly anthropogenic fluxes [kg C m-2]
- double previousyearsCfluxAnt; // was previousyearsCfireflux
- // ecev3 - For coupling to IFS - MUST be serialized!!!!
- int id;
- int ifs_index;
- int IFStypehigh; // 0 to 20
- double IFSfrachigh; // 0 to 1
- int IFStypelow; // 0 to 20
- double IFSfraclow; // 0 to 1. Note: IFSfrachigh + IFSfraclow <= 1
- bool transferhightolow;
- int simulationyear; // 0 to nyear_spinup during spinup, then date.year
- bool isspinup;
- int ndep_lon_index, ndep_lat_index; // For CMIP6 N dep data
- int ndep_index; // For conservatively remapped CMIP6 N dep data
- double mdrynhx[12], mwetnhx[12], mdrynoy[12], mwetnoy[12], mndrydep[12], mnwetdep[12];
- // ecev3 - the following do not need to be serialized
- double laiphen_high_today; // updated daily
- double laiphen_low_today; // updated daily
- double landcover_fpc[NLANDCOVERTYPES]; // updated on Dec 31
- double landcover_lai[NLANDCOVERTYPES]; // updated on Dec 31
- double naturaltreeFPC; // (0-1) - NATURAL stand, calculated on Dec 31
- double naturalgrassFPC; // (0-1) - NATURAL stand, calculated on Dec 31
- int fixedLUafter; // Year from which on Land Use is frozen
- // ecev3 - inputs from IFS to be output for checking
- double ifs_co2[366];
- double ifs_par[366];
- double ifs_lw[366];
- double ifs_precip[366];
- double ifs_temp2m[366];
- double ifs_tempsoil[366];
- double ifs_soilw_surf[366];
- double ifs_soilw_deep[366];
- /// average gridcell soil column wcont for this year for each of the last five simulation years
- Historic<double, 5> awcont_5;
- Date date; // allow each gridcell to keep track of its own date
-
- /// Nitrogen deposition forcing for current gridcell
- Lamarque::NDepData ndepts;
- /// list array [0...npft-1] of Gridcellpft (initialised in constructor)
- ListArray_idin1<Gridcellpft,Pft> pft;
- /// list array [0...nst-1] of Gridcellst (initialised in constructor)
- ListArray_idin1<Gridcellst,StandType> st;
- /// object for keeping track of carbon and nitrogen balance
- MassBalance balance;
- /// Seed for generating random numbers within this Gridcell
- /** The reason why Gridcell has its own seed, rather than using for instance
- * a single global seed is to make it easier to compare results when for
- * instance changing the order in which the simulation proceeds. It also
- * gets serialized together with the rest of the Gridcell state to make it
- * possible to get exactly identical results after a restart.
- *
- * \see randfrac()
- */
- long seed;
- // MEMBER FUNCTIONS
- /// Constructs a Gridcell object
- Gridcell();
- /// Longitude for this grid cell
- double get_lon() const;
- /// Latitude for this grid cell
- double get_lat() const;
- /// Set longitude and latitude for this grid cell
- void set_coordinates(double longitude, double latitude);
- /// Get nitrogen deposition data for this point
- bool getndep(const char* ndepfile, double rcp);
- /// Get historical CMIP6 nitrogen deposition data for this point
- bool getndepCMIP6(const char* ndepfile, int fixedNDepafter);
- /// Get simulation year
- int getsimulationyear(int year);
- void serialize(ArchiveStream& arch);
- /// Creates a new Stand in this grid cell
- Stand& create_stand(landcovertype lc, int no_patch = 0);
- /// Creates new stand and initiates land cover settings when run_landcover==true
- Stand& create_stand_lu(StandType& st, double fraction, int no_patch = 0);
- /// Total gridcell carbon biomass and litter
- double ccont();
- /// Total gridcell nitrogen biomass and litter
- double ncont();
- /// Total gridcell carbon fluxes so far this year
- double cflux();
- /// Total gridcell nitrogen fluxes so far this year
- double nflux();
- /// Deletes the stand which the iterator is pointing at
- /** Returns an iterator pointing to the object following the erased object.
- */
- iterator delete_stand(iterator itr);
- /// Returns number of stands
- unsigned int nbr_stands() const;
- // ecev3 - set first year
- void set_first_year(int fy);
- private:
- /// Longitude for this grid cell
- double lon;
- /// Latitude for this grid cell
- double lat;
- };
- #endif // LPJ_GUESS_GUESS_H
- ///////////////////////////////////////////////////////////////////////////////////////
- // REFERENCES
- //
- // LPJF refers to the original FORTRAN implementation of LPJ as described by Sitch
- // et al 2000
- // Delmas, R., Lacaux, J.P., Menaut, J.C., Abbadie, L., Le Roux, X., Helaa, G., Lobert, J., 1995.
- // Nitrogen compound emission from biomass burning in tropical African Savanna FOS/DECAFE 1991
- // experiment. Journal of Atmospheric Chemistry 22, 175-193.
- // Cosby, B. J., Hornberger, C. M., Clapp, R. B., & Ginn, T. R. 1984 A statistical
- // exploration of the relationships of soil moisture characteristic to the
- // physical properties of soil.
- // Water Resources Research, 20: 682-690.
- // Franzlubbers, AJ & Stuedemann, JA 2009 Soil-profile organic carbon and total
- // nitrogen during 12 years of pasture management in the Southern Piedmont USA.
- // Agriculture Ecosystems & Environment, 129, 28-36.
- // Friend, A. D., Stevens, A. K., Knox, R. G. & Cannell, M. G. R. 1997. A
- // process-based, terrestrial biosphere model of ecosystem dynamics
- // (Hybrid v3.0). Ecological Modelling, 95, 249-287.
- // Fulton, MR 1991 Adult recruitment rate as a function of juvenile growth in size-
- // structured plant populations. Oikos 61: 102-105.
- // Haxeltine A & Prentice IC 1996 BIOME3: an equilibrium terrestrial biosphere
- // model based on ecophysiological constraints, resource availability, and
- // competition among plant functional types. Global Biogeochemical Cycles 10:
- // 693-709
- // Lloyd, J & Taylor JA 1994 On the temperature dependence of soil respiration
- // Functional Ecology 8: 315-323
- // Macduff, JH, Humphreys, MO & Thomas, H 2002. Effects of a stay-green mutation on
- // plant nitrogen relations in Lolium perenne during N starvation and after
- // defoliation. Annals of Botany, 89, 11-21.
- // Monsi M & Saeki T 1953 Ueber den Lichtfaktor in den Pflanzengesellschaften und
- // seine Bedeutung fuer die Stoffproduktion. Japanese Journal of Botany 14: 22-52
- // Olin S., G. Schurgers, M. Lindeskog, D. Wårlind, B. Smith, P. Bodin, J.
- // Holmér, and A. Arneth. 2015 Biogeosciences Discuss., 12, 1047-1111. The
- // impact of atmospheric CO2 and N management on yields and tissue C:N in
- // the main wheat regions of Western Europe
- // Parton, W. J., Hanson, P. J., Swanston, C., Torn, M., Trumbore, S. E., Riley, W.
- // & Kelly, R. 2010. ForCent model development and testing using the Enriched
- // Background Isotope Study experiment. Journal of Geophysical
- // Research-Biogeosciences, 115.
- // Prentice, IC, Sykes, MT & Cramer W 1993 A simulation model for the transient
- // effects of climate change on forest landscapes. Ecological Modelling 65: 51-70.
- // Reich, PB, Walters MB & Ellsworth DS 1992 Leaf Life-Span in Relation to Leaf,
- // Plant, and Stand Characteristics among Diverse Ecosystems.
- // Ecological Monographs 62: 365-392.
- // Sitch, S, Prentice IC, Smith, B & Other LPJ Consortium Members (2000) LPJ - a
- // coupled model of vegetation dynamics and the terrestrial carbon cycle. In:
- // Sitch, S. The Role of Vegetation Dynamics in the Control of Atmospheric CO2
- // Content, PhD Thesis, Lund University, Lund, Sweden.
- // Sykes, MT, Prentice IC & Cramer W 1996 A bioclimatic model for the potential
- // distributions of north European tree species under present and future climates.
- // Journal of Biogeography 23: 209-233.
- // Wang, E, Engel, T, 1998 Simulation of phenological development of wheat crops
- // Agricultural Systems 58:1-24
- // White, M A, Thornton, P E, Running, S. & Nemani, R 2000 Parameterization and
- // Sensitivity Analysis of the BIOME-BGC Terrestrial Ecosystem Model: Net Primary
- // Production Controls. Earth Interactions, 4, 1-55.
|