From 2370ddd7939201be4feaa9287b28c2842edecabb Mon Sep 17 00:00:00 2001 From: Sola_MBA Date: Wed, 8 Oct 2025 16:10:00 +0800 Subject: [PATCH] update 20251007 --- code/adjoint/geos_chem_adj_mod.f | 80 ++++++++++++++-------------- code/modified/geos_chem_mod.f | 10 ++-- code/obs_operators/geocape_ch4_mod.f | 44 +++++++-------- 3 files changed, 67 insertions(+), 67 deletions(-) diff --git a/code/adjoint/geos_chem_adj_mod.f b/code/adjoint/geos_chem_adj_mod.f index 55d573c..c9ad9c7 100644 --- a/code/adjoint/geos_chem_adj_mod.f +++ b/code/adjoint/geos_chem_adj_mod.f @@ -283,11 +283,11 @@ LOGICAL :: FIRST_WEAK !================================================================= - ! GEOS-CHEM-ADJ starts here! + ! GEOS-CHEM-ADJ starts here! 开始伴随过程 !================================================================= !================================================================= - ! ***** I N I T I A L I Z A T I O N ***** + ! ***** I N I T I A L I Z A T I O N ***** 初始化 !================================================================= !---------------------------------------------------------------------- @@ -305,7 +305,7 @@ WRITE( 6, '(a)' ) REPEAT( '=', 79 ) WRITE( 6, '(a,/)' ) 'B A C K W A R D I N T E G R A T I O N' - ! Now set DIRECTION to -1 to indicate that it's adjoint integration + ! Now set DIRECTION to -1 to indicate that it's adjoint integration 设置积分的方向 CALL SET_DIRECTION( -1 ) ! Initialize allocatable arrays @@ -321,7 +321,7 @@ !ENDIF - ! Open BACKWD_met file + ! Open BACKWD_met file 打开逆向的气象文件,里面就是一些描述信息倒是 CALL DISPLAY_MET(165,0) ! Define time variables for use below @@ -343,7 +343,7 @@ ENDIF ! BUG FIX: need to reset EMS_SF_ADJ so that gradients do not - ! accumulate from one iteration to the next. (zj, dkh, 07/30/10) + ! accumulate from one iteration to the next. (zj, dkh, 07/30/10) 在每次迭代中重置了梯度的数组 IF ( LADJ_EMS ) EMS_SF_ADJ = 0D0 ! for new strat. chem. (hml, 08/09/11, adj32_025) @@ -356,7 +356,7 @@ IF ( LADJ_RRATE ) RATE_SF_ADJ = 0D0 !================================================================= - ! ***** 6 - H O U R T I M E S T E P L O O P ***** + ! ***** 6 - H O U R T I M E S T E P L O O P ***** 进行 6 小时的积分 !================================================================= ! Echo message before first timestep @@ -368,28 +368,28 @@ ! NSTEP is the number of dynamic timesteps w/in a 6-h interval ! N_DYN_STEPS = 360 / GET_TS_DYN() - ! now with geos-fp (lzh, 07/10/2014) + ! now with geos-fp (lzh, 07/10/2014) 计算需要计算的次数 N_DYN_STEPS #if defined( GEOS_FP ) N_DYN_STEPS = 180 / GET_TS_DYN() ! GEOS-5.7.x has a 3-hr interval #else N_DYN_STEPS = 360 / GET_TS_DYN() ! All other met has a 6hr interval #endif - FINAL_ELAPSED_MIN = GET_ELAPSED_MIN() + FINAL_ELAPSED_MIN = GET_ELAPSED_MIN() ! 获得程序运行的分钟数(?)应该不是指现实时间 - ! Start a new 6-h loop + ! Start a new 6-h loop 开始迭代积分 DO - ! Get dynamic timestep in seconds + ! Get dynamic timestep in seconds 获得积分时间 N_DYN = 60d0 * GET_TS_DYN() - ! Compute time parameters at start of 6-h loop + ! Compute time parameters at start of 6-h loop 获取当前时间 CALL SET_CURRENT_TIME !================================================================= - ! ***** D Y N A M I C T I M E S T E P L O O P ***** + ! ***** D Y N A M I C T I M E S T E P L O O P ***** 开始积分 !================================================================= - DO MIN_ADJ = FINAL_ELAPSED_MIN - GET_TS_DYN(), 0, - GET_TS_DYN() + DO MIN_ADJ = FINAL_ELAPSED_MIN - GET_TS_DYN(), 0, - GET_TS_DYN() ! 从最后时刻反向积分到 0 时刻 ! mak debug WRITE(6,*)'start of adj time step' @@ -400,7 +400,7 @@ ! Compute & print time quantities at start of dyn step CALL SET_CURRENT_TIME - ! Set time variables for dynamic loop + ! Set time variables for dynamic loop 获得时间参数 !DAY = GET_DAY() DAY_OF_YEAR = GET_DAY_OF_YEAR() ELAPSED_SEC = GET_ELAPSED_SEC() @@ -413,7 +413,7 @@ !CALL MAKE_ADJOINT_CHKFILE( NYMD, NHMS, TAU ) - ! Get info from the perturbed forward run + ! Get info from the perturbed forward run 从前向模拟中获得相关信息和数据,输入的是时间 CALL LOAD_CHECKPT_DATA( NYMD, NHMS ) ! mkeller: weak constraint stuff @@ -428,7 +428,7 @@ ENDIF !============================================================ - ! ***** R E A D M E T F I E L D S ***** + ! ***** R E A D M E T F I E L D S ***** 读取气象场数据 !============================================================ ! If it is the first time through, we will use i6 field from the ! forward calculation, and all we need to do is set NSECb_ADJ @@ -474,7 +474,7 @@ ENDIF !============================================================== - ! ***** R E A D I - 6 F I E L D S ***** + ! ***** R E A D I - 6 F I E L D S ***** 读取 I6 场 !============================================================== !!! geos-fp (lzh, 07/10/2014) #if defined( GEOS_FP ) @@ -502,8 +502,8 @@ ! Compute avg pressure at polar caps (for ADJ argument is PS1, not PS2) CALL AVGPOLE( PS1 ) - ! Set NSECb_ADJ to be used for the interpolation - ! where NSECb_ADJ is the total elapsed time in seconds at the + ! Set NSECb_ADJ to be used for the interpolation 这个参数是用来插值的 + ! where NSECb_ADJ is the total elapsed time in seconds at the 表示从当前 6 小时时间步开始的秒钟数 ! beginning of the current 6h time step which contains ELAPSED_MIN NSECb_ADJ = ( MIN_ADJ + GET_TS_DYN() ) * 60 - 3 * 3600 ENDIF @@ -524,9 +524,9 @@ ! Get the date/time for the previous I-6 data block BEHIND_DATE = GET_I6_TIME_ADJ() - ! Open and read files + ! Open and read files 虽然是打开了气象场文件,但不确定是正向模拟使用的还是专用于伴随的,程序是专用于伴随的 CALL OPEN_I6_FIELDS_ADJ( BEHIND_DATE(1), BEHIND_DATE(2) ) - CALL GET_I6_FIELDS_1_ADJ( BEHIND_DATE(1), BEHIND_DATE(2) ) + CALL GET_I6_FIELDS_1_ADJ( BEHIND_DATE(1), BEHIND_DATE(2) ) ! 从这边看应该是读取的原始气象场 PRINT*,'I6 DATE = ',BEHIND_DATE(1),BEHIND_DATE(2) ! Compute avg pressure at polar caps (for ADJ argument is PS1, not PS2) @@ -608,7 +608,7 @@ CALL GET_A3_FIELDS( BEHIND_DATE(1), BEHIND_DATE(2) ) ! Update daily mean temperature archive for MEGAN biogenics - ! For adjoint, read in checkpointed values (dkh, 01/23/10) + ! For adjoint, read in checkpointed values (dkh, 01/23/10) 对于伴随来说,则是将气象场读入检查点值 IF ( LMEGAN ) CALL UPDATE_T_DAY_ADJ #if defined( GEOS_3 ) @@ -625,7 +625,7 @@ #endif !DAY_OF_SIM initialized to -1 in INIT_ADJ_ARRAYS - ! keeps tabs of day of simulation, going backward in time + ! keeps tabs of day of simulation, going backward in time 确保模拟是反向运行的 ! this is handy for storing diagnostic files that have dimensions ! (IIPAR,JJPAR,DAYS), where DAYS is number of days in simulation ! (adj_group, 6/09/09) @@ -649,7 +649,7 @@ !============================================================== - ! ***** M O N T H L Y O R S E A S O N A L D A T A ***** + ! ***** M O N T H L Y O R S E A S O N A L D A T A ***** 月度或者季节数据 !============================================================== ! UV albedoes @@ -668,7 +668,7 @@ !============================================================== - ! ***** D A I L Y D A T A ***** + ! ***** D A I L Y D A T A ***** 读取每日的数据 ! ! RDLAI returns today's leaf-area index ! RDSOIL returns today's soil type information @@ -726,7 +726,7 @@ ! ***** I N T E R P O L A T E Q U A N T I T I E S ***** ! ! Interpolate I-6 fields to current dynamic timestep, - ! based on their values at NSEC and NSEC+NTDT + ! based on their values at NSEC and NSEC+NTDT 将气象场数据插值到当前时刻 !============================================================== #if defined ( GEOS_3 ) @@ -739,11 +739,11 @@ ENDIF #endif - ! If we are not doing transport, then make sure that + ! If we are not doing transport, then make sure that 为什么会有不做传输的选项啊 ! the floating pressure is set to PSC2 (bdf, bmy, 8/22/02) IF ( .not. LTRAN ) CALL SET_FLOATING_PRESSURE( PSC2 ) - ! Compute airmass quantities at each grid box + ! Compute airmass quantities at each grid box 计算每个网格的空气质量 CALL AIRQNT ! OLD: @@ -2721,7 +2721,7 @@ ! !****************************************************************************** ! Subroutine CALC_ADJ_FORCE_FOR_SENS calculates the cost function for -! sensitivity calculations. (dkh, ks, mak, cs 06/08/09) +! sensitivity calculations. (dkh, ks, mak, cs 06/08/09) 用于敏感性计算的程序 ! ! NOTE: ! (1 ) Split off from CALC_ADJ_FORCE (dkh, ks, mak, cs 06/08/09) @@ -3387,7 +3387,7 @@ ! !****************************************************************************** ! Subroutine LOAD_CHECKPT_DATA reads in information stored during the forward -! calculation. Some of the data (CSPEC) needs to be rotated. +! calculation. Some of the data (CSPEC) needs to be rotated. 读取前向模型的相关数据,某些数据可能需要转置 ! (dkh, 08/10/05) ! ! Arguments as Input: @@ -3468,7 +3468,7 @@ ! LOAD_CHECKPT_DATA begins here! !================================================================= - ! Load the TMP met fields so they can rotate in later. + ! Load the TMP met fields so they can rotate in later. 设置了一些临时变量 IF ( FIRST ) THEN SLP_TMP(:,:) = SLP(:,:) #if defined( GEOS_3 ) || defined( GEOS_4 ) || defined( GEOS_5 ) || defined(GEOS_FP) @@ -3481,26 +3481,26 @@ FIRST = .FALSE. ENDIF - IF ( ITS_TIME_FOR_CHEM() ) THEN + IF ( ITS_TIME_FOR_CHEM() ) THEN ! 如果是需要计算化学过程 ! Rotate arrays for fullchem - IF ( ITS_A_FULLCHEM_SIM() ) THEN + IF ( ITS_A_FULLCHEM_SIM() ) THEN ! 如果全化学模拟 - IF ( TURNAROUND .and. IDO3 /= 0 .and. IDNO2 /=0 ) THEN + IF ( TURNAROUND .and. IDO3 /= 0 .and. IDNO2 /=0 ) THEN ! 如果包含 O3 和 NO2? ! Added in v16 (dkh, 08/27/06) ! Get directly from CSPEC the first time !$OMP PARALLEL DO !$OMP+DEFAULT( SHARED ) !$OMP+PRIVATE( JLOOP, N, IDCSPEC ) - DO JLOOP = 1, ITLOOP - DO N = 1, NOBS_CSPEC + DO JLOOP = 1, ITLOOP ! 对?迭代 + DO N = 1, NOBS_CSPEC ! 对所有化学物种迭代 - IDCSPEC = IDCSPEC_ADJ(N) + IDCSPEC = IDCSPEC_ADJ(N) ! 获取对应的 ID ! Now make this more general (dkh, 02/09/11) !O3_AFTER_CHEM(JLOOP) = CSPEC(JLOOP,IDO3) !NO2_AFTER_CHEM(JLOOP) = CSPEC(JLOOP,IDNO2) - CSPEC_AFTER_CHEM(JLOOP,N) = CSPEC(JLOOP,IDCSPEC) + CSPEC_AFTER_CHEM(JLOOP,N) = CSPEC(JLOOP,IDCSPEC) ! 大概是 ID 和 迭代的对应? ENDDO ENDDO @@ -3534,13 +3534,13 @@ !$OMP END PARALLEL DO ENDIF - ! Turnaround will be false after the first time through this routine + ! Turnaround will be false after the first time through this routine 在第一次运行后,ID 获取的来源就环卫 CHK_CSPEC TURNAROUND = .FALSE. ENDIF ! fullchem ! Read data from file - CALL READ_CHECKPT_FILE ( NYMD, NHMS ) + CALL READ_CHECKPT_FILE ( NYMD, NHMS ) ! 读取检查点文件 IF ( ITS_A_FULLCHEM_SIM() .AND. LCHEM ) THEN diff --git a/code/modified/geos_chem_mod.f b/code/modified/geos_chem_mod.f index 3b4aaf2..821f698 100644 --- a/code/modified/geos_chem_mod.f +++ b/code/modified/geos_chem_mod.f @@ -2424,10 +2424,10 @@ !****************************************************************************** ! Subroutine DISPLAY_MET writes out met field and computed data to the ! screen, used for checking that the fwd and backwd runs are in sync. -! (dkh, 03/13/05) +! (dkh, 03/13/05) 输出气象文件,并且计算,保证正向的和逆向的运行一致? ! ! NOTES: -! (1 ) Use FID = 155 for fwd run and FID = 165 for backwd run +! (1 ) Use FID = 155 for fwd run and FID = 165 for backwd run 155 是正向运行的,165 是逆向运行的,主要是决定了使用的文件名 ! !****************************************************************************** ! @@ -2474,7 +2474,7 @@ ENDIF IF ( LOCATION == 0 ) THEN - ! Open files for output + ! Open files for output 打开输出文件,写入当前的坐标信息? OPEN( FID, FILE=TRIM( FILENAME ), STATUS='UNKNOWN', & IOSTAT=IOS, FORM='FORMATTED', ACCESS='SEQUENTIAL' ) @@ -2493,9 +2493,9 @@ #endif ELSEIF ( LOCATION == 1 ) THEN - ! Hours since start of run + ! Hours since start of run 也就是正向模拟运行的过程 - ! Write quantities + ! Write quantities 写入一些当前时间的量,感觉这个文件主要是包含了一堆描述信息? WRITE( FID, 100 ) GET_YEAR(), GET_MONTH(), GET_DAY(), & GET_HOUR(), GET_MINUTE() diff --git a/code/obs_operators/geocape_ch4_mod.f b/code/obs_operators/geocape_ch4_mod.f index e2741b8..d2a19ad 100644 --- a/code/obs_operators/geocape_ch4_mod.f +++ b/code/obs_operators/geocape_ch4_mod.f @@ -14,7 +14,7 @@ !================================================================= ! Parameters - INTEGER, PARAMETER :: LLGEOCAPE = 13 + INTEGER, PARAMETER :: LLGEOCAPE = 13 ! 卫星观测的垂直层数 INTEGER, PARAMETER :: MAXGEOCAPE = 639059 @@ -25,7 +25,7 @@ REAL*8 :: TOTERROR_INV( LLGEOCAPE, LLGEOCAPE ) REAL*8 :: PRESSURE( LLGEOCAPE ) REAL*8 :: PRESSURE_EDGE( LLGEOCAPE ) - REAL*8 :: RANDNUM( MAXGEOCAPE ) + REAL*8 :: RANDNUM( MAXGEOCAPE ) ! 保存了随机数的数组 CONTAINS @@ -37,7 +37,7 @@ ! Subroutine READ_GEOCAPE_INFO reads and stores information about the new ! instrument, specifically AK, pressure levels and error covariance matrices. ! (kjw, 07/24/11) -! +! 用于读取卫星观测的数据,保存 AK、气压以及误差协方差矩阵(没有观测值么),应该有观测值 ! Arguments as Input: ! ============================================================================ ! (1 ) FILENAME (CHAR) : GEOCAPE filename to read @@ -85,7 +85,7 @@ ! Read and store one variable at a time - ! ------ Averaging Kernel Matrix ------ + ! ------ Averaging Kernel Matrix ------ 读取平均核函数,并保存在模块变量中 ! Filename to read READ_FILENAME = TRIM( '/home/kjw/new_satellites/geocape/' ) // & 'data/' // TRIM( 'geocape_AK.txt' ) @@ -116,7 +116,7 @@ CLOSE( IU_IN ) - ! ------ Observation Error Covariance Matrix ------ + ! ------ Observation Error Covariance Matrix ------ 读取误差协方差矩阵 ! Filename to read READ_FILENAME = TRIM( '/home/kjw/new_satellites/geocape/' ) // & 'data/' // TRIM( 'geocape_obs_error.txt' ) @@ -129,7 +129,7 @@ & STATUS='OLD', IOSTAT=IOS ) IF ( IOS /= 0 ) CALL IOERROR( IOS, IU_IN, 'read_obs_error:1' ) - ! Read File and save info into module variable OBSERROR(:,:) + ! Read File and save info into module variable OBSERROR(:,:) 读取观测误差 DO LN=1,LLGEOCAPE READ( IU_IN, '(13F18.12)', IOSTAT=IOS ) OBSERROR(LN,:) @@ -147,7 +147,7 @@ CLOSE( IU_IN ) - ! ------ Inverse of Observation Error Covariance Matrix ------ + ! ------ Inverse of Observation Error Covariance Matrix ------ 对观测误差协方差矩阵求逆 ! Filename to read READ_FILENAME = TRIM( '/home/kjw/new_satellites/geocape/' ) // & 'data/' // TRIM( 'geocape_obs_error_inv.txt' ) @@ -209,7 +209,7 @@ ! CLOSE( IU_IN ) - ! ------ Pressure Levels ------ + ! ------ Pressure Levels ------ 读取气压数据 ! Filename to read READ_FILENAME = TRIM( '/home/kjw/new_satellites/geocape/' ) // & 'data/' // TRIM( 'geocape_pressure.txt' ) @@ -238,7 +238,7 @@ CLOSE( IU_IN ) - ! ------ Pressure Edges ------ + ! ------ Pressure Edges ------ 获取气压的边界值 ! By finite difference on log(pressure) grid PRESSURE_EDGE(1) = PRESSURE(1) PRESSURE_EDGE(LLGEOCAPE) = 0. @@ -248,7 +248,7 @@ ENDDO - ! Return to calling program + ! Return to calling program 还真没有直接读取观测值 END SUBROUTINE READ_GEOCAPE_INFO !------------------------------------------------------------------------------ @@ -258,7 +258,7 @@ !****************************************************************************** ! Subroutine CALC_GEOCAPE_CH4_FORCE calculates the adjoint forcing from the GEOCAPE ! CH4 observations and updates the cost function. (kjw, 07/20/11) -! +! 该程序计算伴随强迫,并且更新代价函数 ! ! Arguments as Input/Output: ! ============================================================================ @@ -362,10 +362,10 @@ NEW_COST(:) = 0d0 - ! Open files for output + ! Open files for output 在第一次运行时会打开相关文件用于输出(?) IF ( FIRST ) THEN FILENAME = 'pres.NN.m' - CALL EXPAND_NAME( FILENAME, N_CALC ) + CALL EXPAND_NAME( FILENAME, N_CALC ) ! 替换文件名中的 NN 为迭代次数 FILENAME = TRIM( DIAGADJ_DIR ) // TRIM( FILENAME ) OPEN( 101, FILE=TRIM( FILENAME ), STATUS='UNKNOWN', & IOSTAT=IOS, FORM='FORMATTED', ACCESS='SEQUENTIAL' ) @@ -471,11 +471,11 @@ !FILENAME_OBS = TRIM( ADJTMP_DIR ) // TRIM( FILENAME_OBS ) XTAU = GET_TAU() CALL READ_BPCH2( TRIM(FILENAME_OBS), 'IJ-OBS-$', 1, - & XTAU, IIPAR, JJPAR, - & LLPAR, DUMMY_TRUE , QUIET=.TRUE.) + & XTAU, IIPAR, JJPAR, ! II, JJ, LL 都是维度大小而非坐标 + & LLPAR, DUMMY_TRUE , QUIET=.TRUE.) ! DUMMY_TRUE 为读取的观测数据? GC_CH4_TRUE_ARRAY(:,:,:) = DUMMY_TRUE(:,:,:) - ! Convert from [kg] --> [v/v] + ! Convert from [kg] --> [v/v] 单位转换 DO II=1,IIPAR DO JJ=1,JJPAR DO LG=1,LLPAR @@ -543,7 +543,7 @@ print*, ' - CALC_GEOCAPE_CH4_FORCE ', GET_NYMD(), GET_NHMS() - ! Loop over each grid box north of the minimum latitude + ! Loop over each grid box north of the minimum latitude 对于每个网格进行循环 ! 1. Determine number of observations in the current grid box ! 2. Make obseravations DO II = 1, IIPAR @@ -582,7 +582,7 @@ ! Get GEOS-Chem pressure and CH4 column corresponding to this grid box. ! CH4 in [kg/box] and pressure in [hPa] ! Get column of pressure centers and CH4 values - DO LG=1,LLPAR + DO LG=1,LLPAR ! 对垂直上进行循环,计算柱浓度 ! Pressure centers [hPa] GC_PCENTER(LG) = GET_PCENTER(II,JJ,LG) @@ -605,7 +605,7 @@ ! GEOS-Chem surface pressure < GEOCAPE pressure levels nlev = count( PRESSURE_EDGE .LT. GC_PEDGE(1) ) IF ( nlev .LT. 13 ) nlev = nlev + 1 - lind = LLGEOCAPE + 1 - nlev ! minimum vertical index on GEOCAPE grid + lind = LLGEOCAPE + 1 - nlev ! minimum vertical index on GEOCAPE grid 最小气压层的索引 ! Get interpolation matrix that maps GEOS-Chem to GEOCAPE grid @@ -908,13 +908,13 @@ !****************************************************************************** ! Subroutine CALC_GEOCAPE_CH4_FORCE calculates the adjoint forcing from the GEOCAPE ! CH4 observations and updates the cost function. (kjw, 07/20/11) -! +! 似乎是伴随强迫使用的程序,输出不仅有代价函数,还有伴随强迫(不过需要输入扰动) ! ! Arguments as Input/Output: ! ============================================================================ ! (1 ) COST_FUNC_A (REAL*8) : Cost funciton (INOUT) [unitless] -! (2 ) PERT (Real*8) : Array of perturbations to CH4 column (+/- 0.1, for ex.) -! (5 ) ADJ (REAL*8) : Array of adjoint forcings (OUT) +! (2 ) PERT (Real*8) : Array of perturbations to CH4 column (+/- 0.1, for ex.) 扰动的柱浓度 +! (5 ) ADJ (REAL*8) : Array of adjoint forcings (OUT) 强迫伴随 ! ! NOTES: ! (1 )