src/simpleNbox.cpp
//------------------------------------------------------------------------------
/*! \brief              Compute 'slowly varying' fluxes
 *  \param[in]  t       time (at the *beginning* of the current time step.
 *  \param[in]  c       carbon pools (no units)
 *
 *  Compute 'slowly varying' fertilization and anthropogenic fluxes.
 *  Treat the fertilization factors as slowly varying for illustrative purposes
 *  (in fact we could calculate it at each integration step if we wanted to).
 */
\brief              Compute 'slowly varying' fluxes
\param[in]  t       time (at the *beginning* of the current time step.
\param[in]  c       carbon pools (no units)

Compute 'slowly varying' fertilization and anthropogenic fluxes.
Treat the fertilization factors as slowly varying for illustrative purposes
(in fact we could calculate it at each integration step if we wanted to).
\ brief Compute ' slowly varying ' fluxes \ param [ in ] t time ( at the * beginning * of the current time step . \ param [ in ] c carbon pools ( no units ) Compute ' slowly varying ' fertilization and anthropogenic fluxes . Treat the fertilization factors as slowly varying for illustrative purposes ( in fact we could calculate it at each integration step if we wanted to ) .
void SimpleNbox::slowparameval( double t, const double c[] )
{
    omodel->slowparameval( t, c );      
    Ca.set( c[ SNBOX_ATMOS ] * PGC_TO_PPMVCO2, U_PPMV_CO2 );
    double_stringmap::const_iterator itd;
    for( itd = beta.begin(); itd != beta.end(); itd++ ) {
        if( in_spinup ) {
            co2fert[ itd->first ] = 1.0;  
        } else {
            co2fert[ itd->first ] = 1 + beta.at( itd->first ) * log( Ca/C0 );
        }
        H_LOG( logger,Logger::DEBUG ) << "co2fert[ " << itd->first << " ] at " << Ca << " = " << co2fert[ itd->first ] << std::endl;
    }
    const double Tgav = core->sendMessage( M_GETDATA, D_GLOBAL_TEMP ).value( U_DEGC );
    double_stringmap tfs_last;  
    if(t != Core::undefinedIndex() && t > core->getStartDate()) {
        tfs_last = tempferts_tv[t];
    }
    for( itd = beta.begin(); itd != beta.end(); itd++ ) {
        std::string biome(itd->first);
        if( in_spinup ) {
            tempfertd[ biome ] = 1.0;  
            tempferts[ biome ] = 1.0;  
        } else {
            double wf = warmingfactor.at( SNBOX_DEFAULT_BIOME );
            if( warmingfactor.count( biome ) ) {
                wf = warmingfactor[ biome ];   
            }
            const double Tgav_biome = Tgav * wf;    
            tempfertd[ biome ] = pow( q10_rh, ( Tgav_biome / 10.0 ) ); 
            #define Q10_TEMPLAG 0 //125         // TODO: put lag in input files 150, 25
            #define Q10_TEMPN 200 //25
            double Tgav_rm = 0.0;       
            if( t > core->getStartDate() + Q10_TEMPLAG ) {
                for( int i=t-Q10_TEMPLAG-Q10_TEMPN; i<t-Q10_TEMPLAG; i++ ) {
                    Tgav_rm += Tgav_record.get( i ) * wf;
                }
                Tgav_rm /= Q10_TEMPN;
            }
            tempferts[ biome ] = pow( q10_rh, ( Tgav_rm / 10.0 ) );
            double tempferts_last = tfs_last[biome]; 
            if(tempferts[ biome ] < tempferts_last) {
                tempferts[ biome ] = tempferts_last;
            }
            H_LOG( logger,Logger::DEBUG ) << biome << " Tgav=" << Tgav << ", Tgav_biome=" << Tgav_biome << ", tempfertd=" << tempfertd[ biome ]
                << ", tempferts=" << tempferts[ biome ] << std::endl;
        }
    } 
    H_LOG(logger, Logger::DEBUG) << "slowparameval: would have recorded tempferts = " << tempferts[SNBOX_DEFAULT_BIOME]
                                 << " at time= " << tcurrent << std::endl;
}
void SimpleNbox :: slowparameval ( double t , const double c [ ] ) { omodel -> slowparameval ( t , c ) ; Ca . set ( c [ SNBOX_ATMOS ] * PGC_TO_PPMVCO2 , U_PPMV_CO2 ) ; double_stringmap :: const_iterator itd ; for ( itd = beta . begin ( ) ; itd != beta . end ( ) ; itd ++ ) { if ( in_spinup ) { co2fert [ itd -> first ] = 1.0 ; } else { co2fert [ itd -> first ] = 1 + beta . at ( itd -> first ) * log ( Ca / C0 ) ; } H_LOG ( logger , Logger :: DEBUG ) << " " << itd -> first << " " << Ca << " " << co2fert [ itd -> first ] << std :: endl ; } const double Tgav = core -> sendMessage ( M_GETDATA , D_GLOBAL_TEMP ) . value ( U_DEGC ) ; double_stringmap tfs_last ; if ( t != Core :: undefinedIndex ( ) && t > core -> getStartDate ( ) ) { tfs_last = tempferts_tv [ t ] ; } for ( itd = beta . begin ( ) ; itd != beta . end ( ) ; itd ++ ) { std :: string biome ( itd -> first ) ; if ( in_spinup ) { tempfertd [ biome ] = 1.0 ; tempferts [ biome ] = 1.0 ; } else { double wf = warmingfactor . at ( SNBOX_DEFAULT_BIOME ) ; if ( warmingfactor . count ( biome ) ) { wf = warmingfactor [ biome ] ; } const double Tgav_biome = Tgav * wf ; tempfertd [ biome ] = pow ( q10_rh , ( Tgav_biome / 10.0 ) ) ; #define Q10_TEMPLAG  0 //125         // TODO: put lag in input files 150, 25 #define Q10_TEMPN  200 //25 double Tgav_rm = 0.0 ; if ( t > core -> getStartDate ( ) + Q10_TEMPLAG ) { for ( int i = t - Q10_TEMPLAG - Q10_TEMPN ; i < t - Q10_TEMPLAG ; i ++ ) { Tgav_rm += Tgav_record . get ( i ) * wf ; } Tgav_rm /= Q10_TEMPN ; } tempferts [ biome ] = pow ( q10_rh , ( Tgav_rm / 10.0 ) ) ; double tempferts_last = tfs_last [ biome ] ; if ( tempferts [ biome ] < tempferts_last ) { tempferts [ biome ] = tempferts_last ; } H_LOG ( logger , Logger :: DEBUG ) << biome << " " << Tgav << " " << Tgav_biome << " " << tempfertd [ biome ] << " " << tempferts [ biome ] << std :: endl ; } } H_LOG ( logger , Logger :: DEBUG ) << " " << tempferts [ SNBOX_DEFAULT_BIOME ] << " " << tcurrent << std :: endl ; }
\brief              Compute 'slowly varying' fluxes
  \param[in]  t       time (at the *beginning* of the current time step.
\ brief Compute ' slowly varying ' fluxes \ param [ in ] t time ( at the * beginning * of the current time step .
// pass msg on to ocean model // CO2 fertilization // Compute CO2 fertilization factor globally (and for each biome specified) // no perturbation allowed if in spinup // Compute temperature factor globally (and for each biome specified) // Heterotrophic respiration depends on the pool sizes (detritus and soil) and Q10 values // The soil pool uses a lagged Tgav, i.e. we assume it takes time for heat to diffuse into soil /* set tempferts (soil) and tempfertd (detritus) for each biome */ // Need the previous time step values of tempferts.  Since t is // the time at the beginning of the current time step (== the end // of the previous time step), we can use t as the index to look // up the previous value. // Previous time step values of tempferts; initialized empty // Loop over biomes. // NOTE: This is over `beta` because tempfertd is never // initialized for biomes other than the default. // no perturbation allowed in spinup // no perturbation allowed in spinup // biome-specific warming // biome-specific temperature // detritus warms with air // Soil warm very slowly relative to the atmosphere // We use a mean temperature of a window (size Q10_TEMPN) of temperatures to scale Q10 /* window mean of Tgav */ // The soil Q10 effect is 'sticky' and can only increase, not decline // If tfs_last is empty, this will produce 0.0 // loop over biomes // save the new values for use in the next time step // TODO:  move this to a purpose-built recording subroutine //tempferts_tv.set(tcurrent, tempferts);