GEOS Chem Adjoint V8 Flowchart descriptions of Inverse_driver.f Geos_chem_mod.f Chemistry_mod.f Chemdr.f Geos_chem_adj.f Jan/21, 2010 Meemong Lee
Shape & Color convention File Process Function calls Macro Operation IF branch Step1 Step2
Input.geos READ_INPUT_FILE Inverse_driver.f Input.gcadj READ_INPUT_ADJ_FILE Log_opt ITER N_CALC_STOP = ITER LOG_OPT? Y N SET_LOG_SF SET_SF INIT_SETULB INIT_INVERSE INIT_ADJ_ARRAYS Forward mode N_CALC_STOP == 0? N Y DO_GEOS_CHEM MAKE_SF_FILE N LADJ? Y Log_opt GET_X_FROM_SF Optimization Loop ITER = 0 : FWD only ITER = 1 : FWD + ADJ ITER >= 2 : Optimization loop + FWD + ADJ Optimization loop iterates ITER and increments it by one. CLOSE_FILES CLEANUP CLEANUP_ADJ ITER ITER = N_CALC_STOP +1
Optimization Loop ITERATE? SETULB N TASK == FG? LFDTEST && N_CALC > 1 SET_SF_FORFD N_CALC += 1 N_CALC == 1 Log_opt TASK == NEW_X? Y GET_SF_FROM_X N_CALC < N_CALC_STOP N SET_SF TASK == STOP? Y GET_SF_FROM_X DO_GEOS_CHEM Exit READ_GDT_FILE READ_CFN_FILE GET_GRADNT_FROM_ADJ!LFDTEST N_CALC_STOP == 1 N STT_ADJ_FD =ICS_SF_ADJ Y LFDTEST & LICS DO_GEOS_CHEM_ADJ STT_ADJ_FD STT_ADJ_FD =EMS_SF_ADJ Y LFDTEST & LADJ_EMS SET_OPT_RANGE MAKE_GDT_FILE MAKE_SF_FILE MAKE_CFN_FILE COST_FUNC_SAVE(N_CALC) = COST_FUNC MAKE_SAT_DIAG_FILE
DO_GEOS_CHEM
SET_DIRECTION(1) GEOS_Chem_mod.f INITIALIZE PROCESS OPEN/GET MET FIELDS AVGPOLE SET_FLOATING_PRESSURE AIRQNT RDLAND DO_PBL_MIX WRITE DIAGNOSTICS N LADJ Restart File READ MET FILES READ_RESTART_FILE Y DYNAMIC TIME STEP INIT_CHECKPT READ_RESTART_FILE APPLY_IC_SCALING Forward Loop ARCHIVE DIAGNSTICS COPY_I6_FIELDS CLEANUP & QUIT
INITIALIZE PROCESS INIT_DAO INITIALIZE(2) INITIALIZE(3) INIT_PRESSURE Step1!LVARTROP READ_TROPOPAUSE Step2 LEMIS LCHEM ITS_A_FULLCHEM _SIM INIT_COMOD ITS_A_AEROSOL_ SIM INIT_COMOD Step3!LADJ ITS_A_CH4_ SIM INIT_GLOBAL_CH4 Step4 LMEGAN INIT_MEGAN INITIALIZE(2) INITIALIZE(3)
READ MET FIELDS Step1 UNZIP && TIME_FOR_UNZIP UNZIP MET FIELDS Step2 UNZIP && TIME_FOR_DEL REMOVE MET FIELDS Step3 ITS_Time_FOR_A3 OPEN_A3_FIELDS_ADJ GET_A3_FIELDS Step4 ITS_Time_FOR_A6 OPEN_A6_FIELDS_ADJ READ_ A6_FIELDS_ADJ Step5 ITS_Time_FOR_I6 COPY_I6_FIELDS_ADJ OPEN_I6_FIELDS_ADJ GET_I6_FIELDS_1_ADJ Step6 LCHEM && NEW MONTH READ_UV_ALBEDO
DYNAMIC TIMESTEP Step1 FULL_CHEM_SIM TAGCO_SIM LEMIS && NEW_SEASON ANTHROEMS Step2 INTERPOLATE Step3 LUPBD DO_UPBDFLX Step4 DYNAMICS-FWD CONVECTION-FWD EMISSIONS-FWD Step5!LADJ && CH4_SIM CH4_AVGTP Step6 ITS_TIME_CHEM SET_CT_CHEM DO_CHEMISTRY Step7 LWETD && ITS_TIME_DYN DO_WETDEP Step8 LADJ DO_OUTPUT
Step1 NEW_DAY INTERPOLATE RDLAI LMEGAN RDISOLAI UPDATE_T_25_AVG Step2 INTERP FULL_CHEM H2HD_SIM RDSOIL Step3 LVARTROP CHECK_VAR_TROP Step4!LTRAN SET_FLOATING_PRESSURE Step5 AIRQNT COSSZA Step6 ND55 TROPOPAUSE Step7 SET_CT_DYN DIAG_2PM Step8 TIME_FOR_UNIT CONVERT_UNITS
DYNAMICS-FWD Transport Zme step = 30 ITS_Time_DYN LTRAN DO_TRANSPORT AIRQNT LUPBD && FULL_CHEM_SIM UPBDFLX_NOY(2) MAKE_RH LCONV LWETD LSULF INIT_WETSCAV
CONVECTION-FWD ConvecZon Zme step = 30 ITS_Time_CONV SET_CT_CONV DO_PBL_MIX LADJ Y CALL_CHK_CON_FILE LCONV Y DO_CONVECTION EMISSION-FWD Emission Zme step = 60 ITS_Time_EMIS SET_CT_CONV LDRYD && H2HD_SIM Y DO_DRYDEP LEMIS Y DO_EMISSION
DO_CHEMISTRY
chemistry_mod.f! A_CH4_SIM Y OPTDEPTH 3 A_FULLCHEM_SIM FULL_CHEM_SIM (next page+1 LADJ_CHEM 10 AN_AEROSOL_SIM AEROSOL_SIM (next page) 1 A_RnPbBe_SIM CHEMRnPbBe DRYFLXRnPbBe 2 A_CH3I_SIM CHEMCH31 4 A_HCN_SIM CHEM_HCN_CH3CN 6 A_TAGOX_SIM CHEM_TAGGED_OX 7 A_TAGCO_SIM CHEM_TAGGED_CO_ADJ 8 A_C2H6_SIM CHEM_C2H6 9 A_CH4_SIM CHEM_CH4 11 A_MERCURY_SIM CHEM_MERCURY 13 A_H2HD_SIM CHEM_H2_HD DRYFLXH2HD
AEROSOL_SIM AEROSOL_RURALBOX FIRST READER READCHEM INPHOT AEROSOL_CONC RDAER!LCRYST DO_RPMARESS LSSALT CHEMSEASALT LSULF or LCRYST CHEMSULFATE LCARB CHEMCARBOM (organic) LDUST CHEMDUST RDUST_ONLINE (SOILDUST)
FULL_CHEM_SIM CHEMDR LSULF CHEMSULFATE LAERO_THERM DO_RPMARES LCARB CHEMCARBON DRYFLX DIAGOH
MAKE_AVGW chemdr.f READER READCHEM FIRSTCHEM CH4>0 INPHOT INPHOT(LLTROP, NPHOT) SETTRACE (LLRTOP, NPHOT) SETEMDEP(N_TRACERS) (N_TRACERS) GET_GLOBAL_CH4 LSVCSPEC READ_CSPEC_FILE GASCONC LSULF LCARB LDUST LSSALT AEROSOL_CONC SETEMIS(EMISRR, EMISRRN) RDAER FAST_J PHYSPROC(SUNCOS, SUNCOSB) GCKPP_ADJ_DRIVER(forward) LUMP DO_DIAG_OH LDUST Y N RDUST_ONLINE(SOILDUST) RDUST_OFFLINE(SOILDUST) LVARTROP LSVCSPEC SAVE_FULL_TROP
GEOS_CHEM_ADJ
SET_DIRECTION(-1) INIT_WEIGHT SET_CURRENT_TIME RESCALE_ADJOINT GEOS_Chem_adj.f Inverse Dynamic Loop MN_ADJ = FINAL ELAPSED TIME N LOG_OPT LOG_RESCALE_ADJOINT MIN_ADJ > o N LAPSRC N SET_ELAPSED_MIN_ADJ SET_CURRENT_TIME CALC_APRIORI EXIT LOAD_CHECKPT_DATA ITS_Time_OBS N READ MET FILES CALC_ADJ_FORCE_FOR_OBS AIRQNT COSSZA DO_PBL_MIX ADJOINT PROCESS MN_ADJ = GET_TS_DYN()
READ MET FILES Step1 ITS_Time_FOR_I6 COPY_I6_FIELDS_ADJ OPEN_I6_FIELDS_ADJ GET_I6_FIELDS_1_ADJ AVGPOLE Step2 ITS_Time_FOR_A6 GET_A6_TIME_ADJ OPEN_A6_FIELDS_ADJ READ_ A6_FIELDS_ADJ Step3 ITS_Time_FOR_A3 GET_A3_TIME_ADJ OPEN_A3_FIELDS_ADJ GET_A3_FIELDS Step4 LCHEM && New Month? READ_UV_ALBEDO Step5 FULLCHEMN_SIM TAGCO_SIM LADJ_EMS && New SEASON? ANTHROEMS Step6 New Day? RDISOLAI RDSOIL
ADJOINT PROCESS Step1 ITS_Time_EMIS SET_CT_EMIS DO_DRYDEP DO_EMISSION Step2 ITS_Time_CHEM DO_CHEMISTRY_ADJ Step3 ITS_Time_EMIS DO_EMISSION_ADJ Step5 ITS_Time_CONV LCONV CHECK_STT_ADJ DO_CONVECTION_ADJ CHECK_STT_ADJ DO_PBL_MIX_ADJ Step6 ITS_Time_DYN LCONV LWET LCHEM LSULF ADJ_INIT_WETSCAV LTRAN DO_TRANSPORT_ADJ
chemistry_adj_mod.f! A_CH4_SIM Y OPTDEPTH 3 A_FULLCHEM_SIM FULL_CHEM_SIM_ADJ (next page) LADJ_CHEM 10 AN_AEROSOL_SIM Not supported 1 A_RnPbBe_SIM Not supported 2 A_CH3I_SIM Not supported 4 A_HCN_SIM Not supported 6 A_TAGOX_SIM Not supported 7 A_TAGCO_SIM CHEM_TAGGED_CO_ADJ 8 A_C2H6_SIM Not supported 9 A_CH4_SIM Not supported 11 A_MERCURY_SIM Not supported 13 A_H2HD_SIM Not supported
FULL_CHEM_SIM_ADJ LCARB CHEMCARBON_ADJ LSULF LAERO_THERM RECOMP_RPMARES DO_RPMARES_ADJ CHEMSULFATE_ADJ CHEMDR_ADJ LSSEALT Not supported LDUST Not supported LIDTACET/=0 Not supported
chemdr_adj.f MAKE_AVGW FIRSTCHEM Same as CHEMDR LSULF LCARB LDUST LSSALT Same as CHEMDR SETEMIS(EMISRR, EMISRRN) RDAER FAST_J PHYSPROC(SUNCOS, SUNCOSB) GC_KPP_ADJ_DRIVER(inverse) CHECK_STT_ADJ STT = CHK_STT_BEFCHEM CSEP = CHK_CSPEC PARTITION_ADJ CHECK_STT_ADJ
CALC_ADJ_FORCE_FOR_OBS TES NH3 case
CALC_ADJ_FORCE_FOR_OBS- 1/4! Calculate the interpolation weight matrix MAP(1:LLPAR,1:LLNT) = GET_INTMAP( LLPAR, GC_PRES(:), GC_PSURF, LLNT, TES(NT)%PRES(1:LLNT), GC_PSURF )! Get NH3 values at native model resolution GC_NH3_NATIVE(:) = CHK_STT(I,J,:,IDTNH3)! Convert from kg/box to ppm GC_NH3_NATIVE(:) = GC_NH3_NATIVE(:) * TCVV(IDTNH3) / AD(I,J,:) * 1d6 NH3_SAVE(:,NT) = GC_NH3_NATIVE(:)! Get NH3 values from doubled emissions run [ppmv] GC_NH3_NATIVE_DBL(:) = GET_DOUBLED_NH3( GET_NYMD(), GET_NHMS(), REAL(TES(NT)%LON,4), REAL(TES(NT)%LAT,4))! Interpolate GC NH3 column to TES grid DO LL = 1, LLNT GC_NH3(LL) = 0d0 DO L = 1, LLPAR GC_NH3(LL) = GC_NH3(LL) + MAP(L,LL) * GC_NH3_NATIVE(L)! Interpolate doubled GC NH3 column to TES grid DO LL = 1, LLNT GC_NH3_DBL(LL) = 0d0 DO L = 1, LLPAR GC_NH3_DBL(LL) = GC_NH3_DBL(LL) + MAP(L,LL) * GC_NH3_NATIVE_DBL(L)
CALC_ADJ_FORCE_FOR_OBS- 2/4! x_m - x_a DO L = 1, LLNT GC_NH3(L) = MAX(GC_NH3(L), 1d-10) NH3_PERT(L) = LOG(GC_NH3(L)) - LOG(TES(NT)%PRIOR(L))! x_a + A_k * ( x_m - x_a ) DO L = 1, LLNT NH3_HAT(L) = 0d0 DO LL = 1, LLNT NH3_HAT(L) = NH3_HAT(L) + TES(NT)%AVG_KERNEL(L,LL) * NH3_PERT(LL) NH3_HAT(L) = NH3_HAT(L) + LOG(TES(NT)%PRIOR(L))! x_m - x_a for doubled DO L = 1, LLNT GC_NH3_DBL(L) = MAX(GC_NH3_DBL(L), 1d-10) NH3_PERT_DBL(L) = LOG(GC_NH3_DBL(L)) - LOG(TES(NT)%PRIOR(L))! x_a + A_k * ( x_m - x_a ) DO L = 1, LLNT NH3_HAT_DBL(L) = 0d0 DO LL = 1, LLNT NH3_HAT_DBL(L) = NH3_HAT_DBL(L) + TES(NT)%AVG_KERNEL(L,LL) * NH3_PERT_DBL(LL) NH3_HAT_DBL(L) = NH3_HAT_DBL(L) + LOG(TES(NT)%PRIOR(L))
CALC_ADJ_FORCE_FOR_OBS- 3/4! Calculate difference between modeled and observed profile DO L = 1, LLNT IF ( TES(NT)%NH3(L) > 0d0 ) THEN DIFF(L) = NH3_HAT(L) - LOG( TES(NT)%NH3(L) ) ELSE DIFF(L) = 0d0 ENDIF! Calculate 1/2 * DIFF^T * S_{obs}^{-1} * DIFF DO L = 1, LLNT FORCE(L) = 0d0 DO LL = 1, LLNT FORCE(L) = FORCE(L) + TES(NT)%OER_INV(L,LL) * DIFF(LL) NEW_COST(NT) = NEW_COST(NT) + 0.5d0 * DIFF(L) * FORCE(L) ADJ_DIFF = FORCE! Adjoint of difference DO L = 1, LLNT IF ( TES(NT)%NH3(L) > 0d0 ) THEN ADJ_NH3_HAT(L) = ADJ_DIFF(L) ENDIF DO L = 1, LLNT ADJ_NH3_PERT(L) = 0d0 DO LL = 1, LLNT ADJ_NH3_PERT(L) = ADJ_NH3_PERT(L) + TES(NT)%AVG_KERNEL(LL,L) * ADJ_NH3_HAT(LL)
CALC_ADJ_FORCE_FOR_OBS- 4/4! Adjoint of x_m - x_a DO L = 1, LLNT IF ( GC_NH3(L) > 1d-10 ) THEN ADJ_GC_NH3(L) = 1d0 / GC_NH3(L) * ADJ_NH3_PERT(L) ELSE ADJ_GC_NH3(L) = 0d0 ENDIF! Adjoint of interpolation DO L = 1, LLPAR ADJ_GC_NH3_NATIVE(L) = 0d0 DO LL = 1, LLNT ADJ_GC_NH3_NATIVE(L) = ADJ_GC_NH3_NATIVE(L) + MAP(L,LL) * ADJ_GC_NH3(LL)! Adjoint of unit conversion ADJ_GC_NH3_NATIVE(:) = ADJ_GC_NH3_NATIVE(:) * TCVV(IDTNH3) / AD(I,J,:) * 1d6! Pass adjoint back to adjoint tracer array STT_ADJ(I,J,:,IDTNH3) = STT_ADJ(I,J,:,IDTNH3) + ADJ_GC_NH3_NATIVE(:)!AD = (dry) mass of air in grid box (I,J,L) in kg,!tcvv = Array containing [Air MW / Tracer MW] for tracers! Update cost function COST_FUNC = COST_FUNC + SUM(NEW_COST(NTSTOP:NTSTART))