1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033 |
- #define TRACEBACK write (gol,'("in ",a," (",a,", line",i5,")")') rname, __FILE__, __LINE__; call goErr
- #define IF_NOTOK_RETURN(action) if (status/=0) then; TRACEBACK; action; return; end if
- #define IF_ERROR_RETURN(action) if (status> 0) then; TRACEBACK; action; return; end if
- !
- #include "tm5.inc"
- !
- !----------------------------------------------------------------------------
- ! TM5 !
- !----------------------------------------------------------------------------
- !BOP
- !
- ! !MODULE: PHOTOLYSIS
- !
- ! !DESCRIPTION: <add description>
- !\\
- !\\
- ! !INTERFACE:
- !
- MODULE PHOTOLYSIS
- !
- ! !USES:
- !
- use GO, only : gol, goPr, goErr
- use tm5_distgrid, only : dgrid, Get_DistGrid, gather
- use photolysis_data
- #ifdef with_optics
- use optics, only : wavelendep
- #endif
- IMPLICIT NONE
- PRIVATE
- !
- ! !PUBLIC MEMBER FUNCTIONS:
- !
- public :: photolysis_init, photolysis_done ! life cycle
- public :: ozone_info_online ! calculate the overhead ozone
- public :: aerosol_info ! aerosol optical depths
- public :: slingo ! cloud optical properties
- public :: update_csqy ! update ...
- public :: daysim ! calculate solar zenith angles
- public :: get_sza ! return solar zenith angle (function)
- public :: photo_flux ! calculates radiation fields
- public :: photorates_tropo ! calculates photolysis and heating rates
- #ifdef with_optics
- public :: aerosol_info_m7 ! aerosol optical depths
- #endif
- !
- ! !PUBLIC DATA MEMBERS:
- !
- public :: phot_dat ! type defined in photolysis_data
- !
- ! !PRIVATE DATA MEMBERS:
- !
- character(len=*), parameter :: mname = 'photolysis'
- real, parameter :: todu = 3.767e-17 ! from #/cm2 --> du
- real, parameter :: to_m = 3.767e-22 ! from #/cm2 --> m (for o2)
- real, parameter :: sp = 6.022e23*1.e-4*0.2095/(28.964*1e-3*9.81) ! sp from pa ---> #o2/cm2
- logical :: with_o3du
- real,dimension(122,34) :: xs_o3_look
- real,dimension( 65,34) :: xs_hno3_look,xs_pan_look,qy_o3_look
- real,dimension( 45,34) :: xs_h2o2_look
- real,dimension( 55,34) :: xs_n2o5_look
- real,dimension( 89,34) :: xs_no2_look,qy_no2_look
- real,dimension( 62,34) :: xs_no3_look
- real,dimension(105,34) :: xs_ch2o_look ! local
- integer :: l
- real :: wl,x, ww
- #ifdef with_optics
- type(wavelendep),dimension(:),allocatable :: wdep
- #endif
- !
- ! !REVISION HISTORY:
- ! 16 Jun 2011 - P. Le Sager - new version from JEW
- ! 21 Mar 2012 - P. Le Sager - adapted for lon-lat MPI domain decomposition
- ! 3 Oct 2012 - P. Le Sager - separate Init into true init and monthly update
- ! 4 Mar 2013 - P. Le Sager - changes for optics feedback from NB
- !
- ! !REMARKS:
- !
- !EOP
- !--------------------------------------------------------------------------
- CONTAINS
- ! Trap overflow
- function safe_div(n,d,altv) result(q)
- real, intent(in) :: n, d, altv
- real :: q
- if ( exponent(n)-exponent(d) >= maxexponent(n) .OR. d==0) then
- q=altv
- else
- q=n/d
- end if
- end function safe_div
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: INIT_PHOTOLYSIS
- !
- ! !DESCRIPTION: read reference tables for photolysis, allocate photolysis
- ! data. Called from sources_sinks/Trace0 at the run start and
- ! at beginning of every month.
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE PHOTOLYSIS_INIT( first, iunit, o3du )
- !
- ! !USES:
- !
- use dims, only : im, jm, lm, nregions, newsrun
- use ParTools, only : isRoot, par_broadcast
- use global_types, only : d23_data
- use global_data, only : rcfile
- use MeteoData, only : Set
- use MeteoData, only : sp_dat, temper_dat, lsmask_dat, phlb_dat
- use MeteoData, only : lwc_dat, iwc_dat, cc_dat, humid_dat, gph_dat
- use GO, only : TrcFile, Init, Done, ReadRc
- #ifdef with_optics
- use optics, only : Optics_Init
- #endif
- !
- ! !INPUT PARAMETERS:
- !
- logical, intent(in) :: first ! true init for a new run?
- integer, intent(in) :: iunit
- type(d23_data), dimension(nregions), optional, intent(in) :: o3du
- !
- ! !REVISION HISTORY:
- ! 21 Mar 2012 - P. Le Sager - adapted for lon-lat MPI domain decomposition
- !
- ! !REMARKS:
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- integer :: i,j,l,m,n,region,imr,jmr,lmr,i1, i2, j1, j2
- real :: lat
- integer :: status, wav
- type(TrcFile) :: rcF
- character(len=256) :: photodir
- character(len=*), parameter :: rname = mname//'/photolysis_init'
- ! --- begin -------------------------
- with_o3du = present(o3du)
- !--------------------------------------------------
- ! ** TRUE INIT : only once
- !--------------------------------------------------
- if (first) then
- REG: do region = 1, nregions
- call Set( sp_dat(region), status, used=.true. )
- call Set( temper_dat(region), status, used=.true. )
- call Set( humid_dat(region), status, used=.true. )
- call Set( gph_dat(region), status, used=.true. )
- call Set( phlb_dat(region), status, used=.true. )
- call Set( lwc_dat(region), status, used=.true. )
- call Set( iwc_dat(region), status, used=.true. )
- call Set( cc_dat(region), status, used=.true. )
- call Set( lsmask_dat(region), status, used=.true. )
- ! allocate memory photolysis and initialise:
- call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
- lmr=lm(region)
- if (with_o3du) allocate( phot_dat(region)%o3klim_top(j1:j2) )
- allocate(phot_dat(region)%albedo (i1:i2, j1:j2)) ; phot_dat(region)%albedo = 0.05
- allocate(phot_dat(region)%ags_av (i1:i2, j1:j2)) ; phot_dat(region)%ags_av = 0.0
- allocate(phot_dat(region)%sza_av (i1:i2, j1:j2)) ; phot_dat(region)%sza_av = 0.0
- allocate(phot_dat(region)%lwp_av (i1:i2, j1:j2,lmr)) ; phot_dat(region)%lwp_av = 0.0
- allocate(phot_dat(region)%cfr_av (i1:i2, j1:j2,lmr)) ; phot_dat(region)%cfr_av = 0.0
- allocate(phot_dat(region)%reff_av (i1:i2, j1:j2,lmr)) ; phot_dat(region)%reff_av = 0.0
- allocate(phot_dat(region)%aero_surface_clim(i1:i2, j1:j2)) ; phot_dat(region)%aero_surface_clim = 0
- phot_dat(region)%nalb_av = 0.
- phot_dat(region)%ncloud_av = 0.
- phot_dat(region)%naer_av = 0.
- allocate(phot_dat(region)%cloud_reff(i1:i2, j1:j2, lmr )) ; phot_dat(region)%cloud_reff = 0.0
- allocate(phot_dat(region)%pmcld (i1:i2, j1:j2, lmr )) ; phot_dat(region)%pmcld = 0.0
- allocate(phot_dat(region)%taus_cld (i1:i2, j1:j2, lmr )) ; phot_dat(region)%taus_cld = 0.0
- allocate(phot_dat(region)%taua_cld (i1:i2, j1:j2, lmr )) ; phot_dat(region)%taua_cld = 0.0
- allocate(phot_dat(region)%pmaer (i1:i2, j1:j2, lmr, nbands_trop, ngrid )) ; phot_dat(region)%pmaer = 0.0
- allocate(phot_dat(region)%taus_aer (i1:i2, j1:j2, lmr, nbands_trop, ngrid )) ; phot_dat(region)%taus_aer = 0.0
- allocate(phot_dat(region)%taua_aer (i1:i2, j1:j2, lmr, nbands_trop, ngrid )) ; phot_dat(region)%taua_aer = 0.0
- allocate(phot_dat(region)%pmcld_av (i1:i2, j1:j2, lmr )) ; phot_dat(region)%pmcld_av = 0.0
- allocate(phot_dat(region)%taus_cld_av (i1:i2, j1:j2, lmr )) ; phot_dat(region)%taus_cld_av = 0.0
- allocate(phot_dat(region)%taua_cld_av (i1:i2, j1:j2, lmr )) ; phot_dat(region)%taua_cld_av = 0.0
- allocate(phot_dat(region)%pmaer_av (i1:i2, j1:j2, lmr, nbands_trop,ngrid )) ; phot_dat(region)%pmaer_av = 0.0
- allocate(phot_dat(region)%taus_aer_av (i1:i2, j1:j2, lmr, nbands_trop,ngrid )) ; phot_dat(region)%taus_aer_av = 0.0
- allocate(phot_dat(region)%taua_aer_av (i1:i2, j1:j2, lmr, nbands_trop,ngrid )) ; phot_dat(region)%taua_aer_av = 0.0
- allocate(phot_dat(region)%jo3 (i1:i2, j1:j2, lmr )) ; phot_dat(region)%jo3 = 0.0
- allocate(phot_dat(region)%jno2 (i1:i2, j1:j2, lmr )) ; phot_dat(region)%jno2 = 0.0
- allocate(phot_dat(region)%jo3_av (i1:i2, j1:j2, lmr )) ; phot_dat(region)%jo3_av = 0.0
- allocate(phot_dat(region)%jno2_av(i1:i2, j1:j2, lmr )) ; phot_dat(region)%jno2_av = 0.0
- phot_dat(region)%nj_av = 0
- ! absorption cross-sections
- allocate(phot_dat(region)%v2 (i1:i2, j1:j2, lmr+1 )) ; phot_dat(region)%v2 = 0.0
- allocate(phot_dat(region)%v3 (i1:i2, j1:j2, lmr+1 )) ; phot_dat(region)%v3 = 0.0
- allocate(phot_dat(region)%v3_surf (i1:i2, j1:j2 )) ; phot_dat(region)%v3_surf = 0.0
- allocate(phot_dat(region)%qy_ch3cocho(i1:i2, j1:j2, lmr, 52)) ; phot_dat(region)%qy_ch3cocho = 0.0
- ! SAD fields
- phot_dat(region)%nsad_av = 0
- allocate(phot_dat(region)%sad_cld (i1:i2, j1:j2, lmr)) ; phot_dat(region)%sad_cld = 0.0
- allocate(phot_dat(region)%sad_ice (i1:i2, j1:j2, lmr)) ; phot_dat(region)%sad_ice = 0.0
- allocate(phot_dat(region)%sad_aer (i1:i2, j1:j2, lmr)) ; phot_dat(region)%sad_aer = 0.0
- allocate(phot_dat(region)%sad_cld_av (i1:i2, j1:j2, lmr)) ; phot_dat(region)%sad_cld_av = 0.0
- allocate(phot_dat(region)%sad_ice_av (i1:i2, j1:j2, lmr)) ; phot_dat(region)%sad_ice_av = 0.0
- allocate(phot_dat(region)%sad_aer_av (i1:i2, j1:j2, lmr)) ; phot_dat(region)%sad_aer_av = 0.0
-
- end do REG
- ! read settings from rcfile:
- call Init( rcF, rcfile, status )
- call ReadRc( rcF, 'input.photo', photodir, status )
- !--------------------------------------------------------------------
- ! wavelengths in the middle of the intervals
- !--------------------------------------------------------------------
- ! see: C. Bruehl, P.J. Crutzen, Scenarios of possible changes in ...
- ! Climate Dynamics (1988)2: 173-203
- ! ONLINE TUNING : first 13 wavelength bins are now ignored. Grid also shortened above 690nm.
- do l=1,13
- wave_full(l)=1./(56250.-500.*l)
- end do
- do l=14,45
- wave_full(l)=1./(49750.-(l-13)*500.)
- end do
- do l=46,68
- wave_full(l)=(266.+(l-13))*1.e-7
- end do
- do l=69,71
- wave_full(l)=(320.5+2.*(l-68))*1.e-7
- end do
- do l=72,176
- wave_full(l)=(325.+5.*(l-71))*1.e-7
- end do
- do l=2,maxwav-1
- dwave_full(l)=0.5*(wave_full(l+1)-wave_full(l-1))
- end do
- dwave_full(1) = dwave_full(2)
- dwave_full(maxwav) = dwave_full(maxwav-1)
- ! select a subset from the full spctral grid to remove the first band
- wave=wave_full(14:135)
- dwave=dwave_full(14:135)
- !---------------------------------------------------------------------
- ! Rayleigh scattering cross sections
- ! emp. formula of Nicolet plan. space sci.32, 1467f (1984)
- !---------------------------------------------------------------------
- do l=1,maxwav
- wl=wave(l)*1.e4
- x=0.389*wl+0.09426/wl-0.3228
- cs_ray(l)=4.02e-28/wl**(4.+x)
- end do
- !--------------------------------------------------------------
- ! Read and store temperature dependent cross-section values
- !--------------------------------------------------------------
- open(unit=7, file=trim(photodir)//'/tropo_look_up_reduce_2009.dat', status='old')
- read(7,*)
- read(7,*)
- read(7,*)
- do i=1,34
- read(7,'(176(1Pe10.3))') (xs_o3_look(wav,i),wav=1,122)
- enddo
- read(7,*)
- do i=1,34
- read(7,*) (xs_no2_look(wav,i),wav=1,89)
- enddo
- read(7,*)
- do i=1,34
- read(7,*) (xs_hno3_look(wav,i),wav=1,65)
- enddo
- read(7,*)
- do i=1,34
- read(7,*) (xs_h2o2_look(wav,i),wav=1,45)
- enddo
- read(7,*)
- do i=1,34
- read(7,*) (xs_n2o5_look(wav,i),wav=1,55)
- enddo
- read(7,*)
- do i=1,34
- read(7,*) (xs_ch2o_look(wav,i),wav=1,90)
- enddo
- read(7,*)
- do i=1,34
- read(7,*) (xs_pan_look(wav,i),wav=1,65)
- enddo
- read(7,*)
- do i=1,34
- read(7,*) (xs_no3_look(wav,i),wav=1,62)
- enddo
- read(7,*)
- do i=1,34
- read(7,*) (qy_o3_look(wav,i),wav=1,65)
- enddo
- read(7,*)
- do i=1,34
- read(7,*)(qy_no2_look(wav,i),wav=1,89)
- enddo
- close(7)
- !--------------------------------------------------------------
- ! Read and store temperature dependent cross-section values
- !------------------ extraterrestrial flux from input file ------------------
- ! open(unit=7, file=trim(photodir)//'/OMI.data.reduce',status='old')
- ! read(7,*)
- ! read(7,'(1p7e10.2)') flux
- ! close(7)
-
- ! Cannot be read for some unknown reason on cca@ecmwf with cray compiler.
- ! Just set it here:
- flux=(/ 2.351E+12, 2.414E+12, 2.360E+12, 3.004E+12, 8.861E+12, 4.475E+12, 9.005E+12, &
- 1.607E+13, 1.556E+13, 1.221E+13, 2.061E+13, 2.070E+13, 1.047E+13, 7.497E+12, &
- 1.729E+13, 9.523E+12, 2.018E+13, 2.265E+13, 1.275E+13, 1.750E+13, 2.590E+13, &
- 8.777E+13, 2.193E+13, 5.449E+13, 1.074E+14, 6.856E+13, 7.875E+13, 2.275E+13, &
- 1.488E+14, 2.166E+14, 2.518E+14, 3.504E+14, 1.493E+14, 5.366E+13, 4.045E+13, &
- 2.054E+13, 6.274E+13, 9.589E+13, 1.326E+14, 1.307E+13, 1.332E+14, 1.729E+14, &
- 1.349E+14, 5.685E+13, 1.342E+14, 1.391E+14, 8.107E+13, 1.459E+14, 1.965E+14, &
- 5.681E+13, 1.349E+14, 6.819E+13, 2.137E+14, 1.564E+14, 1.334E+14, 3.559E+14, &
- 2.593E+14, 4.187E+14, 7.893E+14, 1.610E+14, 1.021E+15, 9.119E+14, 1.056E+15, &
- 8.424E+14, 6.622E+14, 9.387E+14, 1.463E+15, 3.382E+14, 1.076E+15, 9.586E+14, &
- 1.783E+15, 8.718E+14, 1.864E+15, 1.661E+15, 1.938E+15, 2.101E+15, 2.058E+15, &
- 1.738E+15, 9.227E+14, 2.404E+15, 2.176E+15, 2.625E+15, 2.167E+15, 1.741E+15, &
- 2.424E+15, 1.531E+15, 1.819E+15, 2.625E+15, 2.293E+15, 2.570E+15, 2.619E+15, &
- 2.663E+15, 2.705E+15, 2.542E+15, 1.331E+15, 2.633E+15, 2.575E+15, 2.744E+15, &
- 1.958E+15, 2.642E+15, 2.691E+15, 2.646E+15, 2.720E+15, 2.703E+15, 1.188E+15, &
- 2.720E+15, 2.271E+15, 2.405E+15, 2.723E+15, 2.690E+15, 2.550E+15, 2.670E+15, &
- 2.665E+15, 2.702E+15, 2.653E+15, 2.658E+15, 2.691E+15, 2.593E+15, 2.646E+15, &
- 2.653E+15, 2.636E+15, 2.648E+15 /)
-
- #ifdef with_optics
-
- ! define wavelengths for optics calculations
- nwdep = nbands_trop + count(lmid.ne.lmid_gridA)
- wav_grid = 0
- wav_gridA = 0
- allocate(photo_wavelengths(nwdep))
- l=1
- do i=1,nbands_trop
- if (lmid(i)==lmid_gridA(i)) then
- photo_wavelengths(l) = wave(lmid(i))*1.e4 ! cm to um
- wav_grid(i) = l
- wav_gridA(i) = l
- l=l+1
- else
- photo_wavelengths(l) = wave(lmid(i))*1.e4 ! cm to um
- photo_wavelengths(l+1) = wave(lmid_gridA(i))*1.e4 ! cm to um
- wav_grid(i) = l
- wav_gridA(i) = l+1
- l=l+2
- endif
- enddo
- allocate(wdep(nwdep))
- wdep(:)%wl = photo_wavelengths
- wdep(:)%split = .false.
- wdep(:)%insitu = .false.
-
- call Done( rcF, status )
- IF_NOTOK_RETURN(status=1)
- CALL OPTICS_INIT( nwdep, wdep, status )
- IF_NOTOK_RETURN(status=1)
-
- deallocate(photo_wavelengths)
- #else
- !**************************************************************************
- ! aerosol data from: "Models for Aerosols of the Lower Atmosphere
- ! and the Effects of Humidity Variations on their Optical Properties
- ! E. P. Shettle and R. W. Fenn (1979), Environmental Research Paper
- ! No. 676
- !**************************************************************************
- open(unit=7, file=trim(photodir)//'/aerosol_reduce.dat',status='old')
- do l = 1,4
- read(7,*)
- do i = 1,8
- read(7,*)
- read(7,20)(ext(wav,i,l),wav=1,maxwav)
- read(7,20)(abs_eff(wav,i,l),wav=1,maxwav)
- read(7,20)(g(wav,i,l),wav=1,maxwav)
- do wav=1,maxwav
- sca(wav,i,l) = ext(wav,i,l) - abs_eff(wav,i,l)
- enddo
- enddo
- enddo
- close(7)
- 20 format(6(1X,F7.5))
- do l=1,maxwav
- do i=1,8
- do j=1,4
- sca(l,i,j) = sca(l,i,j)/pn_ref(j)*1.E-5
- abs_eff(l,i,j) = abs_eff(l,i,j)/pn_ref(j)*1.E-5
- end do
- end do
- end do
- ! close rc file
- call Done( rcF, status )
- #endif
-
- ELSE ! NEWSRUN
- !--------------------------------------------------
- ! ** MONTHLY UPDATE
- !--------------------------------------------------
- if (with_o3du) then
- do region = 1, nregions
- call Get_DistGrid( dgrid(region), J_STRT=j1, J_STOP=j2 )
- phot_dat(region)%o3klim_top(:) = o3du(region)%d23(j1:j2,lm(region))
- end do
- end if
- ENDIF
- END SUBROUTINE PHOTOLYSIS_INIT
- !EOC
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: DAYSIM
- !
- ! !DESCRIPTION: Get all solar zenith angles (THA) for a given Julian day
- ! (DAYNR) at 1/6, 3/6(=center), and 5/6 of each grid box.
- ! THA is three times oversampled.
- ! The longitudinal variation is equal to the simulation of
- ! one day, and covers the [-180,180] range for all regions.
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE DAYSIM(region, daynr, is, i1,i2,j1, j2, tha)
- !
- ! !USES:
- !
- use dims, only : im, jm, xbeg, xend
- use binas, only : pi
- use meteodata, only : lli
- !
- ! !INPUT PARAMETERS:
- !
- integer, intent(in) :: daynr, region, is, j1, j2,i1,i2
- !
- ! !OUTPUT PARAMETERS:
- !
- real, intent(out) :: tha( im(region)*3, j1:j2)
- !
- ! !REVISION HISTORY:
- ! 26 Apr 2012 - P. Le Sager - adapted for lon-lat MPI domain decomposition
- !
- ! !REMARKS:
- ! (1) The regions are artificially expanded to cover all longitudes, in
- ! order to keep the correspondance b/w time and longitude.
- ! (2) Need to be called once a day only. Hence separated from GET_SZA,
- ! and the need to have 'im_alt' and 'shift' defined module wide.
- ! (3) Input 'is' is not i1=I_START from the distributed grid, but: (i1-1)*3+1
- ! It is not used yet. To delete?
- ! (4) Considering the cshift functions used on THA in GET_SZA, it is
- ! assumed that THA covers the entire longitude range.
- !EOP
- !------------------------------------------------------------------------
- !BOC
- real, dimension(j1:j2) :: lat
- real :: houra, rdecl, sinhh, eqr, ut
- real :: piby, lon, tz, sintz, costz
- real :: sin2tz, cos2tz, sin3tz, cos3tz
- integer :: i, j, k
- !
- !call Get_DistGrid( dgrid(region), I_STOP=i2, J_STOP=j2 )
-
- piby = pi/180.
- !
- ! latitude range in radian
- lat = lli(region)%lat
- !
- tz = 2.*pi*daynr/365.
- !
- ! Solar declination approximation
- !(p.97, Brasseur et al, Atmospheric Chemistry and Global Change, 1999)
- !
- rdecl = -0.4*cos(2.*pi*real(daynr+10)/365.)
- !
- sintz = sin(tz)
- costz = cos(tz)
- sin2tz = 2.*sintz*costz
- cos2tz = costz*costz-sintz*sintz
- eqr = 0.000075 + 0.001868*costz - 0.032077*sintz &
- - 0.014615*cos2tz - 0.040849*sin2tz
- !
- ! the sza variation over longitude [-180,180] at ut=12 equals
- ! a with variation of ut over [0,24] at longitude 0:
- ! houra = 15.*(ut-12. + eqr*24./(2.*pi) + lon*24./360)*piby
- !
-
- ! THA (sampled at 1/6, 3/6, and 5/6 of each box). As follow for 6 degree resolution:
- !
- ! -180---+---+---177---+---+---174---+---+---171---+---+---168 .......etc...
- ! | | |
- ! | box #1 | box #2 |
- ! | | |
- ! +---------------------------+---------------------------+ .......etc.....
- ! 0 1 2 3 4 5 0 1 2 3 4 5
- ! * * * * * * <---- samples (lon,THA)
- do j=j1,j2
- do i=1,im(region)*3
- lon = -180. + (real(i)-0.5)*360./real(im(region)*3)
- !lon = xbeg(region) + (real(i)-0.5)*(xend(region)-xbeg(region))/real(im(region)*3)
- houra = -pi + lon*piby + eqr
- sinhh = sin(rdecl)*sin(lat(j)) &
- + cos(rdecl)*cos(lat(j))*cos(houra)
- tha(i,j) = acos(sinhh)/piby
- enddo
- enddo
-
- END SUBROUTINE DAYSIM
- !EOC
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: GET_SZA
- !
- ! !DESCRIPTION:
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE GET_SZA(region, i1, j1, i2, j2, tstart, deltat, tha, sza)
- !
- ! !USES:
- !
- use dims, only : im, jm
- !
- ! !INPUT PARAMETERS:
- !
- integer, intent(in) :: region, i1, j1, i2, j2
- real, intent(in) :: tstart ! start time of chemistry timestep
- real, intent(in) :: deltat ! chemistry timestep in hours
- real, intent(in) :: tha(im(region)*3,j1:j2) ! three times oversampled zenith angles
- !
- ! !OUTPUT PARAMETERS:
- !
- real, intent(out) :: sza(i1:i2,j1:j2) ! effective solar zenith angles for this timestep
- !
- ! !REVISION HISTORY:
- ! 26 Apr 2012 - P. Le Sager - adapted for lon-lat MPI domain decomposition
- !
- ! !REMARKS:
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- real, dimension(im(region)*3,j1:j2) :: mu3
- real :: dt
- integer :: it, i, ii
- !
- mu3 = 0.0
- !
- ! split chemistry timestep in intervals and calculate mu at 1/6, 3/6
- ! and 5/6 of timestep chemistry. Interpolate in time using the
- ! longitudinal dependence of tha and take the average.
- !
- do ii=1,5,2
- dt = ( tstart + ii*deltat/6. ) * (real(im(region)*3)/24.)
- it = int(dt)
- dt = dt-it
- mu3 = mu3 + (1-dt)*cshift(tha,it,1)+dt*cshift(tha,it+1,1)
- enddo
- !
- ! average over three angles at three times resolution
- !
- do i=i1,i2
- sza(i,:) = (mu3(i*3-2,:) + mu3(i*3-1,:) + mu3(i*3,:))/9.0
- enddo
- END SUBROUTINE GET_SZA
- !EOC
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: PHOTO_FLUX
- !
- ! !DESCRIPTION:
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE PHOTO_FLUX( region, is, js, sza, rj_new)
- !**********************************************************************
- ! *
- ! contact: *
- ! *
- ! Jason Williams *
- ! Koninklijk Nederlands Meteorologisch instituut (KNMI) *
- ! Postbus 201 *
- ! 3730 AE De Bilt *
- ! tel +31 (0)30 2206748 *
- ! e-mail : williams@knmi.nl *
- ! *
- !**********************************************************************
- ! purpose:
- !
- ! The calculation of the radiation fields using input from TM5 and ECMWF meteo.
- !
- ! method:
- !
- ! Optical properties (optical thickness,cross sections, quantum yields)
- ! are calculated for lm(region) layers. Radiation fluxes are derived for 0:lm(region)
- ! levels, including the surface and top of atmosphere. Thus, level l overlays layer l.
- ! Photolysis rates in a layer are evaluated by taking the average of the
- ! photolysis rates evaluated at the upper and lower boundaries of the layer.
- !
- ! First, spectral calculations are performed for an atmosphere with absorption
- ! only, including gaseous absorption by O2 and O3 and aerosol absorption.
- ! Second, a correction is applied for scattering and surface reflection, per
- ! scattering band and using radiative transfer calculations at representative
- ! wavelengths
- !
- ! This photolysis module is based on:
- !
- ! Landgraf and Crutzen, 1998, J. Atmos. Sci, 55, 863-878.
- ! Williams et al., 2006, Atmos.Chem.Phys., 6, 4137-4161.
- !
- !------------------------------------------------------------------
- !
- ! Albedo field
- ! ------------
- !
- ! In older TM photolysis code, an adhoc uv-vis albedo was computed
- ! from land cover fields:
- !
- ! module dry_deposition
- ! dd_surface_fields
- ! if(root_k)then
- ! dd_calc_inisurf
- ! compute ags on glb1x1 from land cover, on root_k only
- ! dd_coarsen_vd
- ! coarsen ags to vd_temp, copy into phot_dat(region)%albedo
- ! endif
- ! broadcast phot_dat(region)%albedo to all other processors
- !
- ! In the first stratospheric codes, the same adhoc albedo computed in
- ! drydepos was written over the albedo meteo field, and then this one was used.
- ! To avoid this obscure destruction of ecmwf data, we use the phot_dat version here.
- ! In future, this should be replaced by ECMWF field:
- ! UV visible albedo for direct radiation ALUVP (0 - 1) 15 128
- !
- !------------------------------------------------------------------
- ! subroutine to calculate direct flux and actinic flux
- !*******************************************************************
- !
- ! !USES:
- !
- use dims, only : lm, idate, ndyn, ndyn_max
- use MeteoData, only : temper_dat, gph_dat, cc_dat
- !
- ! !INPUT PARAMETERS:
- !
- integer, intent(in) :: region
- integer, intent(in) :: is, js
- real, intent(in) :: sza(is:,js:)
- !
- ! !OUTPUT PARAMETERS:
- !
- ! photolysis rates for this time-step
- real, dimension(is:,js:,:,:), intent(out) :: rj_new ! (i1:i2,j1:j2,lm(region),nj)
- !
- ! !REVISION HISTORY:
- ! 26 Apr 2012 - P. Le Sager - adapted for lon-lat MPI domain decomposition
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- integer :: i, j, l, k, n, table_pos
- real :: zangle, alb, esrm2
- real, dimension(lm(region)+1) :: levels
- logical :: clear, cloudy, debug_flag
- ! temperature index array for the lookup table
- integer, parameter :: n_ind =34 ! number of increments in the look-up table
- integer, parameter :: jindex=9
- integer, parameter :: latindex=21
- real, parameter :: incr = 5. ! 5deg C intervals in look-up table (optimised value)
- real, dimension(n_ind) :: temp_ind
- real, dimension(:), allocatable :: v2_col, v3_col, dv2_col, dv3_col, t_lay, ly_a, column_cloud
- real, dimension(:,:), allocatable :: cst_o3_col
- real, dimension(:,:), allocatable :: cst_no2_col, qy_no2_col
- real, dimension(:,:), allocatable :: cst_hno3_col
- real, dimension(:,:), allocatable :: cst_h2o2_col
- real, dimension(:,:), allocatable :: cst_n2o5_col
- real, dimension(:,:), allocatable :: cst_ch2o_col
- real, dimension(:,:), allocatable :: cst_pan_col
- real, dimension(:,:), allocatable :: cst_no3_col
- real, dimension(:,:), allocatable :: qy_o1d_col
- real, dimension(:,:), allocatable :: qy_ch3cocho_col
- real, dimension(:,:), allocatable :: fdir, fact
- real, dimension(:), allocatable :: taua_cld_col, taus_cld_col
- real, dimension(:,:,:),allocatable :: taus_aer_col, taua_aer_col
- real, dimension(:,:), allocatable :: ts_pi_clr_col, ta_pi_clr_col, g_pi_clr_col, g_pi_cld_col
- real, dimension(:), allocatable :: ts_pi_cld, ta_pi_cld
- real, dimension(:,:,:),allocatable :: pm_aer_col
- real, dimension(:), allocatable :: pm_cld_col
- real, dimension(:,:), allocatable :: ds
- real, dimension(:,:), allocatable :: rj_column
- real, dimension(:,:,:),pointer :: temperature
- ! additional diagnostic array to compare old/new jvalue input
- real, dimension(:), allocatable :: vo3s_col
- integer :: i1, j1, i2, j2
- call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
- allocate( v2_col (lm(region)+1) )
- allocate( v3_col (lm(region)+1) )
- allocate( dv2_col (lm(region) ) )
- allocate( dv3_col (lm(region) ) )
- allocate( t_lay (lm(region) ) )
- allocate( cst_o3_col (lm(region),maxwav) )
- allocate( cst_no2_col (lm(region),89) )
- allocate( qy_no2_col (lm(region),89) )
- allocate( cst_hno3_col (lm(region),65) )
- allocate( cst_h2o2_col (lm(region),45) )
- allocate( cst_n2o5_col (lm(region),55) )
- allocate( cst_ch2o_col (lm(region),105) )
- allocate( cst_pan_col (lm(region),65) )
- allocate( cst_no3_col (lm(region),62) )
- allocate( qy_o1d_col (lm(region),65) )
- allocate( qy_ch3cocho_col(lm(region),52) )
- allocate( fdir (lm(region),maxw) ) ; fdir(:,:) = 0.
- allocate( taus_aer_col (lm(region),nbands_trop,ngrid))
- allocate( taua_aer_col (lm(region),nbands_trop,ngrid))
- allocate( taus_cld_col (lm(region)))
- allocate( taua_cld_col (lm(region)))
- allocate( ts_pi_clr_col (lm(region),nbands_trop))
- allocate( ta_pi_clr_col (lm(region),nbands_trop))
- allocate( g_pi_clr_col (lm(region),nbands_trop))
- allocate( g_pi_cld_col (lm(region),nbands_trop))
- allocate( pm_aer_col (lm(region),nbands_trop,ngrid))
- allocate( pm_cld_col (lm(region)))
- allocate( fact (lm(region),nbands_trop)) ; fact(:,:) = 0.
- allocate( column_cloud (lm(region)))
- allocate( ds (lm(region)+1,lm(region)))
- allocate( rj_column (lm(region),nj)) ; rj_column = 0.
- allocate(vo3s_col(lm(region)+1))
- temperature => temper_dat(region)%data
- clear = .false.
- cloudy = .true.
- debug_flag = .false.
- ! define temperature index array from the lookup table
- do i = 1, 34
- temp_ind(i) = 182.5 + (i-1) * 5.0
- enddo
- do j = j1, j2
- do i = i1, i2
- zangle = sza(i,j)
- t_lay = temperature(i,j,:)
- rj_new(i,j,:,:) = 0.
- if (zangle <= sza_limit ) then
- ! initialise
- fdir = 0. ; dv2_col = 0. ; dv3_col = 0. ; fact = 0.
- v2_col(:) = phot_dat(region)%v2(i,j,:)
- v3_col(:) = phot_dat(region)%v3(i,j,:)
- qy_ch3cocho_col(:,:) = phot_dat(region)%qy_ch3cocho(i,j,:,:)
- column_cloud(:) = cc_dat(region)%data(i,j,:)
- levels=gph_dat(region)%data(i,j,:)
- ! set optical depths parameters
- taus_cld_col = phot_dat(region)%taus_cld(i,j,:)
- taua_cld_col = phot_dat(region)%taua_cld(i,j,:)
- taus_aer_col = phot_dat(region)%taus_aer(i,j,:,:,:)
- taua_aer_col = phot_dat(region)%taua_aer(i,j,:,:,:)
- pm_cld_col = phot_dat(region)%pmcld(i,j,:)
- pm_aer_col = phot_dat(region)%pmaer(i,j,:,:,:)
- !
- ! assign the cross-sections here to avoid the exporting of large arrays
- !
- do k=1,lm(region)
- table_pos=int((t_lay(k) - (temp_ind(1)-0.5*5)) / 5) + 1
- table_pos=min(max(1,table_pos),34) ! bug fix for temperatures below 175.5
- cst_o3_col(k,:) = xs_o3_look(:,table_pos)
- cst_no2_col(k,:) = xs_no2_look(:,table_pos)
- cst_hno3_col(k,:) = xs_hno3_look(:,table_pos)
- cst_h2o2_col(k,:) = xs_h2o2_look(:,table_pos)
- cst_ch2o_col(k,:) = xs_ch2o_look(:,table_pos)
- cst_n2o5_col(k,:) = xs_n2o5_look(:,table_pos)
- cst_pan_col(k,:) = xs_pan_look(:,table_pos)
- cst_no3_col(k,:) = xs_no3_look(:,table_pos)
- qy_o1d_col(k,:) = qy_o3_look(:,table_pos)
- qy_no2_col(k,:) = qy_no2_look(:,table_pos)
- enddo
- ! slant column, lyman-alpha and direct flux ; all are zenith angle dependent
- call directflux(region,zangle,v2_col,v3_col,cst_o3_col,t_lay,fdir,dv2_col,dv3_col,taua_cld_col, &
- taua_aer_col,levels,ds,vo3s_col,debug_flag)
- ! now do radiative transfer calculation, calculate actinic flux
- ! set albedo
- alb = phot_dat(region)%albedo(i,j)
- ! Now call the PIFM RT solver for the online calculation ; both clear and cloudy conditions can be used
- if (clear) call pifm(region,zangle,alb,cst_o3_col,dv2_col,dv3_col, &
- taua_aer_col,taus_aer_col,pm_aer_col,fact)
- if (cloudy) call pifm_ran( region,zangle,alb,cst_o3_col,dv2_col,dv3_col, &
- taua_cld_col,taus_cld_col,pm_cld_col,taua_aer_col,taus_aer_col,pm_aer_col,fact,column_cloud)
- rj_column=0.
- call photorates_tropo(region,zangle,cst_o3_col,cst_no2_col,cst_hno3_col,cst_h2o2_col,cst_ch2o_col,&
- cst_n2o5_col,cst_pan_col,cst_no3_col,qy_no2_col,qy_o1d_col,qy_ch3cocho_col,fact,fdir,&
- rj_column,debug_flag)
- rj_new(i,j,:,:) = rj_column
- elseif(zangle > sza_limit) then
- vo3s_col = 0.
- do k=1,lm(region)
- table_pos=int((t_lay(k) - (temp_ind(1)-0.5*5)) / 5) + 1
- table_pos=min(max(1,table_pos),34) ! max(...) == temperatures below 175.5 used like 180.5
- cst_o3_col(k,:) = xs_o3_look(:,table_pos)
- enddo
- debug_flag=.false.
- endif ! sza_limit
- enddo ! i
- enddo ! j
- ! Correction photolysis for distance sun-earth
- esrm2 = sundis(idate(2),idate(3))
- rj_new = rj_new *esrm2
- ! Store
- phot_dat(region)%jo3 (:,:,:) = rj_new(:,:,:,jo3d)
- phot_dat(region)%jno2 (:,:,:) = rj_new(:,:,:,jno2)
-
- ! Averages
- phot_dat(region)%nj_av = phot_dat(region)%nj_av + float(ndyn)/float(ndyn_max)
- phot_dat(region)%nalb_av = phot_dat(region)%nalb_av + float(ndyn)/float(ndyn_max)
- phot_dat(region)%jo3_av = phot_dat(region)%jo3_av + float(ndyn)/float(ndyn_max) * rj_new(:,:,:,jo3d)
- phot_dat(region)%jno2_av = phot_dat(region)%jno2_av + float(ndyn)/float(ndyn_max) * rj_new(:,:,:,jno2)
- phot_dat(region)%ags_av = phot_dat(region)%ags_av + float(ndyn)/float(ndyn_max) * phot_dat(region)%albedo
- phot_dat(region)%sza_av = phot_dat(region)%sza_av + float(ndyn)/float(ndyn_max) * sza
- ! Done
- nullify(temperature)
- deallocate(v2_col)
- deallocate(v3_col)
- deallocate(dv2_col)
- deallocate(dv3_col)
- deallocate(cst_o3_col)
- deallocate(cst_no2_col)
- deallocate(qy_no2_col)
- deallocate(cst_hno3_col)
- deallocate(cst_h2o2_col)
- deallocate(cst_n2o5_col)
- deallocate(cst_ch2o_col)
- deallocate(cst_pan_col)
- deallocate(cst_no3_col)
- deallocate(qy_o1d_col)
- deallocate(qy_ch3cocho_col)
- deallocate(fdir)
- deallocate(t_lay)
- deallocate(taus_aer_col)
- deallocate(taua_aer_col)
- deallocate(pm_aer_col)
- deallocate(taus_cld_col)
- deallocate(taua_cld_col)
- deallocate(pm_cld_col)
- deallocate(ts_pi_clr_col)
- deallocate(ta_pi_clr_col)
- deallocate(g_pi_clr_col)
- deallocate(g_pi_cld_col)
- deallocate(fact)
- deallocate(column_cloud)
- deallocate(ds)
- deallocate(rj_column)
- deallocate(vo3s_col)
- END SUBROUTINE PHOTO_FLUX
- !EOC
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: DIRECTFLUX
- !
- ! !DESCRIPTION:
- ! Schumann-Runge parameterization
- ! Koppers GAA, Murtagh DP, Ann. Geophysicae 14, 68-79
- !\\
- !\\
- ! !INTERFACE:
- !
- subroutine directflux(region,zangle,v2_col,v3_col,cst_o3_col,t_lay,&
- fdir,dv2_col,dv3_col,taua_cld_col,taua_aer_col,&
- levels,ds,vo3s_col,debug_flag)
- !
- ! !USES:
- !
- use dims, only : lm
- use binas, only : pi, avog, grav, xmair, ae
- !
- ! !INPUT PARAMETERS:
- !
- integer, intent(in) :: region
- real,intent(in) :: zangle
- ! oxygen and ozone column
- real,dimension(lm(region)+1),intent(in) :: v2_col,v3_col
- real,dimension(lm(region)),intent(in) :: taua_cld_col
- real,dimension(lm(region),nbands_trop,ngrid),intent(in) :: taua_aer_col
- !
- ! !OUTPUT PARAMETERS:
- !
- real,dimension(lm(region)+1),intent(out) :: vo3s_col
- ! temperature
- real,dimension(lm(region)),intent(in) :: t_lay
- ! temperature dependent cs of ozone
- real,dimension(lm(region),maxwav),intent(in) :: cst_o3_col
- ! flux through pure absorbing atmosphere
- real,dimension(lm(region),maxw),intent(out) :: fdir
- real,dimension(lm(region)),intent(out) :: dv2_col,dv3_col
- ! levels for ds calculation
- real,dimension(lm(region)+1) :: levels
- real,dimension(lm(region)+1,lm(region)),intent(out) :: ds
- logical,intent(in) :: debug_flag
- !
- ! !REVISION HISTORY:
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- real,dimension(:),allocatable :: t_lev
- real,dimension(:),allocatable :: v2s,v3s,dv2s, dv3s
- integer :: l, li, i, j, k, k1, k2, id, n, h, bandno
- real :: dl_o2,u0
- real,dimension(20) :: coeff_a, coeff_b
- real :: a,b,c, gamma
- real,dimension(maxw) :: fdir_top
- real :: fdir_bot
- real :: ta_o2, ta_o3, tau
- real :: sp, const, press, alp, alv2, sln, ck, sf
- !-----------------------------------------------------------------
- ! declarations for the calculation of DS
- real,dimension(0:lm(region)) :: ze
- real,dimension(0:lm(region),lm(region)) :: ds_tmp
- real :: rpsinz,rj,rjp1,diffj,height1,height2
- real :: zenrad,sm,re,dsj,dummy
- allocate(t_lev(lm(region)+1)) ; t_lev=0.
- allocate(dv2s(lm(region))) ; dv2s = 0.
- allocate(dv3s(lm(region))) ; dv3s = 0.
- allocate(v2s(1:lm(region)+1)) ; v2s = 0.
- allocate(v3s(1:lm(region)+1)) ; v3s = 0.
- ! initialise all output
- fdir = 0. ; dv2_col = 0 ; dv3_col = 0. ; ds = 0. ; ds_tmp = 0.
- ! define temperature on grid levels. Note temperature on layers now has reversed vertical grid
- do k = 2,lm(region)
- t_lev(k) = (t_lay(k) + t_lay(k-1) ) * 0.5
- enddo
- ! boundaries
- t_lev(1) = t_lay(1)
- t_lev(lm(region)+1) = t_lay(lm(region))
- a = 0.50572 ; b = 6.07995 ; c = 1.63640
- dv2_col(lm(region)) = v2_col(lm(region))
- dv3_col(lm(region)) = v3_col(lm(region))
- do l=lm(region)-1,1,-1
- dv2_col(l) = v2_col(l)-v2_col(l+1)
- dv3_col(l) = v3_col(l)-v3_col(l+1)
- end do
- !-----correction of the air mass factor---------------------------------
- ! F. Kasten and T. Young, Revised optical air mass tabels and
- ! approximation formula (1989) Aplied Optics Vol 28, No. 22 P. 4735
- ! and J. Lenoble, atmospheric radiative transfer (1993), P. 236
- ! define air mass factor in mu
- gamma = 90. - zangle
- u0 = sin(gamma*pi/180.) + a *(gamma+b)**(-c)
- u0 = min(1.,u0)
- if(zangle <= 75.) then
- ds = 1/u0
- elseif(zangle >75. .and. zangle <=sza_limit) then
- levels(1:lm(region)+1)=levels(lm(region)+1:1:-1)
- re = (ae+levels(lm(region)+1))*1.e-3
- do k=lm(region)+1,1,-1
- ze(k-1) = (levels(k)/1.e3)-(levels(lm(region)+1)/1.e3)
- enddo
- zenrad=acos(u0)
- do k=0,lm(region)
- rpsinz = (re+ze(k))*sin(zenrad)
- id = k
- do n=1,id
- sm = 1.0
- rj = re + ze(n-1)
- rjp1 = re + ze(n)
- diffj = ze(n-1) - ze(n)
- height1 = rj**2 - rpsinz**2
- height2 = rjp1**2 - rpsinz**2
- height1=max(0.0,height1)
- height2=max(0.0,height2)
- if(id>k .and. n==id) then
- dsj=sqrt(height1)
- else
- dsj=sqrt(height1)-sm*sqrt(height2)
- endif
- ds_tmp(k,n) = dsj/diffj
- enddo ! n
- enddo !k
- ! invert matrix to be compatible with lm(region)+1 being tOA
- ds(1:lm(region)+1,1:lm(region))=ds_tmp(lm(region):0:-1,lm(region):1:-1)
- ENDIF ! sza_rad
- ! slant column : calculate in different way depending on zangle
- if(zangle <=75.) then
- v2s(lm(region)+1)=ds(lm(region),lm(region))*v2_col(lm(region)+1)
- v3s(lm(region)+1)=ds(lm(region),lm(region))*v3_col(lm(region)+1)
- do k1=lm(region)+1,1,-1
- v2s(k1) = v2s(lm(region)+1)
- v3s(k1) = v3s(lm(region)+1)
- do k2=lm(region),k1,-1
- v2s(k1) = v2s(k1) + ds(k1,k2)*dv2_col(k2)
- v3s(k1) = v3s(k1) + ds(k1,k2)*dv3_col(k2)
- end do
- end do
- elseif(zangle>75. .and. zangle<=85.) then
- v2s(lm(region)+1) = ds(lm(region),lm(region))*v2_col(lm(region)+1)
- v3s(lm(region)+1) = ds(lm(region),lm(region))*v3_col(lm(region)+1)
- do k1=lm(region)+1,1,-1
- v2s(k1) = v2s(lm(region)+1)
- v3s(k1) = v3s(lm(region)+1)
- do k2=lm(region),1,-1
- v2s(k1) = v2s(k1) + ds(k1,k2)*dv2_col(k2)
- v3s(k1) = v3s(k1) + ds(k1,k2)*dv3_col(k2)
- enddo
- enddo
- endif
- do k1=lm(region)+1,1,-1
- vo3s_col(k1)=v3s(k1)
- enddo
- ! differential slant column
- dv2s(lm(region)) = v2s(lm(region))-v2s(lm(region)+1)
- dv3s(lm(region)) = v3s(lm(region))-v3s(lm(region)+1)
- do k = lm(region)-1,1,-1
- dv2s(k) = v2s(k)-v2s(k+1)
- dv3s(k) = v3s(k)-v3s(k+1)
- if(dv2s(k)<0.) dv2s(k)=-1.0*dv2s(k)
- if(dv3s(k)<0.) dv3s(k)=-1.0*dv3s(k)
- enddo
- ! intialise direct flux
- fdir_top(1:maxw) = flux(1:maxw)
- ! direct flux = actinic flux for a purely abs. atmosphere
- ! here, layer averaged quantity
- bandno=1
- if(zangle <=85.) then
- do l = 1,maxw
- do k = lm(region),1,-1
- if(l<18) then
- ta_o2 = cross_o2(l)*dv2s(k)
- else
- ta_o2 = 0.
- endif
- ta_o3 = cst_o3_col(k,l)*dv3s(k)
- fdir_bot = fdir_top(l) * exp(-ta_o2-ta_o3-taua_cld_col(k)-taua_aer_col(k,bandno,1))
- fdir(k,l) = (fdir_top(l) + fdir_bot)/2.
- fdir_top(l) = fdir_bot
- if(l>lfin(bandno)) bandno=bandno+1
- enddo
- enddo
- endif
- deallocate(t_lev)
- deallocate(v2s)
- deallocate(v3s)
- deallocate(dv2s)
- deallocate(dv3s)
- END SUBROUTINE DIRECTFLUX
- !EOC
-
- #ifdef with_optics
- ! only define when coupling with photolysis is turned on
-
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: AEROSOL_INFO_M7
- !
- ! !DESCRIPTION: assignment of aerosol optical depths calculated in M7
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE AEROSOL_INFO_M7(region, status)
- !
- ! !USES:
- !
- USE TM5_DISTGRID, ONLY : dgrid, Get_DistGrid
- USE DIMS, ONLY : isr,ier,jsr,jer, ndyn_max, ndyn
- USE METEODATA, ONLY : gph_dat
- USE DIMS, ONLY : im, jm, lm
- USE OPTICS, ONLY : optics_aop_get
- !
- ! !INPUT PARAMETERS:
- !
- integer, intent(in) :: region
- !
- ! !OUTPUT PARAMETERS:
- !
- integer, intent(out) :: status
- !
- ! !REVISION HISTORY:
- ! Aug 2012 - NB
- ! 5 Mar 2013 - Ph. Le Sager - TM5-MP version
- !
- ! !REMARKS:
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- character(len=*), parameter :: rname = mname//'/aerosol_info_m7'
- integer :: i,j,l,lvec, nsend, igrid, i1, i2, j1, j2, lmr
- real, dimension(:,:,:), pointer :: gph
- real, dimension(:,:,:,:), allocatable :: taus_aer, taua_aer, pmaer
- ! Optics output fields (to be used and allocated by methods using the optics)
- real, dimension(:,:,:), allocatable :: aop_out_ext ! extinctions
- real, dimension(:,:), allocatable :: aop_out_a ! single scattering albedo
- real, dimension(:,:), allocatable :: aop_out_g ! assymetry factor
- ! ------------ begin -----------------
-
- ! count lvec, tile grid size
- CALL GET_DISTGRID( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
- lmr=lm(region)
- lvec = (i2-i1+1)*(j2-j1+1)*lmr
- allocate( aop_out_ext(lvec, nwdep, 1))
- allocate( aop_out_a (lvec, nwdep) )
- allocate( aop_out_g (lvec, nwdep) )
- CALL OPTICS_AOP_GET(lvec, region, nwdep, wdep, 1, aop_out_ext, aop_out_a, aop_out_g, status)
- IF_NOTOK_RETURN(status=1)
- gph => gph_dat(region)%data
- allocate(taus_aer (i1:i2, j1:j2, lmr,nwdep)); taus_aer = 0.0
- allocate(taua_aer (i1:i2, j1:j2, lmr,nwdep)); taua_aer = 0.0
- allocate(pmaer (i1:i2, j1:j2, lmr,nwdep)); pmaer = 0.0
- ! ---------------------------------
- ! unpack results from calculate_aop
- ! ---------------------------------
- lvec = 0
- do l = 1, lmr
- do j = j1,j2
- do i = i1,i2
- lvec = lvec + 1
- taus_aer(i,j,l,1:nwdep) = aop_out_ext(lvec,1:nwdep,1) * aop_out_a(lvec,1:nwdep) * (gph(i,j,l+1) - gph(i,j,l)) ! from 1/m to nondim
- taua_aer(i,j,l,1:nwdep) = aop_out_ext(lvec,1:nwdep,1) * (1.-aop_out_a(lvec,1:nwdep)) * (gph(i,j,l+1) - gph(i,j,l))
- pmaer (i,j,l,1:nwdep) = aop_out_g (lvec,1:nwdep)
-
- enddo
- enddo
- enddo
- nullify(gph)
- do i=1, nbands_trop
- phot_dat(region)%taus_aer(:,:,:,i,1) = taus_aer(:,:,:,wav_grid(i))
- phot_dat(region)%taua_aer(:,:,:,i,1) = taua_aer(:,:,:,wav_grid(i))
- phot_dat(region)%pmaer (:,:,:,i,1) = pmaer (:,:,:,wav_grid(i))
- phot_dat(region)%taus_aer(:,:,:,i,2) = taus_aer(:,:,:,wav_gridA(i))
- phot_dat(region)%taua_aer(:,:,:,i,2) = taua_aer(:,:,:,wav_gridA(i))
- phot_dat(region)%pmaer (:,:,:,i,2) = pmaer (:,:,:,wav_gridA(i))
- enddo
- phot_dat(region)%naer_av = phot_dat(region)%naer_av + float(ndyn)/float(ndyn_max)
- phot_dat(region)%pmaer_av = phot_dat(region)%pmaer_av + float(ndyn)/float(ndyn_max) * phot_dat(region)%pmaer
- phot_dat(region)%taus_aer_av = phot_dat(region)%taus_aer_av + float(ndyn)/float(ndyn_max) * phot_dat(region)%taus_aer
- phot_dat(region)%taua_aer_av = phot_dat(region)%taua_aer_av + float(ndyn)/float(ndyn_max) * phot_dat(region)%taua_aer
- deallocate(taus_aer)
- deallocate(taua_aer)
- deallocate(pmaer)
- Deallocate(aop_out_ext)
- Deallocate(aop_out_a )
- Deallocate(aop_out_g )
- status = 0
- END SUBROUTINE AEROSOL_INFO_M7
- !EOC
- #endif
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: AEROSOL_INFO
- !
- ! !DESCRIPTION: assignment of aerosol optical depths
- !
- ! This is a crude method to provide some average values for the absorption and scattering
- ! terms by background aerosol choice of values defined according to the relative humidity.
- ! Absorption component can be set to zero throughout (M.van Weele, private comm.,2005).
- ! Scattering component chosen to be representative of background aerosol
- ! Moreover there is a choice as the whether the values defined by shettle and fenn are used
- ! This will require a look up table on 1x1,60 layers with indexes 1->4 with respect to
- ! location. At the moment background aerosol is chosen throughout
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE AEROSOL_INFO( region )
- !
- ! !USES:
- !
- use dims, only : im, jm, lm, newsrun, ndyn, ndyn_max
- use binas, only : xm_air, xm_h2o,grav
- use global_data, only : mass_dat
- use MeteoData, only : temper_dat, humid_dat, gph_dat, cc_dat, iwc_dat, lwc_dat, phlb_dat
- use MeteoData, only : lsmask_dat
- !
- ! !INPUT PARAMETERS:
- !
- integer, intent(in) :: region
- !
- ! !REVISION HISTORY:
- ! Jun 2005 - JEW -
- ! 26 Apr 2012 - P. Le Sager - adapted for lon-lat MPI domain decomposition
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- real, dimension(:,:,:,:,:), allocatable :: taus_aer, taua_aer
- real, dimension(:,:,:,:,:), allocatable :: pmaer
- real, dimension(:,:,:), allocatable :: rhum, dens, part, dz, press_lay
- real, dimension(:,:,:), pointer :: q, phlb, temp, gph, frac, xland
- real :: a_sc, b_sc, a_ab, b_ab, a_g, b_g
- real :: bsa, baa, ga
- integer :: i_type
- integer, dimension(:,:), pointer :: aero_clim
- real :: wv, tr, scale_aero, lay1, lay2
- integer :: i, j, l, k, kboun, i_ref, b, wav, ll, n
- integer :: i1, j1, i2, j2, lmr
- logical :: aerosol, shettle_and_fenn
- real, dimension(8) :: rh_ref = (/0., 50., 70., 80., 90., 95., 98., 99./)
- real, dimension(4) :: pn_ref = (/ 15000., 4000., 20000., 5000./)
- !
- ! different aerosol types:
- ! 1 = rural aerosol
- ! 2 = maritime aerosol
- ! 3 = urban aerosol
- ! 4 = free troposphere aerosol
- !-----------------------------------------------------------------------
- aerosol = .false.
- shettle_and_fenn = .true.
- call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
- lmr = lm(region)
-
- allocate(taus_aer(i1:i2, j1:j2, lmr, nbands_trop, ngrid))
- allocate(taua_aer(i1:i2, j1:j2, lmr, nbands_trop, ngrid))
- allocate(pmaer (i1:i2, j1:j2, lmr, nbands_trop, ngrid))
- allocate(rhum (i1:i2, j1:j2, lmr))
- allocate(dens (i1:i2, j1:j2, lmr))
- allocate(part (i1:i2, j1:j2, lmr))
- allocate(dz (i1:i2, j1:j2, lmr))
- allocate(press_lay(i1:i2, j1:j2, lmr))
- ! Initialize values
- taus_aer=0.
- taua_aer=0.
- pmaer =0.
-
- ! read in met. data
- temp => temper_dat(region)%data ! (i1:i2, j1:j2, 1:lmr)
- q => humid_dat(region)%data ! (i1:i2, j1:j2, 1:lmr)
- phlb => phlb_dat(region)%data !
- gph => gph_dat(region)%data ! (i1:i2, j1:j2, 1:lmr+1)
- frac => cc_dat(region)%data ! (i1:i2, j1:j2, 1:lmr)
- xland => lsmask_dat(region)%data ! (i1:i2, j1:j2, 1)
-
- aero_clim => phot_dat(region)%aero_surface_clim ! (i1:i2, j1:j2)
- ! initialize values
- scale_aero = 1.0
- ! the land-sea mask is used to ascribe either marine or rural aerosol for the bottom layers
- dz = 0. ; dens = 0. ; rhum = 0.
- phot_dat(region)%taus_aer = 0.
- phot_dat(region)%taua_aer = 0.
- phot_dat(region)%pmaer = 0.
- if (shettle_and_fenn) then
- if(newsrun) then
- do j=j1,j2
- do i=i1,i2
- if(j<=10 .or. j>=80) then
- aero_clim(i,j)=4
- else
- if(xland(i,j,1) < 30.) aero_clim(i,j)=2
- if(xland(i,j,1) >= 30.) aero_clim(i,j)=1
- endif
- enddo
- enddo
- endif
- do l=1,lm(region)
- do j=j1,j2
- do i=i1,i2
- dz(i,j,l) = (gph(i,j,l+1) - gph(i,j,l))
- press_lay(i,j,l) = (phlb(i,j,l) + phlb(i,j,l+1)) * 0.01 * 0.5 ! hPa
- dens(i,j,l) = 7.2427e18 * press_lay(i,j,l)/temp(i,j,l)
- tr=1.-373.15/temp(i,j,l)
- wv=exp((((-.1299*tr-.6445)*tr-1.976)*tr+13.3185)*tr)
- if(frac(i,j,l)<0.95) rhum(i,j,l)=q(i,j,l)*dens(i,j,l)*xm_air/xm_h2o*temp(i,j,l)/(1013.25*wv*7.24e16)
- ! JEW assume saturation when cloud fraction is very high.
- if(frac(i,j,l)>=0.95) rhum(i,j,l)=98.0
- rhum(i,j,l)=min(98.,rhum(i,j,l))
- enddo
- enddo
- enddo
- !
- ! use land-sea mask to ascribe either marine or rural aerosol for different grid cells
- ! in the lower few KM
- !
- do l=1,lm(region)
- do j=j1,j2
- do i=i1,i2
- if(l<5) then
- i_type=aero_clim(i,j)
- elseif(l>=5) then
- i_type=4
- endif
- kboun = 1
- lay1 = (phlb(i,j,l)/phlb(i,j,kboun))**3
- lay2 = (phlb(i,j,l+1)/phlb(i,j,kboun))**3
- if(i_type<4) then
- part(i,j,l) = scale_aero*pn_ref(i_type)*dz(i,j,l)*100.
- kboun = l
- else
- part(i,j,l) = scale_aero*pn_ref(i_type)*0.5*(lay1+lay2)*dz(i,j,l)*100.
- endif
- i_ref = 8
- do k = 1,8
- if(rh_ref(k) < rhum(i,j,l)) i_ref = k
- enddo
- do n=1,ngrid
- do b=1,nbands_trop
- if (n==1) wav=lmid(b)
- if (n==2) wav=lmid_gridA(b)
- a_sc = (sca(wav,i_ref,i_type)-sca(wav,i_ref+1,i_type))/(rh_ref(i_ref)-rh_ref(i_ref+1))
- b_sc = sca(wav,i_ref,i_type)- a_sc*rh_ref(i_ref)
- a_ab = (abs_eff(wav,i_ref,i_type)-abs_eff(wav,i_ref+1,i_type))/(rh_ref(i_ref)-rh_ref(i_ref+1))
- b_ab = abs_eff(wav,i_ref,i_type)- a_ab*rh_ref(i_ref)
- a_g =(g(wav,i_ref,i_type)-g(wav,i_ref+1,i_type))/(rh_ref(i_ref)-rh_ref(i_ref+1))
- b_g =g(wav,i_ref,i_type) - a_g*rh_ref(i_ref)
- bsa = a_sc*rhum(i,j,l) + b_sc
- baa = a_ab*rhum(i,j,l) + b_ab
- ga = a_g*rhum(i,j,l) + b_g
- taus_aer(i,j,l,b,n) = bsa*part(i,j,l)
- taua_aer(i,j,l,b,n) = baa*part(i,j,l)
- if(taus_aer(i,j,l,n,1)>0.) then
- ! do k = 1,nmom
- pmaer(i,j,l,b,n)=ga
- ! enddo
- else
- pmaer(i,j,l,b,n) = 0.
- endif
- enddo !nbands_trop
- enddo !ngrid
- enddo ! l
- enddo ! j
- enddo ! i
- phot_dat(region)%taus_aer = taus_aer
- phot_dat(region)%taua_aer = taua_aer
- phot_dat(region)%pmaer = pmaer
- endif ! shettle and fenn switch
- ! JEW switch for the aerosol absorption and scattering properties
- if (aerosol) then
- do l=1,lm(region)
- do j=j1,j2
- do i=i1,i2
- dens(i,j,l) = 7.2427e18 * press_lay(i,j,l)/temp(i,j,l)
- tr=1.-373.15/temp(i,j,l)
- wv=exp((((-.1299*tr-.6445)*tr-1.976)*tr+13.3185)*tr)
- rhum(i,j,l)=q(i,j,l)*dens(i,j,l)*xm_air/xm_h2o*temp(i,j,l)/(1013.25*wv*7.24e16)
- if(rhum(i,j,l)>40. .and. rhum(i,j,l)<80.) pmaer(i,j,l,:,:) = 0.65
- if(rhum(i,j,l)>=80.) pmaer(i,j,l,:,:) = 0.85
- enddo
- enddo
- enddo
- phot_dat(region)%taus_aer = 3.0e-3
- phot_dat(region)%taua_aer = 1.5e-4
- phot_dat(region)%pmaer = 0.7
- endif
- ! Averages
- phot_dat(region)%naer_av = phot_dat(region)%naer_av + (float(ndyn)/float(ndyn_max))
- phot_dat(region)%pmaer_av = phot_dat(region)%pmaer_av + (float(ndyn)/float(ndyn_max)) * phot_dat(region)%pmaer
- phot_dat(region)%taus_aer_av = phot_dat(region)%taus_aer_av + (float(ndyn)/float(ndyn_max)) * phot_dat(region)%taus_aer
- phot_dat(region)%taua_aer_av = phot_dat(region)%taua_aer_av + (float(ndyn)/float(ndyn_max)) * phot_dat(region)%taua_aer
-
- ! Done
- deallocate(taus_aer)
- deallocate(taua_aer)
- deallocate(pmaer)
- deallocate(rhum)
- deallocate(dens)
- deallocate(part)
- deallocate(dz)
- deallocate(press_lay)
- nullify(q)
- nullify(temp)
- nullify(phlb)
- nullify(gph)
- nullify(frac)
- nullify(xland)
- nullify(aero_clim)
- END SUBROUTINE AEROSOL_INFO
- !EOC
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: SLINGO
- !
- ! !DESCRIPTION: A. Slingo's data for cloud particle radiative properties
- ! (from 'A GCM Parameterization for the Shortwave Properties of Water Clouds'
- ! JAS vol. 46 may 1989 pp 1419-1427)
- !
- ! Called everytime the meteo data is updated to calculate new
- ! cloud optical properties
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE SLINGO( region )
- !
- ! !USES:
- !
- use binas, only : xmair, Avog
- use dims, only : im, jm, lm, lmax_conv
- use global_data, only : mass_dat
- use MeteoData, only : gph_dat, lwc_dat, iwc_dat, cc_dat, phlb_dat, temper_dat, lsmask_dat
- !
- ! !INPUT PARAMETERS:
- !
- integer, intent(in) :: region
- !
- ! !REVISION HISTORY:
- ! 26 Apr 2012 - P. Le Sager - adapted for lon-lat MPI domain decomposition
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- real :: eff_rad ! effective radius no longer fixed but linked to LWP
- real :: rhodz, tau_c, xsa, press, airn, D_ge
- real :: rclf ! inverse cloud fraction
- real :: clwc, ciwc ! [g/m3]
- real :: lfrac, sfrac ! scaled components due to land and sea fraction
- real,dimension(:,:,:),allocatable :: taua_cld
- real,dimension(:,:,:),allocatable :: taus_cld
- !total scattering optical depth for cloud layer (liquid+cirrus)
- !total absorption optical depth for cloud layer (liquid_cirrus)
- real,dimension(:,:,:),allocatable :: pmcld !phase function (HG)
- !----------------------------Local------------------------------------------
- real,dimension(:,:,:),allocatable :: lwp !cloud liquid water path [g/m^2]
- real,dimension(:,:,:),pointer :: frac, lwc, iwc, gph, phlb, temp, xland
-
- real, parameter :: factor = 7.24e16*1.e6*xmair*29.2605/avog
- real,dimension(:,:,:), allocatable :: dz, totalwc, global_cloud_reff
- real, dimension(4) :: abar, bbar, cbar, dbar, ebar, fbar
- ! A coefficient for extinction optical depth
- ! B coefficiant for extinction optical depth
- ! C coefficiant for single particle scat albedo
- ! D coefficiant for single particle scat albedo
- ! E coefficiant for asymmetry parameter
- ! F coefficiant for asymmetry parameter
- data abar/ 2.817e-02, 2.682e-02,2.264e-02,1.281e-02/
- data bbar/ 1.305 , 1.346 ,1.454 ,1.641 /
- data cbar/-5.62e-08 ,-6.94e-06 ,4.64e-04 ,0.201 /
- data dbar/ 1.63e-07 , 2.35e-05 ,1.24e-03 ,7.56e-03 /
- data ebar/ 0.829 , 0.794 ,0.754 ,0.826 /
- data fbar/ 2.482e-03, 4.226e-03,6.560e-03,4.353e-03/
- real :: abari, bbari, cbari, dbari, ebari, fbari
- ! A coefficiant for current spectral interval
- ! B coefficiant for current spectral interval
- ! C coefficiant for current spectral interval
- ! D coefficiant for current spectral interval
- ! E coefficiant for current spectral interval
- ! F coefficiant for current spectral interval
- real :: gc, wc, tot, tmp1 ,tmp2, tmp3
- !asymmetry factor
- !single scattering albedo
- !total optical depth of cloud layer
- ! constants for scattering parameterization of Fu (1996)
- real, dimension(7) :: a0, a1
- data a0/-.236447E-03,-.236447E-03,-.266955E-03,-.266955E-03,-.266955E-03,-.258858E-03,.982244E-04/
- data a1/.253817E+01 ,.253817E+01 ,.254719E+01 ,.254719E+01 ,.254719E+01 ,.253815E+01,.250875E+01/
- ! Parameters for computing cloud effective radius according to Martin et al. (JAS 1994)
- real :: denom,numerator
- real, parameter :: d_land=0.43
- real, parameter :: d_sea=0.33
- integer :: i,j,l,k, indxsl, n, i1, i2, j1, j2, lmr
- !----------- START----------
- call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
- lmr = lm(region)
-
- !-------------------------------------------------------------------------
- ! Set index for cloud particle properties based on the wavelength,
- ! according to A. Slingo (1989) equations 1-3:
- ! Use index 1 (0.25 to 0.69 micrometers) for visible
- ! Use index 2 (0.69 - 1.19 micrometers) for near-infrared
- ! Use index 3 (1.19 to 2.38 micrometers) for near-infrared
- ! Use index 4 (2.38 to 4.00 micrometers) for near-infrared
- indxsl = 1
- ! Set cloud extinction optical depth, single scatter albedo,
- ! asymmetry parameter, and forward scattered fraction:
- abari = abar(indxsl)
- bbari = bbar(indxsl)
- cbari = cbar(indxsl)
- dbari = dbar(indxsl)
- ebari = ebar(indxsl)
- fbari = fbar(indxsl)
- !
- !--------------------------------------------------------------------------
- ! In the parameterization of Fu(1996) wavelength dependant extinction maybe
- ! calculated using a set of pre-defined constants:
- !
- ! nm a0 a1
- ! 250-300 -.236447E-03 .253817E+01
- ! 300-330 -.266955E-03 .254719E+01
- ! 330-360 -.293599E-03 .254540E+01
- ! 360-400 -.258858E-03 .253815E+01
- ! 400-440 -.106451E-03 .252684E+01
- ! 440-480 .129121E-03 .250410E+01
- ! 480-520 -.954458E-04 .252061E+01
- ! 520-570 -.303108E-04 .251805E+01
- ! 570-640 .982244E-04 .250875E+01
- !
- ! used in Beta=IWC(a0+a1/Dg)
- !--------------------------------------------------------------------------
- allocate(taua_cld(i1:i2, j1:j2, lm(region)))
- allocate(taus_cld(i1:i2, j1:j2, lm(region)))
- allocate(pmcld (i1:i2, j1:j2, lm(region)))
- allocate(lwp (i1:i2, j1:j2, lm(region)))
- allocate(dz (i1:i2, j1:j2, lm(region) ))
- allocate(totalwc (i1:i2, j1:j2, lm(region) ))
- allocate(global_cloud_reff(i1:i2, j1:j2, lm(region) ))
- ! Initialize values
- taua_cld = 0. ; taus_cld = 0. ; pmcld = 0. ; lwp = 0.
- ! assume a baseline cloud radius, required for heterogeneous chemistry
- global_cloud_reff = 6.
- !JEW The ice and water particles are now treated seperately. For cloud the values are taken from slingo
- !JEW the refractive index for ICE is very low below 750nm therefore T~T(scatt).
- iwc => iwc_dat (region)%data ! (i1:i2, j1:j2, 1:lmr)
- frac => cc_dat (region)%data ! (i1:i2, j1:j2, 1:lmr)
- gph => gph_dat (region)%data ! (i1:i2, j1:j2, 1:lmr+1)
- lwc => lwc_dat (region)%data ! (i1:i2, j1:j2, 1:lmr)
- phlb => phlb_dat (region)%data !
- temp => temper_dat(region)%data ! (i1:i2, j1:j2, 1:lmr)
- xland => lsmask_dat(region)%data ! (i1:i2, j1:j2, 1)
- ! No negative input
- lwc=max(0.,lwc)
- iwc=max(0.,iwc)
- ! read in new cloud data to feed into the slingo routine. The values of lwc are zero in top levels so limit layer loop
-
- do l=1,lmax_conv
- do j=j1,j2
- do i=i1,i2
- press = (phlb(i,j,l) + phlb(i,j,l+1)) * 0.5 ! Pa
- dz(i,j,l) = ( gph(i,j,l+1) - gph(i,j,l) )
- ! We have replaced the parameterization of McFarlane et al. (1992) with that of Martin et al. (1994).
- ! In the IFS a crude filter of 0.5 for the land fraction is used with the CNN(Marine) = 40.
- ! and CNN(Land) = 900. Here we weight the final CCN with the actual land fraction so as to introduce
- ! more variability.
- ! JEW : there is a potential problem in that nonzero cloud fractions may occur with no associated lwc value
- ! on TM5 vertical resolutions, therefore a filter w.r.t. both fraction and cloud liquid path are included.
- if( lwc(i,j,l) > 1.e-10 .and. frac(i,j,l) > 0.02 ) then
- ! JEW calculate total water path locally : convert to g/m(2) for slingo input
- ! following the conversion procedure for LWC from ECMWF input from old cloud subroutine.
- ! Included comments from old code to explain the prefactor in rhodz:
- ! rho = airn*1e6*xmair/avo ! g/m3
- ! dz = 29.2605*temp(i,j,l)* alog(phlb(i,j,l)/(1.0+phlb(i,j,l+1)))
- rclf=1./frac(i,j,l)
- rhodz = factor*press*alog(phlb(i,j,l)/(1.0+phlb(i,j,l+1)))
- ! VH - scale lwc and lwp with cloud fraction, to compute cloud optical properties
- ! and droplet radius representative for cloudy part only
- lwp(i,j,l) = rhodz*lwc(i,j,l)*rclf
- airn=7.24e16*press/temp(i,j,l) !#/cm3
- clwc=lwc(i,j,l)*xmair*airn*1.e6/avog ! g/m3
- ! Effective radius: Martin et al. (JAS 1994) parametrization
- !if (xland(i,j,l) > 50.) then
- ! Above land use ccn of ~900
- ! D_land = 0.43
- ! CCNLND = 900
- ! NTOT=-2.10E-04*CCNLAND*CCNLAND+0.568*CCNLAND-27.9
- ! DENOM=4.0*pi*rho_w*NTOT*(1.0+D_land*D_land)**3
- ! with rho_w in g/m3.
- denom = 6547.52*1.e6
- numerator=3.0*clwc*rclf*(1.0+3.0*D_land*D_land)**2
- lfrac=0.
- if((numerator/denom) > 1.e-20) lfrac=1.e4*exp(0.333*LOG(numerator/denom))
- !else
- ! Maritime air mass
- ! D_sea = 0.33
- ! CCNSEA = 40
- ! NTOT=-1.15E-03*CCNSEA*CCNSEA+0.963*CCNSEA+5.30
- ! DENOM=4.0*pi*rho_w*NTOT*(1.0+D_sea*D_sea)**3
- denom = 723.210*1.e6
- numerator=3.0*clwc*rclf*(1.0+3.0*D_sea*D_sea)**2
- sfrac=0.
- if((numerator/denom) > 1.e-20) sfrac=1.e4*exp(0.333*LOG(numerator/denom))
- !endif
- ! TvN: Is this the best way to average land and sea?
- eff_rad=(xland(i,j,1)/100.*lfrac)+(1.0-xland(i,j,1)/100.)*sfrac
- ! prevent the radius of non-precipitation clouds being too big
- ! these size limits are equal to those chosen in the IFS
- eff_rad=min(16.0,max(eff_rad, 4.0))
- tmp1 = abari + bbari/eff_rad
- tmp2 = 1. - cbari - dbari*eff_rad
- tmp3 = fbari*eff_rad
- ! Do not let single scatter albedo be 1; delta-eddington solution
- ! for non-conservative case:
- wc = min(tmp2,.999999)
- tot = lwp(i,j,l)*tmp1
- gc = ebari + tmp3
- ! JEW : no wavelength dependence for the absorption or scattering effects due to liquid clouds !!!!!
- taua_cld(i,j,l) = (1.-wc)*tot
- taus_cld(i,j,l) = wc*tot
- ! avoid possible negatives due to input data
- taua_cld(i,j,l)=max(0.0,taua_cld(i,j,l))
- global_cloud_reff(i,j,l) = eff_rad
- ! JEW : for calculating the scattering component due to ice
- if(iwc(i,j,l) > 1.e-10) then
- airn=7.24e16*press/temp(i,j,l)
- ! iwc in g/m3 from TM5 definition
- ciwc=iwc(i,j,l)*airn*xmair*1.e6/avog
- ! Following Eq. (5) of Heymsfield and McFarquhar (JAS, 1996),
- ! the cross-sectional surface area A (km^-1)
- ! can be approximated by:
- ! 10*IWC^0.9, where IWC in g/m3.
- ! Thus, A in m^2/m^3 = m^-1 is given by 0.01 IWC^0.9,
- ! which implies that xsa is in cm^-1.
- xsa=1.0e-4*ciwc**0.9
- !
- ! calculate D_ge using the relationship in Fu (1996) where Beta=extinction co-efficient (m-1)
- !
- ! D_ge = 2(3)**0.5/(3 Rho)*(IWC/xsa)
- !
- ! The above relationship is for instance given in Table 1
- ! in McFarquhar and Heymsfield (JAS, 1997).
- ! Below an ice density in units g/cm^3 and
- ! IWC in g/m^3 are used.
- ! The conversion of IWC from g/m^3 to g/cm^3
- ! gives a factor 10^6, which together with
- ! the division by 100 converts from cm to um.
- !
- D_ge=(2.*1.73205/(3.*0.917))*(ciwc/xsa)
- ! convert to uM
- D_ge=D_ge/100.
- !
- ! Cirrus scattering has a wavelength dependancy
- !
- taus_cld(i,j,l)=taus_cld(i,j,l)+((ciwc*(a0(3)+(a1(3)/D_ge)))*dz(i,j,l))
- endif
- if (taus_cld(i,j,l) > 0.) then
- pmcld(i,j,l)=gc
- else
- pmcld(i,j,l)=0.
- end if
- end if
- enddo
- enddo
- enddo
- ! Store optical depths and phase functions
- phot_dat(region)%pmcld = pmcld
- phot_dat(region)%taus_cld = taus_cld
- phot_dat(region)%taua_cld = taua_cld
- phot_dat(region)%cloud_reff = global_cloud_reff
- ! Averages
- phot_dat(region)%lwp_av = lwp
- phot_dat(region)%cfr_av = phot_dat(region)%cfr_av + frac
- phot_dat(region)%reff_av = global_cloud_reff
- phot_dat(region)%ncloud_av = phot_dat(region)%ncloud_av + 1
- phot_dat(region)%pmcld_av = phot_dat(region)%pmcld_av + pmcld
- phot_dat(region)%taus_cld_av = phot_dat(region)%taus_cld_av + taus_cld
- phot_dat(region)%taua_cld_av = phot_dat(region)%taua_cld_av + taua_cld
- nullify(lwc)
- nullify(frac)
- nullify(iwc)
- nullify(gph)
- nullify(phlb)
- nullify(temp,xland)
- deallocate(taua_cld)
- deallocate(taus_cld)
- deallocate(pmcld)
- deallocate(lwp)
- deallocate(dz)
- deallocate(totalwc)
- deallocate(global_cloud_reff)
- END SUBROUTINE SLINGO
- !EOC
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: UPDATE_CSQY
- !
- ! !DESCRIPTION:
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE UPDATE_CSQY( region )
- !
- ! !USES:
- !
- use dims
- use binas, only: Avog, xmair, grav
- use global_data, only: mass_dat
- use MeteoData, only: phlb_dat, temper_dat
- use chem_param, only: xmo3, fscale
- !
- ! !INPUT PARAMETERS:
- !
- integer, intent(in) :: region
- !
- ! !REVISION HISTORY:
- ! 26 Apr 2012 - P. Le Sager - adapted for lon-lat MPI domain decomposition
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- integer :: i,j,l
- real,dimension(:,:,:),pointer :: temperature
- real,dimension(:,:,:),pointer :: phlb
- real,dimension(:,:,:),allocatable :: density
- real,dimension(:,:,:),allocatable :: pressure
- integer :: k, m, table_pos, i1, j1, i2, j2, lmr
- real :: xa, xb, te, chix, ww, temper, ptorr
- real :: phi, qy, tt, alpha, delta_t
- real,dimension(maxwav) :: rd, phi0
- real :: a0, b0, a1, b1, a2, b2, a3, b3, c3, a4, b4
- real :: term,term1,term2,t_scale
- phlb => phlb_dat(region)%data
- temperature => temper_dat(region)%data
- call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
- lmr = lm(region)
-
- allocate(density (i1:i2, j1:j2, lmr))
- allocate(pressure(i1:i2, j1:j2, lmr))
- !---------------------------------------------------------------------------------
- ! Only update the temperature sensitive regions of the spectral
- ! grids. That is, initialize values values to either zero or cs_ values for selected
- ! species.
- !---------------------------------------------------------------------------------
- do k = 1,lm(region)
- do j = j1,j2
- do i = i1,i2
- ! define air pressure
- pressure(i,j,k) = (phlb(i,j,k) + phlb(i,j,k+1))/2
- enddo
- enddo
- enddo
- ! define air density
- density = 7.24e16*pressure/temperature(i1:i2, j1:j2, 1:lmr)
- !---------------------------------------------------------------------
- ! QUANTUM YIELD OF METHYGLYOXAL S. KOCH and G. K. MOORTGAT
- ! J Phys Chem, 102, 9142-9153, 1998.
- !
- ! JEW: the qy_ch3cocho array has been reduced to 52 bins to represent the pressure.
- ! dep. spectral bins ONLY !!
- !---------------------------------------------------------------------
- ! Calculate co-efficients for METHYGLYOXAL qy outside loop
- phi0 = 1. ; rd = 0.
- ! for wave < 380nm qy is essentially = 1.0.
- do l = 1,39
- if(l<32) then
- phi0(l) = 1
- elseif(l>=32) then
- phi0(l) = 8.15e-9 * exp(7131./wave(l+37)*1.e-7)
- endif
- rd(l) = 7.34e-9 * exp(8793./wave(l+37)*1.e-7)
- enddo
- do l = 40,52
- phi0(l) = 3.63e-7 * exp(5693./wave(l+37)*1.e-7)
- rd(l) = 1.93e4*exp(-5639./wave(l+37)*1.e-7)
- enddo
- do k = 1,lm(region)
- do j = j1,j2
- do i = i1,i2
- ! QUANTUM YIELD OF METHYGLYOXAL JPL 2006 P4-71
- ! CH3COCHO -> CH3C(O)O2 + HO2 + CO (1)
- ! -> CH4 + 2CO (2)
- ! -> CH3CHO + CO (3)
- ! the predominant products are from channel(1) for wav 240-480nm
- ! hPa -> Torr
- ptorr= (pressure(i,j,k)/100.)*760./1.013*1e-3
- !second absorption band
- do l = 1,39
- qy = (phi0(l) * rd(l))/(rd(l) + ptorr*phi0(l))
- phot_dat(region)%qy_ch3cocho(i,j,k,l) = min(1.0,qy)
- end do
- ! switch to the formulation by Chen et al, JPC, 104, 11126-11131, 2000 for wav > 420nm
- do l = 40,52
- qy = phi0(l)/(1.+(phi0(l)*rd(l)*ptorr))
- phot_dat(region)%qy_ch3cocho(i,j,k,l) = min(1.0,qy)
- enddo
- end do ! longitude
- end do ! latitude
- end do ! level
- deallocate(density)
- deallocate(pressure)
- nullify(temperature)
- nullify(phlb)
- END SUBROUTINE UPDATE_CSQY
- !EOC
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: PIFM
- !
- ! !DESCRIPTION:
- ! *
- ! PRACTICAL IMPROVED FLUX METHOD (PIFM) *
- ! to calculate actinic fluxes *
- ! Zdunkowski,Welch,Korb: Beitr. Phys. Atmosph. vol. 53, p. 147 ff *
- ! *
- ! This version is not suitable for calculation for conserving *
- ! scattering (W0=1). W0 is limited to W0 <= 1. - 1.E-15. *
- ! For W0 = 1, AL(4) and AL(5) has to be calculated differently. *
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE PIFM(region, zangle, alb, cst_o3_col, dv2, dv3, taua_aer_col, taus_aer_col, paer_col, fact)
- !
- ! !USES:
- !
- use dims, only : lm
- use binas, only : pi
- !
- ! !INPUT PARAMETERS:
- !
- integer, intent(in) :: region
- real, intent(in) :: zangle ! zenith angle
- real, intent(in) :: alb ! albedo
- real, dimension(lm(region),maxwav) :: cst_o3_col ! temp dep o3 cross sections
- real, dimension(lm(region)) :: dv2, dv3 ! differential column info
- real, dimension(lm(region),nbands_trop,ngrid) :: taua_aer_col, taus_aer_col ! optical depth aerosols
- real, dimension(lm(region),nbands_trop,ngrid) :: paer_col
- real, dimension(lm(region),nbands_trop) :: fact !actinic flux
- !
- ! !REVISION HISTORY:
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- real, dimension(3*(lm(region)+1)) :: rw, & !flux array for cloudy sky
- rf !flux array for clear sky
- real, dimension(lm(region)) :: tu1, & !parallel solar flux
- tu2 !matrix coefficient
- real, dimension(lm(region),5) :: al
- real, dimension(lm(region)+1,nbands_trop):: sd, fd, fu
- real, dimension(0:nmom) :: pray ! phase functions
- real :: taus, taua, tautot, g
- real, dimension(lm(region),nbands_trop) :: taua_clr, taus_clr ! optical depth clear sky
- ! diffusivity factor
- real, parameter :: u = 2., delu0 = 1.e-3, resonc = 1.e-6
- integer :: grid, l, k, n, nl, k3, maxlev, maxlay2, maxlev3
- real :: p1, w0, f, b0, bu0
- real :: eps, factor, ueps2, smooth1, smooth2
- real :: alph1, alph2, alph3, alph4
- real :: gam1, gam2, e, rm, tds1, td1, td2
- real :: fact_bot, fact_top, arg
- !downward diffuse flux
- !upward diffuse flux
- real :: a, b, c, gamma, u0
- real :: cs_o2
- ! internal integer variable
- maxlev = lm(region) + 1
- maxlay2 = 2 * lm(region)
- maxlev3 = 3 * maxlev
- ! intitialise arrays
- al = 0. ; fd = 0. ; sd = 0. ; fu = 0. ; tu1 = 0. ; tu2 = 0. ; rw = 0. ; rf = 0.
- !initialise output (actinic flux)
- fact = 0.
- !-----correction of the air mass factor---------------------------------
- ! F. Kasten and T. Young, Revised optical air mass tabels and
- ! approximation formula (1989) Aplied Optics Vol 28, No. 22 P. 4735
- ! and J. Lenoble, atmospheric radiative transfer (1993), P. 236
- a = 0.50572 ; b = 6.07995 ; c = 1.63640
- ! define air mass factor in mu
- gamma = 90. - zangle
- u0 = sin(gamma*pi/180.) + a *(gamma+b)**(-c)
- u0 = min(1.,u0)
- !===================================================================
- ! calculation of the matrix coefficients a1,...,a5
- !===================================================================
- ! determine phase functions
- pray(0) = 1. ; pray(1) = 0. ; pray(2)=0.1 ; pray(3:nmom) = 0.
- ! reverse order for input parameters
- dv2(1:lm(region)) = dv2(lm(region):1:-1)
- dv3(1:lm(region)) = dv3(lm(region):1:-1)
- ! do not calculate for band #1
- do l = 1,nbands_trop
- if (zangle <= 71.) then
- nl = lmid(l)
- grid = 1
- cs_o2 = 7.322e-24
- elseif (zangle > 71. .and. zangle<=sza_limit) then
- nl = lmid_gridA(l)
- grid = 2
- cs_o2 = 6.608e-24
- endif
- ! reverse order for input parameters
- cst_o3_col(1:lm(region),nl) = cst_o3_col(lm(region):1:-1,nl)
- taus_aer_col(1:lm(region),l,grid) = taus_aer_col(lm(region):1:-1,l,grid)
- taua_aer_col(1:lm(region),l,grid) = taua_aer_col(lm(region):1:-1,l,grid)
- paer_col(1:lm(region),l,grid) = paer_col(lm(region):1:-1,l,grid)
- do k = 1,lm(region)
- ! Calculate optical depth (clear-sky)
- if(nl<18) then
- taua_clr(k,l) = cs_o2*dv2(k) + cst_o3_col(k,nl)*dv3(k)
- else
- taua_clr(k,l) = cst_o3_col(k,nl)*dv3(k)
- endif
- taus_clr(k,l) = cs_ray(nl)*1./0.2095*dv2(k)
- taus = taus_clr(k,l) + taus_aer_col(k,l,grid)
- taua = taua_clr(k,l) + taua_aer_col(k,l,grid)
- tautot = taus + taua
- g = 0.
- if (taus > 0.) &
- g = (paer_col(k,l,grid)* taus_aer_col(k,l,grid) + pray(1)* taus_clr(k,l) )/taus
- if (tautot .ne. 0.) then
- w0=taus / tautot
- else
- w0=0.
- end if
- w0 = min(w0,1.-1.e-15)
- ! P1: first expansion coefficient of the phase function
- p1=3.*g
- ! F: fraction of radiation contained in diffraction peak
- f=g**2
- ! B0: fractional mean backward scattering coefficient
- ! of diffuse light
- ! BU0: backward scattering coefficient of primary scattered
- ! parallel solar light
- ! for small P1 SMOOTH1,SMOOTH2 manage the smooth change of B0
- ! BU0 to 0
- if (p1 <= 0.1) then
- smooth1=1.33333333-p1*3.3333333
- smooth2=10.*p1
- else
- smooth1=1.
- smooth2=1.
- end if
- b0=(3.-p1)/8. *smooth1
- bu0=0.5-u0/4.*(p1-3.*f)/(1.-f) *smooth2
- ! alpha coefficient
- alph1=u*(1.-(1.-b0)*w0)
- alph2=u*b0*w0
- alph3=w0*bu0*(1-f)
- alph4=w0*(1.-bu0)*(1-f)
- ! epsilon and gamma coefficient
- eps=sqrt(alph1**2-alph2**2)
- factor=1.-w0*f
- ! check for resonance condition in GAM1 and GAM2, if fulfil th
- ! chance U0(J) and calculate UEPS2, BU0, ALPH3, ALPH4 again.
- ueps2=(u0 *eps)**2
- arg = ueps2-factor**2
- if (arg < 0.) arg = -1. * arg
- if (arg < resonc) then
- if (ueps2.lt.factor**2) then
- u0 = u0 - delu0
- else
- u0 = u0 + delu0
- end if
- ueps2=(u0 * eps)**2
- bu0=0.5-u0/4.*(p1-3.*f)/(1.-f) *smooth2
- alph3=w0*bu0*(1-f)
- alph4=w0*(1.-bu0)*(1-f)
- end if
- gam1=( factor*alph3-u0 * (alph1*alph3+alph2*alph4) ) * &
- 1/(factor**2-ueps2)
- gam2=(-factor*alph4-u0 * (alph1*alph4+alph2*alph3) ) * &
- 1/(factor**2-ueps2)
- e=exp(-eps*tautot)
- rm=alph2/(alph1+eps)
- al(k,4)=e*(1.-rm**2.)/(1.-e**2. * rm**2.)
- al(k,5)=rm*(1.-e**2.)/(1.-e**2. * rm**2.)
- al(k,1)=exp(-factor*tautot/u0)
- al(k,2)=-al(k,4)*gam2-al(k,5)*gam1*al(k,1) + gam2*al(k,1)
- al(k,3)=-al(k,5)*gam2-al(k,4)*gam1*al(k,1) + gam1
- enddo
- !====================================================================
- ! matrix inversion
- !====================================================================
- ! direct solution of the first four equations
- rf(1) = u0 * flux(nl)
- rf(2) = 0.
- ! 5th to 10th equation: bring matrix elements on the left of the m
- ! diagonal to the rhs: save elements on the right of the main
- ! diagonal in array -tu(l,1)
- rf(3) = al(1,3) * rf(1)
- rf(4) = al(1,1) * rf(1)
- rf(5) = al(1,2) * rf(1)
- tu1(1) = al(1,4)
- tu2(1) = al(1,5)
- ! blocks of 6 equations: eliminate left matrix elements, save righ
- ! matrix elements in array -tu(l,i),
- ! calculate rhs.
- do k=2,lm(region)
- k3=3*k
- td1 = 1./(1.-al(k,5)*tu2(k-1))
- td2 = al(k,4)*tu2(k-1)
- tu1(k) = td1*al(k,4)
- tu2(k) = al(k,5) + td2*tu1(k)
- rf(k3) = td1 * (al(k,3)*rf(k3-2) + al(k,5)*rf(k3-1))
- rf(k3+1)= al(k,1)*rf(k3-2)
- rf(k3+2)= al(k,2)*rf(k3-2) + al(k,4)*rf(k3-1)+td2*rf(k3)
- end do
- ! last two equations: the same as before
- tds1 = 1. / (1.-alb*tu2(lm(region)))
- rf(maxlev3) = tds1 * (alb * rf(maxlev3-2)+ &
- alb * rf(maxlev3-1))
- ! now we have created an upper triangular matrix the elements of
- ! are -tu(l,i), 0, or 1 (in the main diagonal). the 0 and 1 eleme
- ! are not stored in an array. let us solve the system now and sto
- ! results in the arrays rf (fluxes clear sky) and rw (fluxes clou
- do k=lm(region),1,-1
- k3=3*k
- rf(k3+2) = rf(k3+2) + tu2(k)*rf(k3+3)
- rf(k3) = rf(k3) + tu1(k)*rf(k3+3)
- sd(k+1,l) = rf(k3+1)
- fd(k+1,l) = rf(k3+2)
- fu(k+1,l) = rf(k3+3)
- end do
- sd(1,l) = rf(1)
- fd(1,l) = rf(2)
- fu(1,l) = rf(3)
- ! calculate the actinic flux
- fact_top = sd(1,l)/u0 + u * fd(1,l) + u * fu(1,l)
- do k = 1,lm(region)
- fact_bot = sd(k+1,l)/u0 + &
- u * fd(k+1,l) + u * fu(k+1,l)
- fact(k,l) = max(0. ,(fact_top + fact_bot)/2.)
- fact_top = fact_bot
- end do
- ! swap vertical levels to the default order of the model
- fact(1:lm(region),l) = fact(lm(region):1:-1,l)
- cst_o3_col(1:lm(region),nl) = cst_o3_col(lm(region):1:-1,nl)
- enddo ! spectral bands (nbands)
- END SUBROUTINE PIFM
- !EOC
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: PIFM_RAN
- !
- ! !DESCRIPTION: Pifm method including random overlap method for clouds
- !
- !************************************************************************
- !* PRACTICAL IMPROVED FLUX METHOD (PIFM) *
- !* to calculate actinic fluxes *
- !* Zdunkowski,Welch,Korb: Beitr. Phys. Atmosph. vol. 53, p. 147 ff *
- !* *
- !* Cloud effects added using the method of : *
- !* Geleyn and Hollingworth, Contribs. Atms.Phys,52(1),1979 *
- !* *
- !************************************************************************
- !* This version is not suitable for calculation for conserving *
- !* scattering (W0=1). W0 is limited to W0 .le. 1. - 1.E-15. *
- !* For W0 = 1, AL(4) and AL(5) has to be calculated differently. *
- !************************************************************************
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE PIFM_RAN(region, zangle, alb, cst_o3_col, dv2, dv3, &
- taua_cld_col, taus_cld_col, pcld_col, &
- taua_aer_col, taus_aer_col, paer_col, fact, frac )
- !
- ! !USES:
- !
- use dims, only : lm
- use binas, only : pi
- !
- ! !INPUT PARAMETERS:
- !
- integer, intent(in) :: region
- real, intent(in) :: zangle ! zenith angle
- real, intent(in) :: alb ! albedo
-
- real,dimension(lm(region)) :: frac ! cloud fraction per layer (0->1)
- real,dimension(lm(region),maxwav) :: cst_o3_col ! o3 cross sections
- real,dimension(lm(region)) :: dv2, dv3 ! differential column info
- real,dimension(lm(region)) :: taua_cld_col, taus_cld_col ! optical depth clouds
- real,dimension(lm(region),nbands_trop) :: taua_clr_col, taus_clr_col ! optical depth clear sky
- real,dimension(lm(region),nbands_trop,ngrid) :: taua_aer_col, taus_aer_col ! optical depth aerosols
- real,dimension(lm(region),nbands_trop) :: fact ! actinic flux
- real,dimension(lm(region),nbands_trop,ngrid) :: paer_col ! aerosol phase functions
- real,dimension(lm(region)) :: pcld_col ! cloud phase functions
- real,dimension(0:nmom) :: pray ! rayleigh phase function
- !
- ! !REVISION HISTORY:
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- real,dimension(3*(lm(region)+1)) :: rw, & ! flux array for cloudy sky
- rf ! flux array for clear sky
- real,dimension(lm(region)) :: tu1, & ! parallel solar flux
- tu2 ! matrix coefficient
- real,dimension(lm(region),5) :: al
- real,dimension(lm(region)+1,nbands_trop):: sd, fd, fu
- real,dimension(lm(region),nbands_trop) :: TS_PI_CLR,TA_PI_CLR, G_PI_CLR, TS_PI_CLD
- real,dimension(lm(region)) :: TA_PI_CLD, G_PI_CLD
- real :: U,DELU0,RESONC,a,b,c,gamma,u0,cs_o2
- integer :: grid,j,k,l,maxlev,maxlay2,maxlev3,nl,k3
- real :: w0,p1,F,smooth1,smooth2,b0,bu0,alph1,alph2,alph3,alph4,tautot,eps,factor
- real :: rm,gam1,gam2,e,tauscat,td1,td2,tds1,ueps2,g,arg,fact_bot, fact_top
- ! diffusivity factor
- DATA U / 2./
- DATA DELU0 /1.E-3/
- DATA RESONC /1.E-6/
- real :: AL_CLR_1,AL_CLR_2,AL_CLR_3,AL_CLR_4,AL_CLR_5 !matrix coefficient for clear sky
- real :: AL_CLD_1,AL_CLD_2,AL_CLD_3,AL_CLD_4,AL_CLD_5 !matrix coefficient for cloudy sky
- !-----correction of the air mass factor---------------------------------
- ! F. Kasten and T. Young, Revised optical air mass tables and
- ! approximation formula (1989) Aplied Optics Vol 28, No. 22 P. 4735
- ! and J. Lenoble, atmospheric radiative transfer (1993), P. 236
- a = 0.50572 ; b = 6.07995 ; c = 1.63640
- ! define air mass factor in mu
- gamma = 90. - zangle
- u0 = sin(gamma*pi/180.) + a *(gamma+b)**(-c)
- u0 = min(1.,u0)
- !---------------------------------------------------------------------
- ! internal integer variable
- MAXLEV = lm(region) + 1
- MAXLAY2 = 2 * lm(region)
- MAXLEV3 = 3 * MAXLEV
- ! initialize
- fact = 0. ; sd = 0 ; fd = 0. ; fu = 0. ; td1 = 0.
- rf = 0. ; rw = 0. ; al = 0. ; tu1 = 0. ; tu2 = 0.
- ! determine phase functions
- pray(0) = 1. ; pray(1) = 0. ; pray(2)=0.1 ; pray(3:nmom) = 0.
- dv2(1:lm(region)) = dv2(lm(region):1:-1)
- dv3(1:lm(region)) = dv3(lm(region):1:-1)
- frac(1:lm(region)) = frac(lm(region):1:-1)
- taua_cld_col(1:lm(region)) = taua_cld_col(lm(region):1:-1)
- taus_cld_col(1:lm(region)) = taus_cld_col(lm(region):1:-1)
- pcld_col(1:lm(region)) = pcld_col(lm(region):1:-1)
- do l = 1,nbands_trop
- if (zangle <= 71.) then
- nl = lmid(l)
- grid = 1
- cs_o2 = 7.322e-24
- elseif (zangle > 71. .and. zangle<=sza_limit) then
- nl = lmid_gridA(l)
- grid = 2
- cs_o2 = 6.608e-24
- endif
- ! reverse order for input parameters
- cst_o3_col(1:lm(region),nl) = cst_o3_col(lm(region):1:-1,nl)
- taus_aer_col(1:lm(region),l,grid) = taus_aer_col(lm(region):1:-1,l,grid)
- taua_aer_col(1:lm(region),l,grid) = taua_aer_col(lm(region):1:-1,l,grid)
- paer_col(1:lm(region),l,grid) = paer_col(lm(region):1:-1,l,grid)
- ! fill array for absorption and scattering components before performing
- ! calculations.
- do K = 1,lm(region)
- taus_clr_col(k,l) = cs_ray(nl)*1./0.2095*dv2(k)
- if(nl<18) then
- taua_clr_col(k,l) = cs_o2*dv2(k) + cst_o3_col(k,nl)*dv3(k)
- else
- taua_clr_col(k,l) = cst_o3_col(k,nl)*dv3(k)
- endif
- TS_PI_CLR(K,L) = TAUS_CLR_col(K,L)+TAUS_AER_col(K,L,grid)
- TA_PI_CLR(K,L) = TAUA_CLR_col(K,L)+TAUA_AER_col(K,L,grid)
- TS_PI_CLD(K,L) = TAUS_CLD_col(K)
- TA_PI_CLD(K) = TAUA_CLD_col(K)
- IF (TAUS_CLR_col(K,L)+TAUS_AER_col(K,L,grid)>0.) THEN
- G_PI_CLR(K,L) = (PRAY(1)*TAUS_CLR_col(K,L) + &
- PAER_col(k,l,grid)*TAUS_AER_col(K,L,grid))/ &
- (TAUS_CLR_col(K,L)+TAUS_AER_col(K,L,grid))
- ELSE
- G_PI_CLR(K,L) = 0.
- ENDIF
- G_PI_CLD(K) = PCLD_col(k)
- enddo
- do K = 1,lm(region)
- !***** first: clear sky *******************************************
- TAUTOT = TS_PI_CLR(K,L)+TA_PI_CLR(K,L)
- if (tautot /= 0.) then
- W0=TS_PI_CLR(K,L) / TAUTOT
- ELSE
- W0=0.
- ENDIF
- W0 = MIN(W0,1.-1e-15)
- ! P1: first expansion coefficient of the phase function
- P1=3.*G_PI_CLR(K,L)
- ! F: fraction of radiation contained in diffraction peak
- F=G_PI_CLR(K,L)**2
- ! B0: fractional mean backward scattering coefficient of diffuse light
- ! BU0: backward scattering coefficient of primary scattered parallel solar light
- ! for small P1 SMOOTH1,SMOOTH2 manage the smooth change of B0 and
- ! BU0 to 0
- IF (P1<=0.1) THEN
- SMOOTH1=1.33333333-P1*3.3333333
- SMOOTH2=10.*P1
- ELSE
- SMOOTH1=1
- SMOOTH2=1
- ENDIF
- B0=(3.-P1)/8. *SMOOTH1
- BU0=0.5-U0/4.*(P1-3.*F)/(1.-F) *SMOOTH2
- ! alpha coefficient
- ALPH1=U*(1.-(1.-B0)*W0)
- ALPH2=U*B0*W0
- ALPH3=W0*BU0*(1-F)
- ALPH4=W0*(1.-BU0)*(1-F)
- ! epsilon and gamma coefficient
- EPS=SQRT(ALPH1**2-ALPH2**2)
- FACTOR=1.-W0*F
- ! check for resonance condition in GAM1 and GAM2, if fulfil then
- ! chance U0 and calculate UEPS2, BU0, ALPH3, ALPH4 again.
- UEPS2=(U0*EPS)**2
- arg = ueps2-factor**2
- if (arg < 0.) then
- arg = -1. * arg
- endif
- if (arg < resonc) then
- IF(UEPS2.LT.FACTOR**2) THEN
- U0=U0-DELU0
- ELSE
- U0=U0+DELU0
- ENDIF
- UEPS2=(U0*EPS)**2
- BU0=0.5-U0/4.*(P1-3.*F)/(1.-F) *SMOOTH2
- ALPH3=W0*BU0*(1-F)
- ALPH4=W0*(1.-BU0)*(1-F)
- ENDIF
- GAM1=( FACTOR*ALPH3-U0*(ALPH1*ALPH3+ALPH2*ALPH4) ) * &
- & 1/(FACTOR**2-UEPS2)
- GAM2=(-FACTOR*ALPH4-U0*(ALPH1*ALPH4+ALPH2*ALPH3) ) * &
- & 1/(FACTOR**2-UEPS2)
- E=EXP(-EPS*TAUTOT)
- RM=ALPH2/(ALPH1+EPS)
- AL_CLR_4= E*(1-RM**2)/(1-E**2 * RM**2)
- AL_CLR_5= RM*(1-E**2)/(1-E**2 * RM**2)
- AL_CLR_1= EXP(-FACTOR*TAUTOT/U0)
- AL_CLR_2=-AL_CLR_4*GAM2-AL_CLR_5*GAM1* &
- & AL_CLR_1+GAM2*AL_CLR_1
- AL_CLR_3=-AL_CLR_5*GAM2-AL_CLR_4*GAM1* &
- & AL_CLR_1+GAM1
- !******************* second: cloudy sky *****************************
- ! For ECMWF input there is the possibility that cloud fraction occurs without a
- ! corresponding value for lwc
- IF( FRAC(K) > 0.02 .and. TS_PI_CLD(K,L) > 1.e-5 ) THEN
- TAUSCAT = TS_PI_CLR(K,L) + TAUS_CLD_col(K)
- TAUTOT = TA_PI_CLR(K,L) + TAUA_CLD_col(K)+TAUSCAT
- G = G_PI_CLD(K)*TAUS_CLD_col(K)/TAUSCAT
- IF (TAUTOT > 0.) THEN
- W0=TAUSCAT/TAUTOT
- ELSE
- W0=0.
- ENDIF
- W0 = MIN(W0,1.-1e-15)
- P1=3.*G
- F=G**2
- IF (P1<0.1) THEN
- SMOOTH1=1.33333333-P1*3.3333333
- SMOOTH2=10.*P1
- ELSE
- SMOOTH1=1
- SMOOTH2=1
- ENDIF
- B0=(3.-P1)/8. *SMOOTH1
- BU0=0.5-U0/4.*(P1-3.*F)/(1.-F) *SMOOTH2
- ALPH1=U*(1.-(1.-B0)*W0)
- ALPH2=U*B0*W0
- ALPH3=W0*BU0*(1-F)
- ALPH4=W0*(1.-BU0)*(1-F)
- EPS=SQRT(ALPH1**2-ALPH2**2)
- FACTOR=1.-W0*F
- UEPS2=(U0*EPS)**2
- arg = ueps2-factor**2
- if (arg < 0.) then
- arg = -1. * arg
- endif
- if (arg < resonc) then
- IF(UEPS2.LT.FACTOR**2) THEN
- U0=U0-DELU0
- ELSE
- U0=U0+DELU0
- ENDIF
- UEPS2=(U0*EPS)**2
- BU0=0.5-U0/4.*(P1-3.*F)/(1.-F) *SMOOTH2
- ALPH3=W0*BU0*(1-F)
- ALPH4=W0*(1.-BU0)*(1-F)
- ENDIF
- GAM1=( FACTOR*ALPH3-U0*(ALPH1*ALPH3+ALPH2*ALPH4) ) * 1/(FACTOR**2-UEPS2)
- GAM2=(-FACTOR*ALPH4-U0*(ALPH1*ALPH4+ALPH2*ALPH3) ) * 1/(FACTOR**2-UEPS2)
- E=EXP(-EPS*TAUTOT)
- RM=ALPH2/(ALPH1+EPS)
- AL_CLD_4=E*(1-RM**2)/(1-E**2 * RM**2)
- AL_CLD_5=RM*(1-E**2)/(1-E**2 * RM**2)
- AL_CLD_1=EXP(-FACTOR*TAUTOT/U0)
- AL_CLD_2=-AL_CLD_4*GAM2-AL_CLD_5*GAM1*AL_CLD_1+GAM2*AL_CLD_1
- AL_CLD_3=-AL_CLD_5*GAM2-AL_CLD_4*GAM1*AL_CLD_1+GAM1
- AL(K,1) =(1-FRAC(K))*AL_CLR_1 + FRAC(K)*AL_CLD_1
- AL(K,2) =(1-FRAC(K))*AL_CLR_2 + FRAC(K)*AL_CLD_2
- AL(K,3) =(1-FRAC(K))*AL_CLR_3 + FRAC(K)*AL_CLD_3
- AL(K,4) =(1-FRAC(K))*AL_CLR_4 + FRAC(K)*AL_CLD_4
- AL(K,5) =(1-FRAC(K))*AL_CLR_5 + FRAC(K)*AL_CLD_5
- ELSE
- AL(K,1) = AL_CLR_1
- AL(K,2) = AL_CLR_2
- AL(K,3) = AL_CLR_3
- AL(K,4) = AL_CLR_4
- AL(K,5) = AL_CLR_5
- ENDIF
- enddo !k
- !====================================================================
- ! matrix inversion
- !====================================================================
- ! direct solution of the first four equations
- RF(1) = U0*FLUX(NL)
- RF(2) = 0.
- ! 5th to 10th equation: bring matrix elements on the left of the main
- ! diagonal to the rhs: save elements on the right of the main
- ! diagonal in array -tu(l,1)
- RF(3) = AL(1,3) * RF(1)
- RF(4) = AL(1,1) * RF(1)
- RF(5) = AL(1,2) * RF(1)
- TU1(1) = AL(1,4)
- TU2(1) = AL(1,5)
- ! blocks of 6 equations: eliminate left matrix elements, save right
- ! matrix elements in array -tu(l,i),
- ! calculate rhs.
- DO K=2,lm(region)
- K3=3*K
- TD1 = 1./(1.-AL(K,5)*TU2(K-1))
- TD2 = AL(K,4)*TU2(K-1)
- TU1(K) = TD1*AL(K,4)
- TU2(K) = AL(K,5) + TD2*TU1(K)
- RF(K3) = TD1 * (AL(K,3)*RF(K3-2) + AL(K,5)*RF(K3-1))
- RF(K3+1)= AL(K,1)*RF(K3-2)
- RF(K3+2)= AL(K,2)*RF(K3-2) + AL(K,4)*RF(K3-1)+TD2*RF(K3)
- enddo
- ! last two equations: the same as before
- TDS1 = 1. / (1.-ALB*TU2(lm(region)))
- rf(maxlev3) = tds1 * (alb * rf(maxlev3-2)+ &
- alb * rf(maxlev3-1))
- ! now we have created an upper triangular matrix the elements of which
- ! are -tu(l,i), 0, or 1 (in the main diagonal). the 0 and 1 elements
- ! are not stored in an array. let us solve the system now and store the
- ! results in the arrays rf (fluxes clear sky) and rw (fluxes cloudy sky)
- DO K=lm(region),1,-1
- K3=3*K
- RF(K3+2) = RF(K3+2) + TU2(K)*RF(K3+3)
- RF(K3) = RF(K3) + TU1(K)*RF(K3+3)
- SD(K+1,L) = RF(K3+1)
- FD(K+1,L) = RF(K3+2)
- FU(K+1,L) = RF(K3+3)
- enddo ! K
- SD(1,L) = RF(1)
- FD(1,L) = RF(2)
- FU(1,L) = RF(3)
- ! calculate the actinic flux
- fact_top = sd(1,l)/u0 + u * fd(1,l) + u * fu(1,l)
- do k = 1,lm(region)
- fact_bot = sd(k+1,l)/u0 + u * fd(k+1,l) + u * fu(k+1,l)
- fact(k,l) = max(0. ,(fact_top + fact_bot)/2.)
- fact_top = fact_bot
- end do ! K
- ! swap vertical levels to the default order of the model
- fact(1:lm(region),l) = fact(lm(region):1:-1,l)
- cst_o3_col(1:lm(region),nl) = cst_o3_col(lm(region):1:-1,nl)
- enddo ! wavelength
- return
- END SUBROUTINE PIFM_RAN
- !EOC
- !------------------------------------------------------------------------------
- ! TM5 !
- !------------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: SUNDIS
- !
- ! !DESCRIPTION:
- !-----------------------------------------------------------------------------*
- != purpose: =*
- != calculate earth-sun distance variation for a given date. based on =*
- != fourier coefficients originally from: spencer, j.w., 1971, fourier =*
- != series representation of the position of the sun, search, 2:172 =*
- !-----------------------------------------------------------------------------*
- != parameters: =*
- != idate - integer, specification of the date, from yymmdd (i)=*
- != esrm2 - real, variation of the earth-sun distance (o)=*
- != esrm2 = (average e/s dist)^2 / (e/s dist on day idate)^2 =*
- !-----------------------------------------------------------------------------*
- != edit history: =*
- != 01/95 changed computation of trig function values =*
- !-----------------------------------------------------------------------------*
- != this program is free software; you can redistribute it and/or modify =*
- != it under the terms of the gnu general public license as published by the =*
- != free software foundation; either version 2 of the license, or (at your =*
- != option) any later version. =*
- != the tuv package is distributed in the hope that it will be useful, but =*
- != without any warranty; without even the implied warranty of merchantibi- =*
- != lity or fitness for a particular purpose. see the gnu general public =*
- != license for more details. =*
- != to obtain a copy of the gnu general public license, write to: =*
- != free software foundation, inc., 675 mass ave, cambridge, ma 02139, usa. =*
- !-----------------------------------------------------------------------------*
- != to contact the authors, please mail to: =*
- != sasha madronich, ncar/acd, p.o.box 3000, boulder, co, 80307-3000, usa or =*
- != send email to: sasha@ucar.edu =*
- !-----------------------------------------------------------------------------*
- != copyright (c) 1994,95,96 university corporation for atmospheric research =*
- !-----------------------------------------------------------------------------*
- !\\
- !\\
- ! !INTERFACE:
- !
- REAL FUNCTION SUNDIS( imonth, iday)
- !
- ! !USES:
- !
- use binas, only : pi
- !
- ! !INPUT PARAMETERS:
- !
- integer, intent(in) :: iday, imonth
- !
- ! !REVISION HISTORY:
- !
- !EOP
- !------------------------------------------------------------------------------
- !BOC
- ! internal:
- integer mday, month, jday
- real dayn, thet0
- real sinth, costh, sin2th, cos2th
- integer,dimension(12) ::imn=(/ 31,28,31,30,31,30,31,31,30,31,30,31 /)
- ! start
- ! parse date to find day number (julian day)
- mday = 0
- do month = 1, imonth-1
- mday = mday + imn(month)
- end do
- jday = mday + iday
- dayn = float(jday - 1) + 0.5
- ! define angular day number and compute esrm2:
- thet0 = 2.*pi*dayn/365.
- ! calculate sin(2*thet0), cos(2*thet0) from
- ! addition theoremes for trig functions for better
- ! performance; the computation of sin2th, cos2th
- ! is about 5-6 times faster than the evaluation
- ! of the intrinsic functions sin and cos
- !
- sinth = sin(thet0)
- costh = cos(thet0)
- sin2th = 2.*sinth*costh
- cos2th = costh*costh - sinth*sinth
- sundis = 1.000110 + 0.034221*costh + 0.001280*sinth + &
- 0.000719*cos2th + 0.000077*sin2th
- !
- END FUNCTION SUNDIS
- !EOC
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: OZONE_INFO_ONLINE
- !
- ! !DESCRIPTION: calculate, from an ozone field, the overhead ozone at all
- ! grid points.
- ! Optical depth clear sky conditions
- ! upper values are given by the ozone climatology above the
- ! highest model mid-level
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE OZONE_INFO_ONLINE( region )
- !
- ! !USES:
- !
- use binas, only : Avog, xm_air, grav
- use dims
- ! use photolysis_data, only : phot_dat
- use global_data, only : region_dat, mass_dat
- use chem_param, only : xmo3, io3
- use meteodata, only : phlb_dat
- !
- ! !INPUT PARAMETERS:
- !
- integer, intent(in) :: region
- !
- ! !REVISION HISTORY:
- ! Jan 2003 - MK - adapted for new TM5 memory structure.
- ! Jul 2008 - JEW - new ozone info unit coupled for online calculations
- ! 26 Apr 2012 - P. Le Sager - adapted for lon-lat MPI domain decomposition
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- real, parameter :: conv = 0.1*Avog/xmo3 ! from kg/m2 --> #/cm2
- real, parameter :: sp = Avog*1.e-4*0.2095/(xm_air*grav)
- integer :: i, j, l, lmr, i1, i2, j1, j2
- real,dimension(:,:,:),allocatable :: o3_overhead_online, o2_overhead ! #/cm2
- real,dimension(:), pointer :: ozone_klimtop !in #cm-2
- real,dimension(:,:), pointer :: v3_surf ! #/cm2
- real,dimension(:,:,:),pointer :: v2, v3 ! #/cm2
- real,dimension(:,:,:,:),pointer :: o3 ! #/cm2
- real,dimension(:,:,:),pointer :: phlb
- real,dimension(:), pointer :: area
-
- call Get_DistGrid( dgrid(region), I_STRT=i1, I_STOP=i2, J_STRT=j1, J_STOP=j2 )
- lmr = lm(region)
-
- ! allocate on all prcessors so result maybe scattered
- allocate(o3_overhead_online(i1:i2, j1:j2, lm(region))) ; o3_overhead_online = 0.0
- allocate(o2_overhead (i1:i2, j1:j2, lm(region))) ; o2_overhead = 0.0
- v2 => phot_dat(region)%v2
- v3 => phot_dat(region)%v3
- v3_surf => phot_dat(region)%v3_surf
- area => region_dat(region)%dxyp
- phlb => phlb_dat(region)%data
- o3 => mass_dat(region)%rm ! (i1:i2, j1:j2, 1:lmr, io3)
- ! CALCULATE COLUMNS
- ! -----------------
- ! (1) top
- ! --------
- ! o3du is not used anymore, except in cases where stratosphere is not resolved (EC-EARTH)
- if (with_o3du) then ! use fortuin-kelder
- ozone_klimtop => phot_dat(region)%o3klim_top
- do j=j1,j2
- do i=i1,i2
- o3_overhead_online(i,j,lm(region)) = ozone_klimtop(j)
- end do
- end do
-
- else ! from TM4-routine
-
- do j=j1,j2
- do i=i1,i2
- o3_overhead_online(i,j,lm(region)) = 0.5*conv*o3(i,j,lm(region),io3)/area(j)
- end do
- end do
-
- endif
-
- ! (2) rest
- ! --------
- do l = lm(region)-1,1,-1
- do j = j1,j2
- do i = i1,i2
- o3_overhead_online(i,j,l) = o3_overhead_online(i,j,l+1) + &
- 0.5*conv*(o3(i,j,l,io3)+o3(i,j,l+1,io3))/area(j)
- enddo
- enddo
- enddo
- ! Define surface ozone column field for diagnostic purposes
- do j=j1,j2
- do i=i1,i2
- v3_surf(i,j) = o3_overhead_online(i,j,1) + 0.5*conv*o3(i,j,1,io3)/area(j)
- end do
- end do
- ! Boundaries
- v3(:,:,1) = o3_overhead_online(:,:,1)
- ! now transform o3 column from layers to levels
- do l = 2,lm(region)
- v3(:,:,l) = ( o3_overhead_online(:,:,l) + o3_overhead_online(:,:,l-1) ) * 0.5
- enddo
- ! TOA
- do j=j1,j2
- do i=i1,i2
- v3(i,j,lm(region)+1) = 0.5*v3(i,j,lm(region))
- enddo
- enddo
- ! determine oxygen columns (can directly be calculated on levels)
- do l = 1,lm(region)
- do j = j1,j2
- do i = i1,i2
- v2(i,j,l) = phlb(i,j,l)*sp
- enddo
- enddo
- enddo
- ! top boundary for v2
- v2(:,:,lm(region)+1) = 0.5*v2(:,:,lm(region))
- nullify(o3)
- nullify(ozone_klimtop)
- nullify(area)
- nullify(phlb)
- nullify(v2)
- nullify(v3)
- nullify(v3_surf)
- deallocate(o3_overhead_online)
- deallocate(o2_overhead)
- END SUBROUTINE OZONE_INFO_ONLINE
- !EOC
- !--------------------------------------------------------------------------
- ! TM5 !
- !--------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: PHOTORATES_TROPO
- !
- ! !DESCRIPTION: calculation of photolysis and heating rates
- !
- ! References:
- ! J. Landgraf and P.J. Crutzen, 1998:
- ! An Efficient Methode for Online Calculation of Photolysis and
- ! Heating Rates, J. Atmos. Sci., 55, 863-878
- !
- ! Expanded for high angles and online:
- ! J.E.Williams, J. Landgraf, B. Bregman and H. H. Walter, A modified band
- ! approach for the accurate calculation of online photolysis rates in
- ! stratospheric-tropospheric Chemistry Transport Models, Atms. Chem. Phys.,
- ! 6, 4137-4161, 2006.
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE PHOTORATES_TROPO(region, zangle, cst_o3_col, cst_no2_col, cst_hno3_col, cst_h2o2_col, &
- cst_ch2o_col, cst_n2o5_col, cst_pan_col, cst_no3_col, qy_no2_col, qy_o1d_col, &
- qy_ch3cocho_col, fact, fdir, rj, debug_flag)
- !
- ! !USES:
- !
- use Dims, only : im, jm, lm, idate
- use global_data, only : mass_dat
- !
- ! !INPUT PARAMETERS:
- !
- integer, intent(in) :: region
- real, intent(in) :: zangle
- real,dimension(lm(region),nbands_trop), intent(in) :: fact !actinic flux
- real,dimension(lm(region),maxw), intent(in) :: fdir !flux o2-o3 abs.
- logical, intent(in) :: debug_flag
- real,dimension(lm(region),maxwav), intent(in) :: cst_o3_col
- real,dimension(lm(region),89), intent(in) :: cst_no2_col, qy_no2_col
- real,dimension(lm(region),65), intent(in) :: cst_hno3_col, qy_o1d_col
- real,dimension(lm(region),55), intent(in) :: cst_n2o5_col
- real,dimension(lm(region),45), intent(in) :: cst_h2o2_col
- real,dimension(lm(region),105), intent(in) :: cst_ch2o_col
- real,dimension(lm(region),65), intent(in) :: cst_pan_col
- real,dimension(lm(region),62), intent(in) :: cst_no3_col
- real,dimension(lm(region),52), intent(in) :: qy_ch3cocho_col
- !
- ! !OUTPUT PARAMETERS:
- !
- real,dimension(lm(region),nj), intent(out) :: rj !photolysis rates
- !
- ! !REVISION HISTORY:
- !
- !EOP
- !------------------------------------------------------------------------
- !BOC
- real,dimension(nbands_trop) :: bjo1d, bjno2, bjhno3, bjcoh2, bjchoh, bjn2o5, bjhno4, bjpan, &
- bjno2o,bjnoo2, bjh2o2, bjch3ooh,bjald2,bjch3o2co,bjch3cocho,bjch3ono2,bjo2
- !=================================================================================================
- !First tropospheric band is temperature independent for H2O2.N2O5,HCHO and NO2 therefore remove from large temp dep. arrays.
- real,dimension(17) :: cs_h2o2, cs_n2o5,cs_ch2o,cs_no2, cs_o2
- data cs_h2o2 /4.34E-19, 4.07E-19, 3.85E-19, 3.63E-19, 3.41E-19, 3.18E-19, 2.95E-19, &
- 2.72E-19, 2.50E-19, 2.30E-19, 2.10E-19, 1.92E-19, 1.74E-19, 1.57E-19, &
- 1.41E-19, 1.26E-19, 1.13E-19/
- data cs_n2o5 /8.049E-18, 7.208E-18, 6.212E-18, 4.853E-18, 3.925E-18, 3.248E-18, 2.619E-18, &
- 2.087E-18, 1.661E-18, 1.349E-18, 1.131E-18, 9.549E-19, 8.353E-18, 7.427E-19, &
- 6.762E-19, 6.095E-19, 5.229E-19/
- data cs_ch2o /0.00E+00, 0.00E+00, 0.00E+00, 0.00E+00, 0.00E+00, 0.00E+00, 0.00E+00, &
- 0.00E+00, 0.00E+00, 0.00E+00, 0.00E+00, 1.844E-22, 3.311E-22, 3.198E-22, &
- 6.982E-22, 7.341E-22, 1.383E-21/
- data cs_o2 /7.448E-24, 7.322E-24, 7.002E-24, 6.608E-24, 6.118E-24, 5.736E-24, 5.302E-24,&
- 4.741E-24, 4.261E-24, 3.788E-24, 3.213E-24, 2.69E-24, 2.218E-24, 1.793E-24,&
- 1.384E-24, 1.054E-24, 6.318E-25/
- real,dimension(62) :: cs_hno4 !
- ! Reference : JPL 2006, 4-40
- data cs_hno4 /4.43E-18, 3.64E-18, 3.09E-18, 2.54E-18, 2.13E-18, 1.78E-18, 1.51E-18, &
- 1.30E-18, 1.13E-18, 1.01E-18, 9.07E-19, 8.33E-19, 7.65E-19, 7.06E-19, &
- 6.48E-19, 5.91E-19, 5.36E-19, 4.83E-19, 4.36E-19, 3.93E-19, 3.53E-19, &
- 3.10E-19, 2.69E-19, 2.31E-19, 1.96E-19, 1.61E-19, 1.27E-19, 9.53E-20, &
- 7.01E-20, 4.93E-20, 3.31E-20, 2.14E-20, 1.60E-20, 1.40E-20, 1.30E-20, &
- 1.20E-20, 1.10E-20, 1.00E-20, 9.00E-21, 8.20E-21, 7.40E-21, 6.60E-21, &
- 5.80E-21, 5.00E-21, 4.60E-21, 4.20E-21, 3.80E-21, 3.40E-21, 3.00E-21, &
- 2.80E-21, 2.60E-21, 2.40E-21, 2.20E-21, 2.00E-21, 1.80E-21, 1.50E-21, &
- 1.10E-21, 7.00E-22, 0.00E+00, 0.00E+00, 0.00E+00, 0.00E+00/
- real, dimension(89) :: cs_ch3ooh
- ! Reference : JPL 2011, D9
- data cs_ch3ooh / 2.782E-19, 2.782E-19, 2.782E-19, 2.782E-19, 2.782E-19, 2.316E-19, 1.956E-19, &
- 1.696E-19, 1.476E-19, 1.318E-19, 1.169E-19, 1.036E-19, 9.132E-20, 8.045E-20, &
- 7.084E-20, 6.199E-20, 5.483E-20, 4.808E-20, 4.260E-20, 3.744E-20, 3.263E-20, &
- 2.819E-20, 2.431E-20, 2.119E-20, 1.827E-20, 1.569E-20, 1.338E-20, 1.107E-20, &
- 9.226E-21, 7.677E-21, 6.358E-21, 5.152E-21, 4.406E-21, 4.130E-21, 3.930E-21, &
- 3.730E-21, 3.530E-21, 3.330E-21, 3.130E-21, 2.982E-21, 2.834E-21, 2.686E-21, &
- 2.538E-21, 2.390E-21, 2.276E-21, 2.162E-21, 2.048E-21, 1.934E-21, 1.820E-21, &
- 1.730E-21, 1.640E-21, 1.550E-21, 1.460E-21, 1.370E-21, 1.306E-21, 1.210E-21, &
- 1.082E-21, 9.720E-22, 7.900E-22, 6.100E-22, 4.700E-22, 3.500E-22, 2.700E-22, &
- 2.100E-22, 1.600E-22, 1.200E-22, 7.500E-23, 5.200E-23, 4.000E-23, 4.050E-23, &
- 4.100E-23, 1.000E-23, 6.000E-24, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, &
- 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, &
- 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00/
- real, dimension(120) :: cs_ch3cocho
- ! Reference : JPL 2006, P 4-71
- data cs_ch3cocho /2.280E-19, 1.489E-19, 9.624E-20, 6.968E-20, 5.036E-20, 3.627E-20, 2.581E-20, &
- 1.729E-20, 1.440E-20, 1.435E-20, 1.460E-20, 1.521E-20, 1.619E-20, 1.743E-20, &
- 1.908E-20, 2.036E-20, 2.207E-20, 2.312E-20, 2.509E-20, 2.697E-20, 2.807E-20, &
- 3.175E-20, 3.343E-20, 3.580E-20, 4.070E-20, 4.234E-20, 4.473E-20, 4.906E-20, &
- 4.782E-20, 4.712E-20, 4.813E-20, 4.120E-20, 3.760E-20, 3.690E-20, 3.700E-20, &
- 3.740E-20, 3.740E-20, 3.620E-20, 3.380E-20, 3.150E-20, 2.920E-20, 2.710E-20, &
- 2.520E-20, 2.340E-20, 2.180E-20, 2.060E-20, 1.970E-20, 1.900E-20, 1.860E-20, &
- 1.860E-20, 1.870E-20, 1.820E-20, 1.680E-20, 1.500E-20, 1.340E-20, 1.180E-20, &
- 9.670E-21, 8.110E-21, 6.470E-21, 4.950E-21, 3.220E-21, 2.950E-21, 3.850E-21, &
- 5.560E-21, 7.650E-21, 1.080E-20, 1.470E-20, 1.900E-20, 2.420E-20, 3.200E-20, &
- 4.030E-20, 4.670E-20, 5.620E-20, 6.920E-20, 8.520E-20, 9.690E-20, 1.020E-19, &
- 1.030E-19, 1.040E-19, 1.080E-19, 9.940E-20, 9.620E-20, 8.680E-20, 3.690E-20, &
- 9.140E-21, 2.680E-21, 1.080E-21, 6.270E-22, 3.920E-22, 2.430E-22, 1.740E-22, &
- 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, &
- 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, &
- 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, &
- 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, &
- 0.000E+00/
- real,dimension(62) :: cs_orgn
- ! Reference : average 1-C4H9ONO2 & 2-C4H9ONO2 (IUPAC data sheet P18 and P19)
- ! JEW: The absorption spectrum of 2-C4H9ONO2 is mirrored around the maxiumum.
- data cs_orgn / 5.250E-018, 4.398E-018, 3.609E-018, 2.804E-018, 2.172E-018, 1.595E-018, 1.130E-018, &
- 7.710E-019, 5.025E-019, 3.714E-019, 2.623E-019, 1.900E-019, 1.342E-019, 9.905E-020, &
- 7.285E-020, 5.245E-020, 4.052E-020, 3.110E-020, 2.806E-020, 5.649E-020, 5.136E-020, &
- 4.886E-020, 4.635E-020, 4.358E-020, 3.970E-020, 3.610E-020, 3.247E-020, 2.784E-020, &
- 2.308E-020, 1.846E-020, 1.401E-020, 9.810E-021, 7.430E-021, 6.550E-021, 6.080E-021, &
- 5.610E-021, 5.140E-021, 4.670E-021, 4.200E-021, 3.840E-021, 3.480E-021, 3.120E-021, &
- 2.760E-021, 2.400E-021, 2.170E-021, 1.940E-021, 1.710E-021, 1.480E-021, 1.250E-021, &
- 1.131E-021, 1.012E-021, 8.930E-022, 7.740E-022, 2.550E-022, 2.350E-022, 2.050E-022, &
- 1.650E-022, 1.400E-022, 1.050E-022, 8.000E-023, 0.000E+000, 0.000E+000/
- real, dimension(89) :: cs_ald2
- ! Reference : average CH3CHO & C2H5CHO (JPL and IUPAC data sheet, respectively)
- data cs_ald2 /5.211E-022, 5.133E-022, 5.163E-022, 5.272E-022, 5.526E-022, 5.837E-022, 6.266E-022, &
- 6.774E-022, 7.498E-022, 8.806E-022, 1.054E-021, 1.387E-021, 1.849E-021, 2.472E-021, &
- 3.444E-021, 4.679E-021, 6.217E-021, 8.229E-021, 1.074E-020, 1.376E-020, 1.729E-020, &
- 2.131E-020, 2.584E-020, 3.082E-020, 3.565E-020, 4.055E-020, 4.482E-020, 4.809E-020, &
- 5.184E-020, 5.155E-020, 5.245E-020, 4.795E-020, 4.640E-020, 4.600E-020, 4.540E-020, &
- 4.465E-020, 4.330E-020, 4.085E-020, 3.870E-020, 3.730E-020, 3.585E-020, 3.490E-020, &
- 3.380E-020, 3.265E-020, 3.145E-020, 3.015E-020, 2.895E-020, 2.750E-020, 2.485E-020, &
- 2.235E-020, 2.125E-020, 1.990E-020, 1.869E-020, 1.777E-020, 1.631E-020, 1.471E-020, &
- 1.254E-020, 1.014E-020, 6.315E-021, 3.375E-021, 1.525E-021, 2.300E-022, 9.000E-023, &
- 3.000E-023, 1.500E-023, 0.000E+000, 0.000E+000, 0.000E+000, 0.000E+000, 0.000E+000, &
- 0.000E+000, 0.000E+000, 0.000E+000, 0.000E+000, 0.000E+000, 0.000E+000, 0.000E+000, &
- 0.000E+000, 0.000E+000, 0.000E+000, 0.000E+000, 0.000E+000, 0.000E+000, 0.000E+000, &
- 0.000E+000, 0.000E+000, 0.000E+000, 0.000E+000, 0.000E+000/
- !==========================================================================================================
- ! Similar procedure for quantum yields for : HCHO and NO3. A quantum yield of 0.8 is adopted for JN2O5 below 305nm
- ! as recommended in JPL 2006 - JEW 2009
- real,dimension(90) :: qyh_hco,qyh2_co
- real,dimension(62) :: qyno2_o,qyno_o2
- data qyh_hco /0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, &
- 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, &
- 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 3.087E-01, 3.087E-01, 3.030E-01, &
- 3.113E-01, 3.325E-01, 3.649E-01, 4.059E-01, 4.535E-01, 5.061E-01, 5.611E-01, &
- 6.159E-01, 6.662E-01, 7.097E-01, 7.418E-01, 7.550E-01, 7.580E-01, 7.610E-01, &
- 7.620E-01, 7.620E-01, 7.620E-01, 7.600E-01, 7.580E-01, 7.540E-01, 7.490E-01, &
- 7.440E-01, 7.370E-01, 7.290E-01, 7.200E-01, 7.090E-01, 6.980E-01, 6.850E-01, &
- 6.710E-01, 6.560E-01, 6.390E-01, 6.220E-01, 6.030E-01, 5.830E-01, 5.500E-01, &
- 5.020E-01, 4.490E-01, 3.430E-01, 1.650E-01, 0.000E+00, 0.000E+00, 0.000E+00, &
- 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, &
- 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, &
- 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, &
- 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00/ !(JPL 2006, p4-47)
- data qyh2_co /0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, &
- 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, &
- 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 4.913E-01, 4.913E-01, 4.970E-01, &
- 4.887E-01, 4.697E-01, 4.546E-01, 4.313E-01, 4.020E-01, 3.682E-01, 3.440E-01, &
- 3.152E-01, 2.922E-01, 2.662E-01, 2.547E-01, 2.450E-01, 2.420E-01, 2.390E-01, &
- 2.380E-01, 2.380E-01, 2.380E-01, 2.400E-01, 2.420E-01, 2.460E-01, 2.510E-01, &
- 2.560E-01, 2.630E-01, 2.710E-01, 2.800E-01, 2.910E-01, 3.020E-01, 3.150E-01, &
- 3.290E-01, 3.440E-01, 3.610E-01, 3.780E-01, 3.970E-01, 4.170E-01, 4.500E-01, &
- 4.980E-01, 5.510E-01, 6.570E-01, 7.350E-01, 6.500E-01, 5.000E-01, 3.800E-01, &
- 2.200E-01, 4.000E-03, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, &
- 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, &
- 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, &
- 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00, 0.000E+00/
- data qyno2_o /0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, &
- 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, &
- 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 1.00, &
- 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, &
- 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, &
- 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, &
- 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, &
- 1.00, 0.83, 0.65, 0.58, 0.51, 0.43, 0.36, &
- 0.29, 0.22, 0.14, 0.07, 0.0, 0.0/
- data qyno_o2 /0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, &
- 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, &
- 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, &
- 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, &
- 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, &
- 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, &
- 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, &
- 0.0, 0.18, 0.35, 0.31, 0.27, 0.23, 0.19, &
- 0.16, 0.12, 0.08, 0.04, 0.0, 0.0/
- !========================================================================================================
- integer :: i, j, l, k, c
- real :: delta1, delta2, delta3, delta4, delta5, delta6, delta7, delta1_spec, delta3_spec
- integer, dimension(7) :: band_start, band_middle, band_end
- logical :: daylight
- ! ==============================================================
- ! CALCULATION PHOTOLYSIS RATES FOR SCATTERING ATMOSPHERE
- ! ==============================================================
- ! the check for daylight is skipped as the calculation of rj is only called within the photo_flux loop
- ! where a filter already applies
- rj(:,:) = 0.
-
- ! choose the grid settings dependent on the SZA for the column
- if(zangle<=71.) then
- band_start(:)=lini(:)
- band_middle(:)=lmid(:)
- band_end(:)=lfin(:)
- elseif(zangle>71. .and. zangle<=sza_limit) then
- band_start(:)=lini_gridA(:)
- band_middle(:)=lmid_gridA(:)
- band_end(:)=lfin_gridA(:)
- endif
- do k = 1,lm(region)
- ! re-initialize bj values
- do l = 1,nbands_trop
- bjo1d(l) = 0.0
- bjno2(l) = 0.0
- bjhno3(l) = 0.0
- bjcoh2(l) = 0.0
- bjchoh(l) = 0.0
- bjn2o5(l) = 0.0
- bjhno4(l) = 0.0
- bjno2o(l) = 0.0
- bjnoo2(l) = 0.0
- bjh2o2(l) = 0.0
- bjch3ooh(l) = 0.0
- bjpan(l) = 0.0
- bjald2(l) = 0.0
- bjch3cocho(l) = 0.0
- bjch3ono2(l) = 0.0
- bjo2(l) = 0.0
- end do
- !==============================================================================================
- ! re-initialize the temporary arrays for the next layer
- !===============================================================================================
- delta1 = 0. ; delta2 = 0. ;delta3 = 0. ; delta4 = 0. ; delta5 = 0. ; delta6 = 0. ; delta7 = 0.
- delta1_spec = 0. ; delta3_spec = 0.
- ! =====================================================================================
- ! Tropo band 1
- ! =====================================================================================
- ! temp indep species for this band: no2,h2o2,n2o5,hno4,ch2o,ch3ooh,ald2,orgntr
- do l = band_start(1),band_end(1)
- bjo1d(1) = bjo1d(1) + cst_o3_col(k,l)*qy_o1d_col(k,l)*fdir(k,l)
- bjno2(1) = bjno2(1) + cst_no2_col(k,l)*qy_no2_col(k,l)*fdir(k,l)
- bjh2o2(1) = bjh2o2(1) + cs_h2o2(l)*fdir(k,l)
- bjhno3(1) = bjhno3(1) + cst_hno3_col(k,l)*fdir(k,l)
- bjhno4(1) = bjhno4(1) + cs_hno4(l)*fdir(k,l)
- bjn2o5(1) = bjn2o5(1) + 0.8*cs_n2o5(l)*fdir(k,l)
- bjchoh(1) = bjchoh(1) + cs_ch2o(l)*qyh_hco(l)*fdir(k,l)
- bjch3ooh(1) = bjch3ooh(1) + cs_ch3ooh(l)*fdir(k,l)
- bjald2(1) = bjald2(1) + cs_ald2(l)*fdir(k,l)
- bjpan(1) = bjpan(1) + cst_pan_col(k,l)*fdir(k,l)
- bjch3ono2(1) = bjch3ono2(1) + cs_orgn(l) * fdir(k,l)
- bjo2(1) = bjo2(1) + cs_o2(l) * fdir(k,l)
- end do
- ! =====================================================================================
- ! Tropo band 2
- ! =====================================================================================
- ! temp indep species for this band: hno4,ch3ooh,ald2,orgntr
- do l = band_start(2),band_end(2) ! temp indep for : no2,hno4,ch2o,ch3ooh,orgntr
- bjo1d(2) = bjo1d(2) + cst_o3_col(k,l)*qy_o1d_col(k,l)*fdir(k,l)
- bjno2(2) = bjno2(2) + cst_no2_col(k,l)*qy_no2_col(k,l)*fdir(k,l)
- bjh2o2(2) = bjh2o2(2) + cst_h2o2_col(k,l-17)*fdir(k,l)
- bjhno3(2) = bjhno3(2) + cst_hno3_col(k,l)*fdir(k,l)
- bjhno4(2) = bjhno4(2) + cs_hno4(l)*fdir(k,l)
- bjn2o5(2) = bjn2o5(2) + 0.8*cst_n2o5_col(k,l-17)*fdir(k,l)
- bjcoh2(2) = bjcoh2(2) + cst_ch2o_col(k,l-17)*qyh2_co(l)*fdir(k,l)
- bjchoh(2) = bjchoh(2) + cst_ch2o_col(k,l-17)*qyh_hco(l)*fdir(k,l)
- bjch3ooh(2) = bjch3ooh(2) + cs_ch3ooh(l)*fdir(k,l)
- bjpan(2) = bjpan(2) + cst_pan_col(k,l)*fdir(k,l)
- bjald2(2) = bjald2(2) + cs_ald2(l)* fdir(k,l)
- bjch3cocho(2) = bjch3cocho(2) + cs_ch3cocho(l)*fdir(k,l)
- bjch3ono2(2) = bjch3ono2(2) + cs_orgn(l) * fdir(k,l)
- end do
- ! =======================================================================================
- ! Tropo band 3
- ! =======================================================================================
- ! temp indep species for this band: hno4,ch3ooh,ald2,mgly,orgntr
- do l = band_start(3),band_end(3)
- bjo1d(3) = bjo1d(3) + cst_o3_col(k,l)*qy_o1d_col(k,l)*fdir(k,l)
- bjno2(3) = bjno2(3) + cst_no2_col(k,l)*qy_no2_col(k,l)*fdir(k,l)
- bjh2o2(3) = bjh2o2(3) + cst_h2o2_col(k,l-17)*fdir(k,l)
- bjhno3(3) = bjhno3(3) + cst_hno3_col(k,l)*fdir(k,l)
- bjhno4(3) = bjhno4(3) + cs_hno4(l)*fdir(k,l)
- bjn2o5(3) = bjn2o5(3) + 0.8*cst_n2o5_col(k,l-17)*fdir(k,l)
- bjcoh2(3) = bjcoh2(3) + cst_ch2o_col(k,l-17)*qyh2_co(l)*fdir(k,l)
- bjchoh(3) = bjchoh(3) + cst_ch2o_col(k,l-17)*qyh_hco(l)*fdir(k,l)
- bjch3ooh(3) = bjch3ooh(3) + cs_ch3ooh(l)*fdir(k,l)
- bjpan(3) = bjpan(3) + cst_pan_col(k,l)*fdir(k,l)
- bjald2(3) = bjald2(3) + cs_ald2(l)*fdir(k,l)
- bjch3cocho(3) = bjch3cocho(3) + cs_ch3cocho(l)*fdir(k,l)
- bjch3ono2(3) = bjch3ono2(3) + cs_orgn(l)*fdir(k,l)
- end do
- ! ================================================================================
- ! Tropo band 4
- ! ================================================================================
- ! temp indep species for this band: hno4,ch3ooh,ald2,orgntr
- do l = band_start(4),band_end(4)
- bjo1d(4) = bjo1d(4)+cst_o3_col(k,l)*qy_o1d_col(k,l)*fdir(k,l)
- bjno2(4) = bjno2(4) + cst_no2_col(k,l)*qy_no2_col(k,l)*fdir(k,l)
- bjh2o2(4) = bjh2o2(4) + cst_h2o2_col(k,l-17)*fdir(k,l)
- bjhno3(4) = bjhno3(4) + cst_hno3_col(k,l)*fdir(k,l)
- bjhno4(4) = bjhno4(4) + cs_hno4(l)*fdir(k,l)
- bjn2o5(4) = bjn2o5(4) + cst_n2o5_col(k,l-17)*fdir(k,l)
- bjcoh2(4) = bjcoh2(4) + cst_ch2o_col(k,l-17)*qyh2_co(l)*fdir(k,l)
- bjchoh(4) = bjchoh(4) + cst_ch2o_col(k,l-17)*qyh_hco(l)*fdir(k,l)
- bjch3ooh(4) = bjch3ooh(4) + cs_ch3ooh(l)*fdir(k,l)
- bjpan(4) = bjpan(4) + cst_pan_col(k,l)*fdir(k,l)
- bjald2(4) = bjald2(4) + cs_ald2(l)*fdir(k,l)
- bjch3cocho(4) = bjch3cocho(4) + cs_ch3cocho(l)*qy_ch3cocho_col(k,l-37)*fdir(k,l)
- bjch3ono2(4) = bjch3ono2(4) + cs_orgn(l)*fdir(k,l)
- end do
- ! ========================================================================================
- ! Tropo band 5
- ! ========================================================================================
- ! temp indep species for this band: hno4,ch3ooh,ald2,orgntr
- do l = band_start(5),band_end(5)
- bjo1d(5) = bjo1d(5)+cst_o3_col(k,l)*qy_o1d_col(k,l)*fdir(k,l)
- bjno2(5) = bjno2(5)+cst_no2_col(k,l)*qy_no2_col(k,l)*fdir(k,l)
- bjh2o2(5) = bjh2o2(5)+cst_h2o2_col(k,l-17)*fdir(k,l)
- bjhno3(5) = bjhno3(5)+cst_hno3_col(k,l)*fdir(k,l)
- bjhno4(5) = bjhno4(5)+cs_hno4(l)*fdir(k,l)
- bjn2o5(5) = bjn2o5(5)+cst_n2o5_col(k,l-17)*fdir(k,l)
- bjcoh2(5) = bjcoh2(5)+cst_ch2o_col(k,l-17)*qyh2_co(l)*fdir(k,l)
- bjchoh(5) = bjchoh(5)+cst_ch2o_col(k,l-17)*qyh_hco(l)*fdir(k,l)
- bjch3ooh(5) = bjch3ooh(5)+cs_ch3ooh(l)*fdir(k,l)
- bjpan(5) = bjpan(5)+cst_pan_col(k,l)*fdir(k,l)
- bjald2(5) = bjald2(5)+cs_ald2(l)* fdir(k,l)
- bjch3cocho(5) = bjch3cocho(5)+cs_ch3cocho(l)*qy_ch3cocho_col(k,l-37)*fdir(k,l)
- bjch3ono2(5) = bjch3ono2(5)+cs_orgn(l)*fdir(k,l)
- end do
- !=========================================================================================
- ! Tropo band 6
- !=========================================================================================
- do l = band_start(6),band_end(6)
- bjno2(6) = bjno2(6) +cst_no2_col(k,l)*qy_no2_col(k,l)*fdir(k,l)
- bjcoh2(6) = bjcoh2(6)+cst_ch2o_col(k,l-17)*qyh2_co(l)*fdir(k,l)
- bjch3ooh(6) = bjch3ooh(6)+cs_ch3ooh(l)*fdir(k,l)
- bjno2o(6) = bjno2o(6)+cst_no3_col(k,l-60)*qyno2_o(l-60)*fdir(k,l)
- bjch3cocho(6) = bjch3cocho(6)+cs_ch3cocho(l)*qy_ch3cocho_col(k,l-37)*fdir(k,l)
- end do
- ! Add the contribution from band 6 separately for H2O2, N2O5 and HNO3 for high angle grid to allow reducion in cst arrays
- ! This has been tested using a box model to ensure that no errors are introduced compared to using main array
- if(zangle>71.) then
- bjh2o2(6) = bjh2o2(6)+cst_h2o2_col(k,44)*fdir(k,61)
- bjh2o2(6) = bjh2o2(6)+cst_h2o2_col(k,45)*fdir(k,62)
- do c=63,68
- bjn2o5(6) = bjn2o5(6)+cst_n2o5_col(k,c-17)*fdir(k,c)
- enddo
- bjhno3(6) = bjhno3(6)+cst_hno3_col(k,63)*fdir(k,63)
- bjpan(6) = 0.
- elseif(zangle<=71.) then
- do c=61,63
- bjhno3(6) = bjhno3(6)+cst_hno3_col(k,c)*fdir(k,c)
- enddo
- do c=61,69
- bjn2o5(6) = bjn2o5(6)+cst_n2o5_col(k,c-17)*fdir(k,c)
- enddo
- do c=61,62
- bjpan(6) = bjpan(6)+cst_pan_col(k,c)*fdir(k,c)
- enddo
- endif
- !========================================================================================
- ! Tropo band 7
- !=========================================================================================
- do l = band_start(7),band_end(7)-2
- bjno2o(7) = bjno2o(7)+cst_no3_col(k,l-60)*qyno2_o(l-60)*fdir(k,l)
- bjnoo2(7) = bjnoo2(7)+cst_no3_col(k,l-60)*qyno_o2(l-60)*fdir(k,l)
- end do
- ! only set a scaling ratio for the first band once the sza > 71.
- ! only calculate limits to bands 2 and 4 for high sza
- if(zangle<=71.) then
- delta1 = fact(k,1)/fdir(k,band_middle(1))
- delta2 = fact(k,2)/fdir(k,band_middle(2))
- delta3 = fact(k,3)/fdir(k,band_middle(3))
- delta4 = fact(k,4)/fdir(k,band_middle(4))
- delta5 = fact(k,5)/fdir(k,band_middle(5))
- delta6 = fact(k,6)/fdir(k,band_middle(6))
- delta7 = fact(k,7)/fdir(k,band_middle(7))
- elseif(zangle>71. .and. zangle<=sza_limit) then
- delta1 = safe_div( fact(k,1), fdir(k,band_middle(1)), huge(1.))
- delta2 = safe_div( fact(k,2), fdir(k,band_middle(2)), huge(1.))
- delta3 = safe_div( fact(k,3), fdir(k,band_middle(3)), huge(1.))
- delta4 = safe_div( fact(k,4), fdir(k,band_middle(4)), huge(1.))
- delta5 = safe_div( fact(k,5), fdir(k,band_middle(5)), huge(1.))
- delta6 = safe_div( fact(k,6), fdir(k,band_middle(6)), huge(1.))
- delta7 = safe_div( fact(k,7), fdir(k,band_middle(7)), huge(1.))
- if(fdir(k,band_middle(1))>5.e9) delta1_spec = fact(k,1)/fdir(k,band_middle(1))
- if(fdir(k,band_middle(3))>1.e9) delta3_spec = fact(k,3)/fdir(k,band_middle(3))
- endif
- ! ============================================================
- ! CALCULATION PHOTOLYSIS RATES FOR SCATTERING ATMOSPHERE
- ! ============================================================
- ! O2 -> O3P
- rj(k,jo2) = bjo2(1)*delta1
- ! O3 -> 2OH
- rj(k,jo3d) = bjo1d(1)*delta1 + bjo1d(2)*delta2 &
- + bjo1d(3)*delta3 + bjo1d(4)*delta4 &
- + bjo1d(5)*delta5
- ! NO2 -> O3
- rj(k,jno2) = bjno2(1)*delta1 + bjno2(2)*delta2 + &
- bjno2(3)*delta3 + bjno2(4)*delta4 + &
- bjno2(5)*delta5 + bjno2(6)*delta6
- ! HNO3 -> OH + NO2
- rj(k,jhno3) = bjhno3(1)*delta1 + bjhno3(2)*delta2 + &
- bjhno3(3)*delta3 + bjhno3(4)*delta4 + &
- bjhno3(5)*delta5 + bjhno3(6)*delta6
- ! HNO4 -> HO2 + NO2
- rj(k,jhno4) = bjhno4(1)*delta1 + bjhno4(2)*delta2 + &
- bjhno4(3)*delta3 + bjhno4(4)*delta4 + &
- bjhno4(5)*delta5
- ! N2O5 -> NO2 + NO2
- rj(k,jn2o5) = bjn2o5(1)*delta1 + bjn2o5(2)*delta2 + &
- bjn2o5(3)*delta3 + bjn2o5(4)*delta4 + &
- bjn2o5(5)*delta5 + bjn2o5(6)*delta6
- ! PAN (QY = 1) -> NO2 + C2O3
- rj(k,jpan) = bjpan(1)*delta1 + bjpan(2)*delta2 + &
- bjpan(3)*delta3 + bjpan(4)*delta4 + &
- bjpan(5)*delta5 + bjpan(6)*delta6
- ! CH2O -> CO
- rj(k,jach2o) = bjcoh2(2)*delta2 + bjcoh2(3)*delta3 &
- + bjcoh2(4)*delta4 + bjcoh2(5)*delta5 &
- + bjcoh2(6)*delta6
- ! CH2O -> COH + H
- rj(k,jbch2o) = bjchoh(1)*delta1 + bjchoh(2)*delta2 &
- + bjchoh(3)*delta3 + bjchoh(4)*delta4 &
- + bjchoh(5)*delta5 + bjchoh(6)*delta6
- ! H2O2 -> 2OH
- rj(k,jh2o2) = bjh2o2(1)*delta1 + bjh2o2(2)*delta2 &
- + bjh2o2(3)*delta3 + bjh2o2(4)*delta4 &
- + bjh2o2(5)*delta5 + bjh2o2(6)*delta6
- ! NO3 -> NO2 + O
- rj(k,jano3) = bjno2o(6)*delta6 + bjno2o(7)*delta7
- ! NO3 -> NO
- rj(k,jbno3) = bjnoo2(7)*delta7
- ! CH3OOH -> HCHO + HO2 + OH
- rj(k,jmepe) = bjch3ooh(1)*delta1 + bjch3ooh(2)*delta2 + &
- bjch3ooh(3)*delta3 + bjch3ooh(4)*delta4 + &
- bjch3ooh(5)*delta5 + bjch3ooh(6)*delta6
- ! ALD2 -> HCHO + XO2 + CO + 2HO2
- rj(k,j45) = bjald2(1)*delta1 + bjald2(2)*delta2 &
- + bjald2(3)*delta3 + bjald2(4)*delta4 &
- + bjald2(5)*delta5
- ! CH3ONO2 -> HO2 + NO2
- rj(k,jorgn) = bjch3ono2(1)*delta1 + bjch3ono2(2)*delta2 + &
- bjch3ono2(3)*delta3 + bjch3ono2(4)*delta4 + &
- bjch3ono2(5)*delta5
- ! CH3COCHO -> C2O3 + HO2 + CO
- rj(k,j74) = bjch3cocho(2)*delta2 + bjch3cocho(3)*delta3 + &
- bjch3cocho(4)*delta4 + bjch3cocho(5)*delta5 + &
- bjch3cocho(6)*delta6 + bjch3cocho(7)*delta7
- if(zangle>80. .and. zangle<=85.) then
-
- rj(k,jo3d) = 0. ; rj(k,jhno3) = 0. ; rj(k,jhno4) = 0. ; rj(k,jn2o5) = 0.
- rj(k,jh2o2) = 0. ; rj(k,jach2o) = 0. ; rj(k,jbch2o) = 0.
- rj(k,jpan) = 0. ; rj(k,j45) = 0. ; rj(k,jorgn) = 0. ; rj(k,j74) = 0. ; rj(k,jo2) = 0.
- ! O2 -> 2O3P
- rj(k,jo2) = bjo2(1)*delta1_spec
- ! O3 -> O(1D) + O2
- rj(k,jo3d) = bjo1d(1)*delta1_spec + bjo1d(2)*delta2 + &
- bjo1d(3)*delta3_spec + bjo1d(4)*delta4 + &
- bjo1d(5)*delta5
- ! HNO3 -> OH + NO2
- rj(k,jhno3) = bjhno3(1)*delta1_spec + bjhno3(2)*delta2 + &
- bjhno3(3)*delta3_spec + bjhno3(4)*delta4 + &
- bjhno3(5)*delta5 + bjhno3(6)*delta6
- ! N2O5 -> NO2 + NO2
- rj(k,jn2o5) = bjn2o5(1)*delta1_spec + bjn2o5(2)*delta2 + &
- bjn2o5(3)*delta3_spec + bjn2o5(4)*delta4 + &
- bjn2o5(5)*delta5 + bjn2o5(6)*delta6
- ! PAN (QY = 1)
- rj(k,jpan) = bjpan(1)*delta1_spec + bjpan(2)*delta2 + &
- bjpan(3)*delta3_spec + bjpan(4)*delta4 + &
- bjpan(5)*delta5 + bjpan(6)*delta6
- ! ORGNTR -> HO2 + NO2
- rj(k,jorgn) = bjch3ono2(1)*delta1_spec + bjch3ono2(2)*delta2 + &
- bjch3ono2(3)*delta3_spec + bjch3ono2(4)*delta4 + &
- bjch3ono2(5)*delta5
- ! ALD2 -> HCHO + XO2 + CO + 2HO2
- rj(k,j45) = bjald2(1)*delta1_spec + bjald2(2)*delta2 + &
- bjald2(3)*delta3_spec + bjald2(4)*delta4 + &
- bjald2(5)*delta5
- ! NO2 -> O3
- rj(k,jno2) = bjno2(1)*delta1_spec + bjno2(2)*delta2 + &
- bjno2(3)*delta3_spec + bjno2(4)*delta4 + &
- bjno2(5)*delta5 + bjno2(6)*delta6
- ! CH2O -> CO
- rj(k,jach2o) = bjcoh2(2)*delta2 + bjcoh2(3)*delta3_spec + &
- bjcoh2(4)*delta4 + bjcoh2(5)*delta5 + &
- bjcoh2(6)*delta6
- ! CH2O -> COH + H
- rj(k,jbch2o) = bjchoh(1)*delta1_spec + bjchoh(2)*delta2 + &
- bjchoh(3)*delta3_spec + bjchoh(4)*delta4 + &
- bjchoh(5)*delta5 + bjchoh(6)*delta6
- rj(k,jhno4) = bjhno4(1)*delta1_spec + bjhno4(2)*delta2 + &
- bjhno4(3)*delta3_spec + bjhno4(4)*delta4 + &
- bjhno4(5)*delta5
- ! H2O2 -> 2OH
- rj(k,jh2o2) = bjh2o2(1)*delta1_spec + bjh2o2(2)*delta2 + &
- bjh2o2(3)*delta3_spec + bjh2o2(4)*delta4 + &
- bjh2o2(5)*delta5 + bjh2o2(6)*delta6
- ! CH3OOH -> HCHO + HO2 + OH
- rj(k,jmepe) = bjch3ooh(1)*delta1_spec + bjch3ooh(2)*delta2 + &
- bjch3ooh(3)*delta3_spec + bjch3ooh(4)*delta4 + &
- bjch3ooh(5)*delta5 + bjch3ooh(6)*delta6
- ! CH3COCHO -> C2O3 + HO2 + CO
- rj(k,j74) = bjch3cocho(2)*delta2 + bjch3cocho(3)*delta3_spec + &
- bjch3cocho(4)*delta4 + bjch3cocho(5)*delta5 + &
- bjch3cocho(6)*delta6 + bjch3cocho(7)*delta7
- endif ! sza > 80.
- rj(k,jrooh) = rj(k,jmepe)
- enddo ! layers
- END SUBROUTINE PHOTORATES_TROPO
- !EOC
- !------------------------------------------------------------------------------
- ! TM5 !
- !------------------------------------------------------------------------------
- !BOP
- !
- ! !IROUTINE: PHOTOLYSIS_DONE
- !
- ! !DESCRIPTION: Deallocates photolysis data, and writes photolysis statistics:
- ! output (e.g. monthly) averaged photolysis jo3, jno2 and
- ! surface data of: albedo, cloud-cover, cloud optical thickness
- ! total ozone
- !\\
- !\\
- ! !INTERFACE:
- !
- SUBROUTINE PHOTOLYSIS_DONE( status )
- !
- ! !USES:
- !
- use dims, only : region_name, im, jm, lm
- use dims, only : idatei, idatee
- use global_data, only : outdir
- use file_hdf, only : THdfFile, TSds
- use file_hdf, only : Init, Done, WriteAttribute, Init, Done, WriteData
- use partools, only : isRoot
- !
- ! !OUTPUT PARAMETERS:
- !
- integer, intent(out) :: status
- !
- ! !REVISION HISTORY:
- ! 21 Mar 2012 - P. Le Sager - adapted for lon-lat MPI domain decomposition
- !
- ! !REMARKS:
- ! (1) Called from SOURCES_SINKS/TRACE_END
- !
- !EOP
- !------------------------------------------------------------------------------
- !BOC
- character(len=*), parameter :: rname = mname//'/end_photolysis'
- integer :: n
- integer :: k,iret,imr,jmr,lmr
- integer :: region
- real, allocatable :: average_field(:,:,:), average_field_2d(:,:), average_field_5d(:,:,:,:,:)
- type(THdfFile) :: io
- type(TSds) :: sds
- character(len=256) :: fname
- ! --- begin --------------------------------
- if (isRoot) then
- write (fname,'(a,"/j_statistics_",i4.4,3i2.2,"_",i4.4,3i2.2,".hdf")') &
- trim(outdir), idatei(1:4), idatee(1:4)
- call Init(io,fname,'create',status)
- IF_ERROR_RETURN(status=1)
- end if
-
- REG: do region=1,nregions
-
- if(isRoot) then
- imr=im(region)
- jmr=jm(region)
- lmr=lm(region)
- else
- imr=1; jmr=1; lmr=1
- end if
- allocate(average_field(imr,jmr,lmr))
- ! Assume that the nav is the same on all proc
- write (gol,*) 'end_photolysis: j_statistics ', &
- '(region, nj_av, nvo3s_av, ncloud_av)', region, &
- phot_dat(region)%nj_av, phot_dat(region)%nvo3s_av; call goPr
- !---- 3D fields
- if ( phot_dat(region)%nj_av > 0 ) then
- call gather(dgrid(region), phot_dat(region)%jo3_av, average_field, 0, status)
- if ( isRoot ) then
- average_field = average_field/phot_dat(region)%nj_av
- call Init(Sds,io,'jo3_av',(/imr,jmr,lmr/),'real(4)',status)
- IF_ERROR_RETURN(status=1)
- call WriteAttribute(Sds,'Unit','1/s',status)
- IF_ERROR_RETURN(status=1)
- call WriteData(Sds,average_field,status)
- IF_ERROR_RETURN(status=1)
- call Done(Sds,status)
- IF_ERROR_RETURN(status=1)
- end if
- call gather(dgrid(region), phot_dat(region)%jno2_av, average_field, 0, status)
- if ( isRoot ) then
- average_field = average_field/phot_dat(region)%nj_av
- call Init(Sds,io,'jno2_av',(/imr,jmr,lmr/),'real(4)',status)
- IF_ERROR_RETURN(status=1)
- call WriteAttribute(Sds,'Unit','1/s',status)
- IF_ERROR_RETURN(status=1)
- call WriteData(Sds,average_field,status)
- IF_ERROR_RETURN(status=1)
- call Done(Sds,status)
- IF_ERROR_RETURN(status=1)
- end if
- call gather(dgrid(region), phot_dat(region)%reff_av, average_field, 0, status)
- if ( isRoot ) then
- call Init(Sds,io,'reff_av',(/imr,jmr,lmr/),'real(4)',status)
- IF_ERROR_RETURN(status=1)
- call WriteAttribute(Sds,'Unit','um',status)
- IF_ERROR_RETURN(status=1)
- call WriteData(Sds,average_field,status)
- IF_ERROR_RETURN(status=1)
- call Done(Sds,status)
- IF_ERROR_RETURN(status=1)
- end if
- call gather(dgrid(region), phot_dat(region)%lwp_av, average_field, 0, status)
- if ( isRoot ) then
- call Init(Sds,io,'lwp_av',(/imr,jmr,lmr/),'real(4)',status)
- IF_ERROR_RETURN(status=1)
- call WriteAttribute(Sds,'Unit','g/m2',status)
- IF_ERROR_RETURN(status=1)
- call WriteData(Sds,average_field,status)
- IF_ERROR_RETURN(status=1)
- call Done(Sds,status)
- IF_ERROR_RETURN(status=1)
- end if
- end if
-
- ! ---- 2D fields
- if ( phot_dat(region)%nalb_av > 0 ) then
- allocate(average_field_2d(imr,jmr))
- call gather(dgrid(region), phot_dat(region)%ags_av, average_field_2d, 0, status)
- if(isRoot) then
- average_field_2d = average_field_2d / phot_dat(region)%nalb_av
- call Init(Sds,io,'ags_av',(/imr,jmr/),'real(4)',status)
- IF_ERROR_RETURN(status=1)
- call WriteAttribute(Sds,'Unit','Fraction',status)
- IF_ERROR_RETURN(status=1)
- call WriteData(Sds,average_field_2d,status)
- IF_ERROR_RETURN(status=1)
- call Done(Sds,status)
- IF_ERROR_RETURN(status=1)
- end if
- call gather(dgrid(region), phot_dat(region)%sza_av, average_field_2d, 0, status)
- if ( isRoot ) then
- average_field_2d = average_field_2d / phot_dat(region)%nalb_av
- call Init(Sds,io,'sza_av',(/imr,jmr/),'real(4)',status)
- IF_ERROR_RETURN(status=1)
- call WriteAttribute(Sds,'Unit','Zenith Angle',status)
- IF_ERROR_RETURN(status=1)
- call WriteData(Sds,average_field_2d,status)
- IF_ERROR_RETURN(status=1)
- call Done(Sds,status)
- IF_ERROR_RETURN(status=1)
- end if
- deallocate(average_field_2d)
- end if ! any 2D field
- ! Clouds data (3D)
- if ( phot_dat(region)%ncloud_av > 0 ) then
- call gather(dgrid(region), phot_dat(region)%pmcld_av, average_field, 0, status)
- if ( isRoot ) then
- average_field = average_field/phot_dat(region)%ncloud_av
- call Init(Sds,io,'pmcld_av',(/imr,jmr,lmr/),'real(4)',status)
- IF_ERROR_RETURN(status=1)
- call WriteAttribute(Sds,'Unit',' ',status)
- IF_ERROR_RETURN(status=1)
- call WriteData(Sds,average_field,status)
- IF_ERROR_RETURN(status=1)
- call Done(Sds,status)
- IF_ERROR_RETURN(status=1)
- endif
-
- call gather(dgrid(region), phot_dat(region)%taus_cld_av, average_field, 0, status)
- if ( isRoot ) then
- average_field = average_field/phot_dat(region)%ncloud_av
- call Init(Sds,io,'taus_cld_av',(/imr,jmr,lmr/),'real(4)',status)
- IF_ERROR_RETURN(status=1)
- call WriteAttribute(Sds,'Unit',' ',status)
- IF_ERROR_RETURN(status=1)
- call WriteData(Sds,average_field,status)
- IF_ERROR_RETURN(status=1)
- call Done(Sds,status)
- IF_ERROR_RETURN(status=1)
- end if
- call gather(dgrid(region), phot_dat(region)%taua_cld_av, average_field, 0, status)
- if ( isRoot ) then
- average_field = average_field/phot_dat(region)%ncloud_av
- call Init(Sds,io,'taua_cld_av',(/imr,jmr,lmr/),'real(4)',status)
- IF_ERROR_RETURN(status=1)
- call WriteAttribute(Sds,'Unit',' ',status)
- IF_ERROR_RETURN(status=1)
- call WriteData(Sds,average_field,status)
- IF_ERROR_RETURN(status=1)
- call Done(Sds,status)
- IF_ERROR_RETURN(status=1)
- end if
- end if
- ! Aerosols info (5D)
- if ( phot_dat(region)%naer_av > 0 ) then
- allocate(average_field_5d(imr,jmr,lmr,nbands_trop,ngrid))
- call gather(dgrid(region), phot_dat(region)%pmaer_av, average_field_5d, 0, status)
- if ( isRoot ) then
- average_field_5d = average_field_5d/phot_dat(region)%naer_av
- call Init(Sds,io,'pmaer_av',(/imr,jmr,lmr,nbands_trop,ngrid/),'real(4)',status)
- IF_ERROR_RETURN(status=1)
- call WriteAttribute(Sds,'Unit',' ',status)
- IF_ERROR_RETURN(status=1)
- call WriteData(Sds,average_field_5d,status)
- IF_ERROR_RETURN(status=1)
- call Done(Sds,status)
- IF_ERROR_RETURN(status=1)
- end if
- call gather(dgrid(region), phot_dat(region)%taus_aer_av, average_field_5d, 0, status)
- if ( isRoot ) then
- average_field_5d = average_field_5d/phot_dat(region)%naer_av
- call Init(Sds,io,'taus_aer_av',(/imr,jmr,lmr,nbands_trop,ngrid/),'real(4)',status)
- IF_ERROR_RETURN(status=1)
- call WriteAttribute(Sds,'Unit',' ',status)
- IF_ERROR_RETURN(status=1)
- call WriteData(Sds,average_field_5d,status)
- IF_ERROR_RETURN(status=1)
- call Done(Sds,status)
- IF_ERROR_RETURN(status=1)
- end if
- call gather(dgrid(region), phot_dat(region)%taua_aer_av, average_field_5d, 0, status)
- if ( isRoot ) then
- average_field_5d = average_field_5d/phot_dat(region)%naer_av
- call Init(Sds,io,'taua_aer_av',(/imr,jmr,lmr,nbands_trop,ngrid/),'real(4)',status)
- IF_ERROR_RETURN(status=1)
- call WriteAttribute(Sds,'Unit',' ',status)
- IF_ERROR_RETURN(status=1)
- call WriteData(Sds,average_field_5d,status)
- IF_ERROR_RETURN(status=1)
- call Done(Sds,status)
- IF_ERROR_RETURN(status=1)
- end if
-
- deallocate(average_field_5d)
- end if
- if ( phot_dat(region)%nsad_av >0 ) then
-
- call gather(dgrid(region), phot_dat(region)%sad_cld_av, average_field, 0, status)
-
- if ( isRoot ) then
- average_field = average_field/phot_dat(region)%nsad_av
- call Init(Sds,io,'sad_cld',(/imr,jmr,lmr/),'real(4)',status)
- IF_ERROR_RETURN(status=1)
- call WriteAttribute(Sds,'Unit','cm^2/cm^3 ',status)
- call WriteAttribute(Sds,'long_name','average water cloud surface area density',status)
- IF_ERROR_RETURN(status=1)
- call WriteData(Sds,average_field,status)
- IF_ERROR_RETURN(status=1)
- call Done(Sds,status)
- IF_ERROR_RETURN(status=1)
- endif
-
- call gather(dgrid(region), phot_dat(region)%sad_ice_av, average_field, 0, status)
-
- if ( isRoot ) then
- average_field = average_field/phot_dat(region)%nsad_av
- call Init(Sds,io,'sad_ice',(/imr,jmr,lmr/),'real(4)',status)
- IF_ERROR_RETURN(status=1)
- call WriteAttribute(Sds,'Unit','cm^2/cm^3 ',status)
- call WriteAttribute(Sds,'long_name','average ice cloud surface area density',status)
- IF_ERROR_RETURN(status=1)
- call WriteData(Sds,average_field,status)
- IF_ERROR_RETURN(status=1)
- call Done(Sds,status)
- IF_ERROR_RETURN(status=1)
- endif
-
- call gather(dgrid(region), phot_dat(region)%sad_aer_av, average_field, 0, status)
- if ( isRoot ) then
- average_field = average_field/phot_dat(region)%nsad_av
- call Init(Sds,io,'sad_aer',(/imr,jmr,lmr/),'real(4)',status)
- IF_ERROR_RETURN(status=1)
- call WriteAttribute(Sds,'Unit','cm^2/cm^3 ',status)
- call WriteAttribute(Sds,'long_name','average aerosol surface area density',status)
- IF_ERROR_RETURN(status=1)
- call WriteData(Sds,average_field,status)
- IF_ERROR_RETURN(status=1)
- call Done(Sds,status)
- IF_ERROR_RETURN(status=1)
- endif
- end if
-
- deallocate(average_field)
- end do REG
- if ( isRoot ) then
- call Done(io, status)
- IF_ERROR_RETURN(status=1)
- endif
-
- do region = 1,nregions
- if (associated( phot_dat(region)%o3klim_top)) deallocate(phot_dat(region)%o3klim_top )
- deallocate(phot_dat(region)%albedo )
- deallocate(phot_dat(region)%ags_av )
- deallocate(phot_dat(region)%sza_av )
- deallocate(phot_dat(region)%lwp_av )
- deallocate(phot_dat(region)%cfr_av )
- deallocate(phot_dat(region)%reff_av )
- deallocate(phot_dat(region)%aero_surface_clim)
- deallocate(phot_dat(region)%cloud_reff )
- deallocate(phot_dat(region)%pmcld )
- deallocate(phot_dat(region)%taus_cld )
- deallocate(phot_dat(region)%taua_cld )
- deallocate(phot_dat(region)%pmaer )
- deallocate(phot_dat(region)%taus_aer )
- deallocate(phot_dat(region)%taua_aer )
- deallocate(phot_dat(region)%pmcld_av )
- deallocate(phot_dat(region)%taus_cld_av)
- deallocate(phot_dat(region)%taua_cld_av)
- deallocate(phot_dat(region)%pmaer_av )
- deallocate(phot_dat(region)%taus_aer_av)
- deallocate(phot_dat(region)%taua_aer_av)
- deallocate(phot_dat(region)%jo3 )
- deallocate(phot_dat(region)%jno2 )
- deallocate(phot_dat(region)%jo3_av )
- deallocate(phot_dat(region)%jno2_av )
- deallocate(phot_dat(region)%v2 )
- deallocate(phot_dat(region)%v3 )
- deallocate(phot_dat(region)%v3_surf )
- deallocate(phot_dat(region)%qy_ch3cocho)
- deallocate(phot_dat(region)%sad_cld )
- deallocate(phot_dat(region)%sad_ice )
- deallocate(phot_dat(region)%sad_aer )
- deallocate(phot_dat(region)%sad_cld_av )
- deallocate(phot_dat(region)%sad_ice_av )
- deallocate(phot_dat(region)%sad_aer_av )
- end do
- #ifdef with_optics
- deallocate( wdep ) !NB optics_done
- #endif
- ! ok
- status = 0
- END SUBROUTINE PHOTOLYSIS_DONE
- !EOC
- END MODULE PHOTOLYSIS
|