/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Driver for the Adjoint (ADJ) model ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ int InitSaveData(); void Initialize(); int SaveData(); int CloseSaveData(); int GenerateMatlab( char * prefix ); void GetMass( KPP_REAL CL[], KPP_REAL Mass[] ); void INTEGRATE_ADJ( int NADJ, KPP_REAL Y[], KPP_REAL Lambda[][NVAR], KPP_REAL TIN, KPP_REAL TOUT, KPP_REAL ATOL_adj[][NVAR], KPP_REAL RTOL_adj[][NVAR], int ICNTRL_U[], KPP_REAL RCNTRL_U[], int ISTATUS_U[], KPP_REAL RSTATUS_U[] ); int main() { KPP_REAL T, DVAL[NSPEC]; int i, j, ind_1 = ind_O1D, ind_2 = ind_O3; /*~~> NADJ = Number of functionals for which sensitivities are computed Note: the setting below is for sensitivities of all final concentrations; the setting may have to be changed for other applications */ int NADJ = NVAR; KPP_REAL Y_adj[NADJ][NVAR], ATOL_adj[NADJ][NVAR], RTOL_adj[NADJ][NVAR]; /*~~> Control (in) and status (out) arguments for the integration */ KPP_REAL RCNTRL[20], RSTATUS[20]; int ICNTRL[20], ISTATUS[20]; STEPMIN = (double)0.0; STEPMAX = (double)0.0; /*~~~> Tolerances for calculating concentrations */ for( i=0; i Tolerances for calculating adjoints are used for controlling adjoint truncation error and for solving the linear adjoint equations by iterations Note: Adjoints typically span many orders of magnitude and a careful tuning of ATOL_adj may be necessary */ for(i=0; i The adjoint values at the final time */ for(i=0; i Default control options */ for(i=0; i<20; i++) { ICNTRL[i] = 0; RCNTRL[i] = (double)0.0; ISTATUS[i] = 0; RSTATUS[i] = (double)0.0; } /*~~~> Begin time loop */ TIME = TSTART; InitSaveData(); T = TSTART; GetMass( C, DVAL ); printf("\n%6.1f%% %7.2f ", (TIME-TSTART)/(TEND-TSTART)*100, TIME/3600 ); for( i = 0; i < NMONITOR; i++ ) printf( "%9.3e ", C[ MONITOR[i] ]/CFACTOR ); for( i = 0; i < NMASS; i++ ) printf( "%9.3e ", DVAL[i]/CFACTOR ); TIME = T; SaveData(); INTEGRATE_ADJ( NADJ, VAR, Y_adj, T, TEND, ATOL_adj, RTOL_adj, ICNTRL, RCNTRL, ISTATUS, RSTATUS ); GetMass( C, DVAL ); printf("\n%6.1f%% %7.2f ", (TEND-TSTART)/(TEND-TSTART)*100, TIME/3600 ); for( i = 0; i < NMONITOR; i++ ) printf( "%9.3e ", C[ MONITOR[i] ]/CFACTOR ); for( i = 0; i < NMASS; i++ ) printf( "%9.3e ", DVAL[i]/CFACTOR ); TIME = T; SaveData(); /*~~~> End time loop ~~~~~~~~~~*/ printf( "\n\n****************************************************\n" ); printf( " Concentrations and Sensitivities at final time\n" ); printf( " were written in the file KPP_ROOT_ADJ_results.m\n"); printf( "****************************************************\n"); FILE *out; out = fopen("KPP_ROOT_ADJ_results.m", "w"); if(out == NULL) { printf("Unable to open file KPP_ROOT_ADJ_results.m\n"); exit(1); } for(j=0; j The entire matrix of sensitivities */ printf(" "); for(i=0; i