LandscapeDNDC  1.36.0
ldndc::SoilChemistryMeTrX Class Reference

Biogeochemical model MeTrx. More...

Inherits ldndc::MBE_LegacyModel.

Public Member Functions

lerr_t solve ()
 

Private Member Functions

lerr_t MeTrX_write_output ()
 
lerr_t MeTrX_write_output_daily ()
 
lerr_t MeTrX_write_output_yearly ()
 
lerr_t MeTrX_write_output_layer_daily ()
 
lerr_t MeTrX_write_output_layer_yearly ()
 
lerr_t MeTrX_write_output_fluxes ()
 
lerr_t MeTrX_write_output_pools ()
 
lerr_t MeTrX_write_output_subdaily ()
 
lerr_t MeTrX_write_rates ()
 
lerr_t MeTrX_fertilize ()
 
lerr_t MeTrX_manure ()
 
lerr_t MeTrX_till ()
 
lerr_t MeTrX_reset ()
 
lerr_t MeTrX_reset_subdaily ()
 
lerr_t MeTrX_reset_daily ()
 
lerr_t MeTrX_update ()
 
lerr_t MeTrX_check_for_negative_value (char const *)
 iterates over complete soilchemistry state and checks for negative values
 
lerr_t MeTrX_spinup ()
 
lerr_t MeTrX_physics ()
 
void MeTrX_leaching ()
 Downwards transport of solutes, litter and humus with percolation water. More...
 
void MeTrX_groundwater_access ()
 
lerr_t MeTrX_plant_respiration (size_t)
 Updates o2 and co2 concentrations in soil layers. There is no o2 mass conservation guaranteed because vegetation modules calculate autotrophic respiration without oxygen limitation. When oxygen demand in soil layers is not fullfilled o2_deff stores deficit and increases oxygen demand in following layers.
 
lerr_t MeTrX_freeze_thaw ()
 
lerr_t MeTrX_fragmentation ()
 
void MeTrX_litter_distribution (double const &, double const &, double const &, double const &, double const &, double const &, CBM_Vector< double > &accumulated_litter_sl)
 Adds carbon and nitrogen litter to soil litter pools.
 
lerr_t MeTrX_gas_diffusion ()
 
void MeTrX_liq_diffusion ()
 
lerr_t MeTrX_pertubation ()
 
lerr_t MeTrX_metabolism ()
 
lerr_t MeTrX_dissolution ()
 
void MeTrX_ebullition ()
 
void MeTrX_iron_reduction ()
 
void MeTrX_iron_oxidation ()
 
void MeTrX_algae_dynamics ()
 
void MeTrX_ch4_production ()
 
void MeTrX_ch4_oxidation ()
 
void MeTrX_microbial_dynamics ()
 
void MeTrX_soil_organic_matter_turnover ()
 
lerr_t MeTrX_fermentation ()
 
void MeTrX_urea_hydrolysis ()
 
void MeTrX_pH_calculation ()
 
lerr_t MeTrX_nitrogen_fertilizer_release ()
 Transforms nitrogen from slow release nitrogen fertilizer to nh4. More...
 
void MeTrX_nitrification ()
 
void MeTrX_denitrification ()
 
void MeTrX_chemodenitrification ()
 
void MeTrX_clay_nh4_equilibrium ()
 
void MeTrX_nh3_nh4_equilibrium ()
 
void MeTrX_anaerobic_volume ()
 
double MeTrX_get_ph_sl (size_t)
 Returns dynamic pH-value of given soil layer.
 
double MeTrX_get_ph_wl ()
 
double MeTrX_get_fact_tm_decomp (size_t const &)
 Response function for decomposition of organic matter depeding on temperature and moisture. More...
 
double MeTrX_get_fact_tm_denit (size_t const &)
 Response function for denitrification depending on temperature and moisture.
 
double MeTrX_get_k_mm_x_sl (size_t const &_sl, double const &_k_mm)
 Scales Michaelis-Menten constant according to spatial discretization.
 
double MeTrX_get_c_tot ()
 
double MeTrX_get_n_tot ()
 
lerr_t MeTrX_receive_state ()
 
lerr_t MeTrX_send_state ()
 
lerr_t MeTrX_dissolution_soil (double const &, double &, double &)
 
lerr_t MeTrX_update_soil_discretization ()
 

Static Private Attributes

static const double TNORM = 293.2
 
static const double N_MINERALISATION_FRACTION = 0.5
 

Detailed Description

Biogeochemical model MeTrx.

Member Function Documentation

◆ MeTrX_algae_dynamics()

void ldndc::SoilChemistryMeTrX::MeTrX_algae_dynamics ( )
private
Parameters
[in]None
[out]None
Returns
void

Referenced by solve().

Here is the caller graph for this function:

◆ MeTrX_anaerobic_volume()

void ldndc::SoilChemistryMeTrX::MeTrX_anaerobic_volume ( )
private
Parameters
[in]None
[out]None
Returns
void

Referenced by MeTrX_pertubation(), and solve().

Here is the caller graph for this function:

◆ MeTrX_ch4_oxidation()

void ldndc::SoilChemistryMeTrX::MeTrX_ch4_oxidation ( )
private
Parameters
[in]None
[out]None
Returns
void

Referenced by solve().

Here is the caller graph for this function:

◆ MeTrX_ch4_production()

void ldndc::SoilChemistryMeTrX::MeTrX_ch4_production ( )
private
Parameters
[in]None
[out]None
Returns
void

Referenced by solve().

Here is the caller graph for this function:

◆ MeTrX_chemodenitrification()

void ldndc::SoilChemistryMeTrX::MeTrX_chemodenitrification ( )
private
Parameters
[in]None
[out]None
Returns
void

Referenced by MeTrX_get_fact_tm_denit(), and solve().

Here is the caller graph for this function:

◆ MeTrX_clay_nh4_equilibrium()

void ldndc::SoilChemistryMeTrX::MeTrX_clay_nh4_equilibrium ( )
private
Parameters
[in]None
[out]None
Returns
void

References ldndc::cation_exchange_capacity().

Referenced by solve().

95 {
96  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
97  {
98  /* partitioning coefficient */
99  double const k_nh4( 1.0);
100 
101  /* total mount of n-nh4 [1e3:g] */
102  double const nh4_sol_old( nh4_ae_sl[sl] + nh4_an_sl[sl]);
103  double const nh4_total( nh4_sol_old + sc_.clay_nh4_sl[sl]);
104 
105  /* soil mass [1e3:g] */
106  double const m_soil( sc_.get_soil_mass( sl));
107 
108  /* soil organic matter content [%] */
109  double const som_percentage( sc_.som_sl[sl] / m_soil * 100.0);
110 
111  /* cation exchange capacity [1e-2:mol] */
112  double const cec( cation_exchange_capacity(
113  sc_.clay_sl[sl] * 100.0,
114  sc_.sand_sl[sl] * 100.0,
115  som_percentage,
116  sc_.ph_sl[sl],
117  ECOSYS_GRASSLAND) * m_soil);
118 
119  /* nh4 exchange capacity [kg] */
120  double const nh4_capacity( cec * cbm::MN * 1.0e-5);
121 
122  /* nh4 per soil mass [1e-5:mol:g] */
123  double const nh4_total_percentage( nh4_total * 1.0e5 / (cbm::MN * m_soil));
124 
125  /* adsorbed nh4 percentage [%] */
126  double const nh4_clay_percentage( k_nh4 * nh4_total_percentage);
127 
128  /* adsorbed nh4 */
129  double const nh4_clay( cbm::bound_max( nh4_clay_percentage * 1.0e-2 * nh4_capacity, nh4_total));
130 
131  /* nh4 - clay_nh4 exchange */
132  double const delta_nh4( cbm::flt_greater( nh4_clay, sc_.clay_nh4_sl[sl]) ?
133  (nh4_clay - sc_.clay_nh4_sl[sl]) * MeTrX_get_wfps( sl) * FTS_TOT_ :
134  (nh4_clay - sc_.clay_nh4_sl[sl]) * MeTrX_get_wfps( sl) * 0.1 * FTS_TOT_);
135 
136  sc_.clay_nh4_sl[sl] += delta_nh4;
137  double const nh4_sol_new( nh4_total - sc_.clay_nh4_sl[sl]);
138  if ( cbm::flt_greater_zero( nh4_sol_old))
139  {
140  nh4_ae_sl[sl] = nh4_ae_sl[sl] / nh4_sol_old * nh4_sol_new;
141  nh4_an_sl[sl] = nh4_sol_new - nh4_ae_sl[sl];
142  }
143  else
144  {
145  nh4_ae_sl[sl] = nh4_sol_new * (1.0 - sc_.anvf_sl[sl]);
146  nh4_an_sl[sl] = nh4_sol_new * sc_.anvf_sl[sl];
147  }
148  }
149 }
double LDNDC_API cation_exchange_capacity(double _clay, double _sand, double _som, double _ph, ecosystem_type_e _ecosystem)
Detailed description provided here .
Here is the call graph for this function:
Here is the caller graph for this function:

◆ MeTrX_denitrification()

void ldndc::SoilChemistryMeTrX::MeTrX_denitrification ( )
private
Parameters
[in]None
[out]None
Returns
void

Referenced by solve().

Here is the caller graph for this function:

◆ MeTrX_dissolution()

lerr_t ldndc::SoilChemistryMeTrX::MeTrX_dissolution ( )
private
Parameters
[in]None
[out]None
Returns
error code

Referenced by MeTrX_groundwater_access(), and solve().

Here is the caller graph for this function:

◆ MeTrX_dissolution_soil()

lerr_t ldndc::SoilChemistryMeTrX::MeTrX_dissolution_soil ( double const &  _henry,
double &  _val_gas,
double &  _val_liq 
)
private
Parameters
[in]_henryNone
[in,out]_gasgaseous species
[in,out]_liqdissolved substance
Returns
error code

Referenced by MeTrX_groundwater_access().

525 {
526  double const val_tot( _val_gas + _val_liq);
527  if ( cbm::flt_greater_zero( val_tot))
528  {
529  _val_liq = _henry / (1.0 + _henry) * val_tot;
530  _val_gas = val_tot - _val_liq;
531  }
532  return LDNDC_ERR_OK;
533 }
Here is the caller graph for this function:

◆ MeTrX_ebullition()

void ldndc::SoilChemistryMeTrX::MeTrX_ebullition ( )
private
Parameters
[in]None
[out]None
Returns
void

Referenced by MeTrX_groundwater_access(), and solve().

Here is the caller graph for this function:

◆ MeTrX_fermentation()

lerr_t ldndc::SoilChemistryMeTrX::MeTrX_fermentation ( )
private
Parameters
[in]None
[out]None
Returns
error code

Referenced by solve().

Here is the caller graph for this function:

◆ MeTrX_fertilize()

lerr_t ldndc::SoilChemistryMeTrX::MeTrX_fertilize ( )
private
Parameters
[in]None
[out]None
Returns
error code

Referenced by solve().

34 {
35  EventAttributes const * ev_fert = NULL;
36  while (( ev_fert = this->m_FertilizeEvents.pop()) != NULL)
37  {
38  double new_fertilizer_n( -sc_.accumulated_n_fertilizer);
39  //
40  cbm::string_t const fertilizer = ev_fert->get( "/type", "?");
41  //
42  double const f_depth = ev_fert->get( "/depth", 0.0);
43 
44  // amount of fertilizer [kg:ha-1]
45  double const n_amount( ev_fert->get( "/amount", 0.0));
46 
47  // amount of nitrification inhibitor [kg:ha-1]
48  double const ni_amount( ev_fert->get( "/ni_amount", 0.0));
49 
50  // amount of urease inhibitor [kg:ha-1]
51  double const ui_amount( ev_fert->get( "/ui_amount", 0.0));
52 
53  if ( have_water_table &&
54  cbm::flt_equal_zero( f_depth))
55  {
56  double const n_amount_sbl( n_amount / (cbm::M2_IN_HA * sb_.surfacebulk_layer_cnt()));
57  double const ni_amount_sbl( ni_amount / (cbm::M2_IN_HA * sb_.surfacebulk_layer_cnt()));
58  double const ui_amount_sbl( ui_amount / (cbm::M2_IN_HA * sb_.surfacebulk_layer_cnt()));
59 
60  for (size_t sbl = 0; sbl < sb_.surfacebulk_layer_cnt(); ++sbl)
61  {
62  if ( fertilizer == "nh4no3" )
63  {
64  sb_.nh4_sbl[sbl] += 0.5 * n_amount_sbl;
65  sb_.no3_sbl[sbl] += 0.5 * n_amount_sbl;
66  accumulated_n_nh4_fertilization_sbl[sbl] += 0.5 * n_amount_sbl;
67  accumulated_n_no3_fertilization_sbl[sbl] += 0.5 * n_amount_sbl;
68  sc_.accumulated_n_fertilizer += n_amount_sbl;
69  }
70  else if ( fertilizer == "nh3" )
71  {
72  sb_.nh3_sbl[sbl] += n_amount_sbl;
73  accumulated_n_nh3_fertilization_sbl[sbl] += n_amount_sbl;
74  sc_.accumulated_n_fertilizer += n_amount_sbl;
75  }
76  else if ( fertilizer == "no3" )
77  {
78  sb_.no3_sbl[sbl] += n_amount_sbl;
79  accumulated_n_no3_fertilization_sbl[sbl] += n_amount_sbl;
80  sc_.accumulated_n_fertilizer += n_amount_sbl;
81  }
82  else if (( fertilizer == "nh4" ) || ( fertilizer == "nh4hco3" ) || ( fertilizer == "nh4hpo4" ))
83  {
84  sb_.nh4_sbl[sbl] += n_amount_sbl;
85  accumulated_n_nh4_fertilization_sbl[sbl] += n_amount_sbl;
86  sc_.accumulated_n_fertilizer += n_amount_sbl;
87  }
88  else if ( fertilizer == "nh4so4" )
89  {
90  sb_.so4_sbl[sbl] += n_amount_sbl * (cbm::MS / cbm::MN);
91  sb_.nh4_sbl[sbl] += n_amount_sbl;
92  accumulated_n_nh4_fertilization_sbl[sbl] += n_amount_sbl;
93  sc_.accumulated_n_fertilizer += n_amount_sbl;
94  }
95  else if ( fertilizer == "so4" )
96  {
97  sb_.so4_sbl[sbl] += n_amount_sbl;
98  }
99  else if ( fertilizer == "urea" )
100  {
101  sb_.urea_sbl[sbl] += n_amount_sbl;
102  accumulated_n_urea_fertilization_sbl[sbl] += n_amount_sbl;
103  sc_.accumulated_n_fertilizer += n_amount_sbl;
104  }
105  /* controled release nitrogen fertilizer */
106  else if ( fertilizer == "crnf" )
107  {
108  crnf_.add_crnf( n_amount_sbl);
109  sb_.coated_nh4_sbl[sbl] += n_amount_sbl;
110  sc_.accumulated_n_fertilizer += n_amount_sbl;
111  }
112  else
113  {
114  KLOGWARN( "Unknown fertilizer type \"",fertilizer,"\". Ignoring event!");
115  }
116 
117  sb_.ni_sbl[sbl] += ni_amount_sbl;
118  sb_.ui_sbl[sbl] += ui_amount_sbl;
119  crnf_.add_nitrification_inhibitior( ni_amount_sbl);
120  crnf_.add_urease_inhibitior( ui_amount_sbl);
121  }
122  }
123  else
124  {
125  size_t l_0( 0);
126  size_t l_1( 1);
127  if ( cbm::flt_equal_zero( f_depth))
128  {
129  l_0 = 0;
130  l_1 = 1;
131  for( size_t sl = 1; sl < sl_.soil_layer_cnt(); ++sl)
132  {
133  if ( sc_.depth_sl[sl] <= 0.01)
134  {
135  l_1 = sl;
136  }
137  else{ break; }
138  }
139  }
140  else
141  {
142  //l_0 not allowed to be deeper than last but one soil layer
143  l_0 = sl_.soil_layer_cnt()-2;
144  //find first layer (from top) having at least depth <depth(fert)>
145  for ( size_t l = 0; l < sl_.soil_layer_cnt()-1; ++l)
146  {
147  if ( cbm::flt_greater_equal( sc_.depth_sl[l], f_depth))
148  {
149  l_0 = l;
150  break;
151  }
152  }
153  //l_1 must at least one layer below l_0
154  l_1 = l_0 + 1;
155  for ( size_t l = l_0 + 1; l < sl_.soil_layer_cnt(); ++l)
156  {
157  /* distribute at least among 4cm soil profile */
158  if ( cbm::flt_greater_equal( sc_.depth_sl[l], f_depth + 0.04))
159  {
160  l_1 = l;
161  break;
162  }
163  }
164  }
165 
166  double const n_amount_per_layer = (n_amount / cbm::M2_IN_HA) / (double)( l_1 - l_0);
167  double const ni_amount_per_layer = (ni_amount / cbm::M2_IN_HA) / (double)( l_1 - l_0);
168  double const ui_amount_per_layer = (ui_amount / cbm::M2_IN_HA) / (double)( l_1 - l_0);
169 
170  for ( size_t sl = l_0; sl < l_1; ++sl)
171  {
172  if ( fertilizer == "nh4no3" )
173  {
174  nh4_ae_sl[sl] += 0.5 * n_amount_per_layer * (1.0 - sc_.anvf_sl[sl]);
175  nh4_an_sl[sl] += 0.5 * n_amount_per_layer * sc_.anvf_sl[sl];
176  no3_ae_sl[sl] += 0.5 * n_amount_per_layer * (1.0 - sc_.anvf_sl[sl]);
177  no3_an_sl[sl] += 0.5 * n_amount_per_layer * sc_.anvf_sl[sl];
178  accumulated_n_nh4_fertilization_sl[sl] += 0.5 * n_amount_per_layer;
179  accumulated_n_no3_fertilization_sl[sl] += 0.5 * n_amount_per_layer;
180  sc_.accumulated_n_fertilizer += n_amount_per_layer;
181  }
182  else if ( fertilizer == "nh3" )
183  {
184  sc_.nh3_liq_sl[sl] += n_amount_per_layer;
185  accumulated_n_nh3_fertilization_sl[sl] += n_amount_per_layer;
186  sc_.accumulated_n_fertilizer += n_amount_per_layer;
187  }
188  else if ( fertilizer == "no3" )
189  {
190  no3_ae_sl[sl] += n_amount_per_layer * (1.0 - sc_.anvf_sl[sl]);
191  no3_an_sl[sl] += n_amount_per_layer * sc_.anvf_sl[sl];
192  accumulated_n_no3_fertilization_sl[sl] += n_amount_per_layer;
193  sc_.accumulated_n_fertilizer += n_amount_per_layer;
194  }
195  else if (( fertilizer == "nh4" ) || ( fertilizer == "nh4hco3" ) || ( fertilizer == "nh4hpo4" ))
196  {
197  nh4_ae_sl[sl] += n_amount_per_layer * (1.0 - sc_.anvf_sl[sl]);
198  nh4_an_sl[sl] += n_amount_per_layer * sc_.anvf_sl[sl];
199  accumulated_n_nh4_fertilization_sl[sl] += n_amount_per_layer;
200  sc_.accumulated_n_fertilizer += n_amount_per_layer;
201  }
202  else if ( fertilizer == "nh4so4" )
203  {
204  sc_.so4_sl[sl] += n_amount_per_layer * (cbm::MS / cbm::MN);
205  nh4_ae_sl[sl] += n_amount_per_layer * (1.0 - sc_.anvf_sl[sl]);
206  nh4_an_sl[sl] += n_amount_per_layer * sc_.anvf_sl[sl];
207  accumulated_n_nh4_fertilization_sl[sl] += n_amount_per_layer;
208  sc_.accumulated_n_fertilizer += n_amount_per_layer;
209  }
210  else if ( fertilizer == "so4" )
211  {
212  sc_.so4_sl[sl] += n_amount_per_layer;
213  }
214  else if ( fertilizer == "urea" )
215  {
216  sc_.urea_sl[sl] += n_amount_per_layer;
217  accumulated_n_urea_fertilization_sl[sl] += n_amount_per_layer;
218  sc_.accumulated_n_fertilizer += n_amount_per_layer;
219  }
220  /* controled release nitrogen fertilizer */
221  else if ( fertilizer == "crnf" )
222  {
223  crnf_.add_crnf( n_amount_per_layer);
224  sc_.coated_nh4_sl[sl] += n_amount_per_layer;
225  accumulated_n_nh4_fertilization_sl[sl] += n_amount_per_layer;
226  sc_.accumulated_n_fertilizer += n_amount_per_layer;
227  }
228  else
229  {
230  KLOGWARN( "Unknown fertilizer type \"",fertilizer,"\". Skipping event!");
231  break;
232  }
233 
234  sc_.ni_sl[sl] += ni_amount_per_layer;
235  sc_.ui_sl[sl] += ui_amount_per_layer;
236  crnf_.add_nitrification_inhibitior( ni_amount_per_layer);
237  crnf_.add_urease_inhibitior( ui_amount_per_layer);
238  }
239  }
240 
241  cbm::state_scratch_t * mcom = io_kcomm->get_scratch();
242 
243  new_fertilizer_n += sc_.accumulated_n_fertilizer;
244  double old_fertilizer_n( 0.0);
245  mcom->get( "fertilize:amount", &old_fertilizer_n, 0.0);
246  mcom->set( "fertilize:amount", old_fertilizer_n + (new_fertilizer_n * cbm::M2_IN_HA));
247  }
248 
249  return LDNDC_ERR_OK;
250 }
Here is the caller graph for this function:

◆ MeTrX_fragmentation()

lerr_t ldndc::SoilChemistryMeTrX::MeTrX_fragmentation ( )
private
Parameters
[in]None
[out]None
Returns
error code

References MeTrX_get_fact_tm_decomp(), and MeTrX_litter_distribution().

Referenced by solve().

25 {
26  /***************/
27  /* wood litter */
28  /***************/
29 
30  /* aboveground wood litter */
31  if ( cbm::flt_greater_zero( sc_.c_wood) ||
32  cbm::flt_greater_zero( sc_.n_wood))
33  {
34  double const k_frag_wood_tm( K_FRAG_WOOD * MeTrX_get_fact_tm_decomp( 0));
35  double const frag_c_wood( k_frag_wood_tm * sc_.c_wood);
36  double const frag_n_wood( k_frag_wood_tm * sc_.n_wood);
37 
38  sc_.c_wood -= frag_c_wood;
39  sc_.n_wood -= frag_n_wood;
40 
41  sc_.c_raw_lit_2_above += 0.5 * frag_c_wood;
42  sc_.c_raw_lit_3_above += 0.5 * frag_c_wood;
43 
44  sc_.n_raw_lit_2_above += 0.5 * frag_n_wood;
45  sc_.n_raw_lit_3_above += 0.5 * frag_n_wood;
46 
47  if ( spinup_.spinup_stage( this->lclock()))
48  {
49  spinup_.exit_wood += frag_c_wood;
50  }
51  }
52 
53 
54  /* belowground wood litter */
55  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
56  {
57  if ( cbm::flt_greater_zero( sc_.c_wood_sl[sl]) ||
58  cbm::flt_greater_zero( sc_.n_wood_sl[sl]))
59  {
60  double const frag_c_wood( K_FRAG_WOOD * MeTrX_get_fact_tm_decomp( sl) * sc_.c_wood_sl[sl]);
61  double const frag_n_wood( K_FRAG_WOOD * MeTrX_get_fact_tm_decomp( sl) * sc_.n_wood_sl[sl]);
62 
63  sc_.c_wood_sl[sl] -= frag_c_wood;
64  sc_.n_wood_sl[sl] -= frag_n_wood;
65 
66  sc_.c_raw_lit_2_sl[sl] += 0.5 * frag_c_wood;
67  sc_.c_raw_lit_3_sl[sl] += 0.5 * frag_c_wood;
68 
69  sc_.n_raw_lit_2_sl[sl] += 0.5 * frag_n_wood;
70  sc_.n_raw_lit_3_sl[sl] += 0.5 * frag_n_wood;
71  }
72  }
73 
74 
75  /******************/
76  /* stubble litter */
77  /******************/
78 
79  if ( cbm::flt_greater_zero( sc_.c_stubble_lit1 + sc_.c_stubble_lit2 + sc_.c_stubble_lit3))
80  {
81  double const k_frag_stubble_tm( K_FRAG_STUBBLE * MeTrX_get_fact_tm_decomp( 0));
82  double const c_senescence_lit1( k_frag_stubble_tm * sc_.c_stubble_lit1);
83  double const c_senescence_lit2( k_frag_stubble_tm * sc_.c_stubble_lit2);
84  double const c_senescence_lit3( k_frag_stubble_tm * sc_.c_stubble_lit3);
85 
86  double const n_senescence_lit1( k_frag_stubble_tm * sc_.n_stubble_lit1);
87  double const n_senescence_lit2( k_frag_stubble_tm * sc_.n_stubble_lit2);
88  double const n_senescence_lit3( k_frag_stubble_tm * sc_.n_stubble_lit3);
89 
90  sc_.c_stubble_lit1 -= c_senescence_lit1;
91  sc_.c_stubble_lit2 -= c_senescence_lit2;
92  sc_.c_stubble_lit3 -= c_senescence_lit3;
93 
94  sc_.n_stubble_lit1 -= n_senescence_lit1;
95  sc_.n_stubble_lit2 -= n_senescence_lit2;
96  sc_.n_stubble_lit3 -= n_senescence_lit3;
97 
98  sc_.c_raw_lit_1_above += c_senescence_lit1;
99  sc_.c_raw_lit_2_above += c_senescence_lit2;
100  sc_.c_raw_lit_3_above += c_senescence_lit3;
101 
102  sc_.n_raw_lit_1_above += n_senescence_lit1;
103  sc_.n_raw_lit_2_above += n_senescence_lit2;
104  sc_.n_raw_lit_3_above += n_senescence_lit3;
105  }
106 
107 
108  /**************/
109  /* raw litter */
110  /**************/
111 
112  /* aboveground */
113  if ( cbm::flt_greater_zero( sc_.c_raw_lit_1_above + sc_.c_raw_lit_2_above + sc_.c_raw_lit_3_above))
114  {
115  double const k_frag_raw_litter_tm( K_FRAG_RAW_LITTER * MeTrX_get_fact_tm_decomp( 0));
116  double const c_senescence_lit1( k_frag_raw_litter_tm * sc_.c_raw_lit_1_above);
117  double const c_senescence_lit2( k_frag_raw_litter_tm * sc_.c_raw_lit_2_above);
118  double const c_senescence_lit3( k_frag_raw_litter_tm * sc_.c_raw_lit_3_above);
119 
120  double const n_senescence_lit1( k_frag_raw_litter_tm * sc_.n_raw_lit_1_above);
121  double const n_senescence_lit2( k_frag_raw_litter_tm * sc_.n_raw_lit_2_above);
122  double const n_senescence_lit3( k_frag_raw_litter_tm * sc_.n_raw_lit_3_above);
123 
124  sc_.c_raw_lit_1_above -= c_senescence_lit1;
125  sc_.c_raw_lit_2_above -= c_senescence_lit2;
126  sc_.c_raw_lit_3_above -= c_senescence_lit3;
127 
128  sc_.n_raw_lit_1_above -= n_senescence_lit1;
129  sc_.n_raw_lit_2_above -= n_senescence_lit2;
130  sc_.n_raw_lit_3_above -= n_senescence_lit3;
131 
132  MeTrX_litter_distribution( n_senescence_lit1, n_senescence_lit2, n_senescence_lit3,
133  c_senescence_lit1, c_senescence_lit2, c_senescence_lit3,
134  accumulated_n_aboveground_raw_litter_fragmentation_sl);
135  }
136 
137  /* belowground */
138  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
139  {
140  if ( cbm::flt_greater_zero( sc_.c_raw_lit_1_sl[sl]))
141  {
142  double const fact_decomp( K_FRAG_RAW_LITTER * MeTrX_get_fact_tm_decomp( sl));
143  double const c_decomp_lit1( fact_decomp * sc_.c_raw_lit_1_sl[sl]);
144  double const c_decomp_lit2( fact_decomp * sc_.c_raw_lit_2_sl[sl]);
145  double const c_decomp_lit3( fact_decomp * sc_.c_raw_lit_3_sl[sl]);
146 
147  double const n_decomp_lit1( fact_decomp * sc_.n_raw_lit_1_sl[sl]);
148  double const n_decomp_lit2( fact_decomp * sc_.n_raw_lit_2_sl[sl]);
149  double const n_decomp_lit3( fact_decomp * sc_.n_raw_lit_3_sl[sl]);
150 
151  sc_.c_raw_lit_1_sl[sl] -= c_decomp_lit1;
152  sc_.c_raw_lit_2_sl[sl] -= c_decomp_lit2;
153  sc_.c_raw_lit_3_sl[sl] -= c_decomp_lit3;
154 
155  sc_.n_raw_lit_1_sl[sl] -= n_decomp_lit1;
156  sc_.n_raw_lit_2_sl[sl] -= n_decomp_lit2;
157  sc_.n_raw_lit_3_sl[sl] -= n_decomp_lit3;
158 
159  sc_.C_lit1_sl[sl] += c_decomp_lit1;
160  sc_.C_lit2_sl[sl] += c_decomp_lit2;
161  sc_.C_lit3_sl[sl] += c_decomp_lit3;
162 
163  sc_.N_lit1_sl[sl] += n_decomp_lit1;
164  sc_.N_lit2_sl[sl] += n_decomp_lit2;
165  sc_.N_lit3_sl[sl] += n_decomp_lit3;
166 
167  accumulated_n_belowground_raw_litter_fragmentation_sl[sl] += n_decomp_lit1 + n_decomp_lit2 + n_decomp_lit3;
168  }
169  }
170 
171 
172  /****************/
173  /* algae litter */
174  /****************/
175 
176  if ( cbm::flt_greater_zero( c_dead_algae) ||
177  cbm::flt_greater_zero( n_dead_algae))
178  {
179  double const fact_decomp( K_FRAG_ALGAE * MeTrX_get_fact_tm_decomp( 0));
180  double const c_decomp_algae( fact_decomp * c_dead_algae);
181  double const n_decomp_algae( fact_decomp * n_dead_algae);
182 
183  c_dead_algae -= c_decomp_algae;
184  n_dead_algae -= n_decomp_algae;
185 
186  MeTrX_litter_distribution( 0.25 * n_decomp_algae, 0.7 * n_decomp_algae, 0.05 * n_decomp_algae,
187  0.25 * c_decomp_algae, 0.7 * c_decomp_algae, 0.05 * c_decomp_algae,
188  accumulated_n_litter_from_algae_sl);
189 
190  dC_litter_algae += c_decomp_algae;
191 
192  if ( !cbm::flt_greater_zero( c_dead_algae))
193  {
194  c_dead_algae = 0.0;
195  }
196  if ( !cbm::flt_greater_zero( n_dead_algae))
197  {
198  n_dead_algae = 0.0;
199  }
200  }
201 
202 
203  /******************/
204  /* dung and urine */
205  /******************/
206 
207  if ( cbm::flt_greater_zero( sc_.c_dung) ||
208  cbm::flt_greater_zero( sc_.n_dung) ||
209  cbm::flt_greater_zero( sc_.n_urine))
210  {
211  MeTrX_litter_distribution( 0.25 * sc_.n_dung, 0.7 * sc_.n_dung, 0.05 * sc_.n_dung,
212  0.25 * sc_.c_dung, 0.7 * sc_.c_dung, 0.05 * sc_.c_dung,
213  accumulated_n_litter_from_dung_sl);
214 
215  for( size_t sl = 0; sl <= SL_SURFACE_DISTRIBUTION; ++sl)
216  {
217  sc_.urea_sl[sl] += sc_.n_urine * SL_SURFACE_DISTRIBUTION_INVERSE;
218  accumulated_n_urea_from_dung_sl[sl] += sc_.n_urine * SL_SURFACE_DISTRIBUTION_INVERSE;
219  }
220 
221  sc_.accumulated_c_livestock_grazing += sc_.c_dung;
222  sc_.accumulated_n_livestock_grazing += sc_.n_dung + sc_.n_urine;
223 
224  sc_.c_dung = 0.0;
225  sc_.n_dung = 0.0;
226  sc_.n_urine = 0.0;
227  }
228 
229  return LDNDC_ERR_OK;
230 }
double MeTrX_get_fact_tm_decomp(size_t const &)
Response function for decomposition of organic matter depeding on temperature and moisture...
Definition: soilchemistry-metrx-decomposition.cpp:661
void MeTrX_litter_distribution(double const &, double const &, double const &, double const &, double const &, double const &, CBM_Vector< double > &accumulated_litter_sl)
Adds carbon and nitrogen litter to soil litter pools.
Definition: soilchemistry-metrx-fragmentation.cpp:238
Here is the call graph for this function:
Here is the caller graph for this function:

◆ MeTrX_freeze_thaw()

lerr_t ldndc::SoilChemistryMeTrX::MeTrX_freeze_thaw ( )
private
Parameters
[in]None
[out]None
Returns
error code

Referenced by solve().

395 {
396  if ( have_freeze_thaw)
397  {
398  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
399  {
400  if (false)
401  {
402  if ( cbm::flt_greater_zero( v_ice_sl[sl]) &&
403  cbm::flt_greater( mc_temp_sl[sl], -0.5))
404  {
405  freeze_thaw_fact_sl[sl] = 1.0;
406  }
407  else if (freeze_thaw_fact_sl[sl] > 0.1)
408  {
409  freeze_thaw_fact_sl[sl] -= 0.3 * FTS_TOT_ * freeze_thaw_fact_sl[sl];
410  }
411  else
412  {
413  freeze_thaw_fact_sl[sl] = 0.0;
414  }
415  }
416 
417  if ( cbm::flt_greater_zero( v_ice_sl[sl]) &&
418  cbm::flt_less_equal( mc_temp_sl[sl], 0.0))
419  {
420  cumulative_freezing_degree_days_sl[sl] += std::abs( mc_temp_sl[sl]) * FTS_TOT_;
421  }
422  else if (cbm::flt_equal_zero( v_ice_sl[sl]) &&
423  cbm::flt_greater_zero( mc_temp_sl[sl]))
424  {
425  if ( cumulative_freezing_degree_days_sl[sl] > 10.0)
426  {
427  double c_decomp_aorg( cbm::bound( 0.0, cumulative_freezing_degree_days_sl[sl] / 400.0, 0.99) * sc_.C_aorg_sl[sl]);
428  double n_decomp_aorg( cbm::bound( 0.0, cumulative_freezing_degree_days_sl[sl] / 400.0, 0.99) * sc_.N_aorg_sl[sl]);
429  sc_.C_aorg_sl[sl] -= c_decomp_aorg;
430  sc_.N_aorg_sl[sl] -= n_decomp_aorg;
431 
432  sc_.an_doc_sl[sl] += c_decomp_aorg * sc_.anvf_sl[sl];
433  sc_.doc_sl[sl] += c_decomp_aorg * (1.0 - sc_.anvf_sl[sl]);
434 
435  don_ae_sl[sl] += (1.0 - sipar_.METRX_FRAC_MINERAL()) * n_decomp_aorg * (1.0 - sc_.anvf_sl[sl]);
436  don_an_sl[sl] += (1.0 - sipar_.METRX_FRAC_MINERAL()) * n_decomp_aorg * sc_.anvf_sl[sl];
437 
438  nh4_ae_sl[sl] += sipar_.METRX_FRAC_MINERAL() * n_decomp_aorg * (1.0 - sc_.anvf_sl[sl]);
439  nh4_an_sl[sl] += sipar_.METRX_FRAC_MINERAL() * n_decomp_aorg * sc_.anvf_sl[sl];
440  }
441 
442  cumulative_freezing_degree_days_sl[sl] = 0.0;
443  }
444  }
445  }
446 
447  return LDNDC_ERR_OK;
448 }
Here is the caller graph for this function:

◆ MeTrX_gas_diffusion()

lerr_t ldndc::SoilChemistryMeTrX::MeTrX_gas_diffusion ( )
private
Parameters
[in]None
[out]None
Returns
error code

Referenced by MeTrX_groundwater_access(), and solve().

Here is the caller graph for this function:

◆ MeTrX_get_c_tot()

double ldndc::SoilChemistryMeTrX::MeTrX_get_c_tot ( )
private
Parameters
[in]None
[out]None
Returns
Total soil associated carbon

References MeTrX_get_n_tot().

62 {
63  double c_tot( c_algae + c_dead_algae + sc_.c_wood
64  + sc_.c_stubble_lit1 + sc_.c_stubble_lit2 + sc_.c_stubble_lit3
65  + sc_.c_raw_lit_1_above + sc_.c_raw_lit_2_above + sc_.c_raw_lit_3_above);
66 
67  for (size_t sl = 0; sl < sl_.soil_layer_cnt(); sl++)
68  {
69  c_tot += ( sc_.c_wood_sl[sl]
70  + sc_.doc_sl[sl] + sc_.an_doc_sl[sl] + doc_ice_sl[sl]
71  + ae_acetate_sl[sl] + an_acetate_sl[sl] + acetate_ice_sl[sl]
72  + sc_.C_micro1_sl[sl] + sc_.C_micro2_sl[sl] + sc_.C_micro3_sl[sl]
73  + sc_.C_aorg_sl[sl] + c_microbial_necromass_sl[sl]
74  + c_humus_1_sl[sl] + c_humus_2_sl[sl] + c_humus_3_sl[sl]
75  + sc_.C_lit1_sl[sl] + sc_.C_lit2_sl[sl] + sc_.C_lit3_sl[sl]
76  + sc_.c_raw_lit_1_sl[sl] + sc_.c_raw_lit_2_sl[sl] + sc_.c_raw_lit_3_sl[sl]
77  + ch4_gas_sl[sl] + ch4_liq_sl[sl]
78  + co2_gas_sl[sl] + co2_liq_sl[sl]);
79  }
80 
81  for (size_t sbl = 0; sbl < sb_.surfacebulk_layer_cnt(); ++sbl)
82  {
83  c_tot += sb_.ch4_sbl[sbl] + sb_.co2_sbl[sbl] + sb_.doc_sbl[sbl];
84  }
85 
86  return c_tot;
87 }
Here is the call graph for this function:

◆ MeTrX_get_fact_tm_decomp()

double ldndc::SoilChemistryMeTrX::MeTrX_get_fact_tm_decomp ( size_t const &  _sl)
private

Response function for decomposition of organic matter depeding on temperature and moisture.

Parameters
[in]_slsoil layer
[out]None
Returns
requested factor

Referenced by MeTrX_fragmentation().

662 {
663  double const fact_t( std::exp( -sipar_.METRX_F_DECOMP_T_EXP_1() *
664  pow(1.0 - mc_temp_sl[_sl] / sipar_.METRX_F_DECOMP_T_EXP_2(), 2.0)));
665  double const fact_m( ldndc::meteo::F_weibull( MeTrX_get_wfps_eff( _sl, 0.0),
666  sipar_.METRX_F_DECOMP_M_WEIBULL_1(),
667  sipar_.METRX_F_DECOMP_M_WEIBULL_2(),
668  1.0));
669  return cbm::harmonic_mean2( fact_t, fact_m);
670 }
Here is the caller graph for this function:

◆ MeTrX_get_n_tot()

double ldndc::SoilChemistryMeTrX::MeTrX_get_n_tot ( )
private
Parameters
[in]None
[out]None
Returns
Total soil associated nitrogen

Referenced by MeTrX_get_c_tot().

19 {
20  double n_tot( n_algae + n_dead_algae + sc_.n_wood
21  + sc_.n_stubble_lit1 + sc_.n_stubble_lit2 + sc_.n_stubble_lit3
22  + sc_.n_raw_lit_1_above + sc_.n_raw_lit_2_above + sc_.n_raw_lit_3_above);
23 
24  for (size_t sl = 0; sl < sl_.soil_layer_cnt(); sl++)
25  {
26  n_tot += ( sc_.n_wood_sl[sl]
27  + nh4_ae_sl[sl] + nh4_an_sl[sl] + sc_.clay_nh4_sl[sl] + sc_.coated_nh4_sl[sl] + nh4_ice_sl[sl]
28  + sc_.nh3_liq_sl[sl] + sc_.nh3_gas_sl[sl] + sc_.urea_sl[sl]
29  + no3_ae_sl[sl] + no3_an_sl[sl] + no3_ice_sl[sl]
30  + sc_.no2_sl[sl] + sc_.an_no2_sl[sl]
31  + don_ae_sl[sl] + don_an_sl[sl] + don_ice_sl[sl]
32  + no_gas_sl[sl] + an_no_gas_sl[sl] + no_liq_sl[sl] + an_no_liq_sl[sl]
33  + n2o_gas_sl[sl] + an_n2o_gas_sl[sl] + n2o_liq_sl[sl] + an_n2o_liq_sl[sl]
34  + sc_.N_lit1_sl[sl] + sc_.N_lit2_sl[sl] + sc_.N_lit3_sl[sl]
35  + sc_.n_raw_lit_1_sl[sl] + sc_.n_raw_lit_2_sl[sl] + sc_.n_raw_lit_3_sl[sl]
36  + n_micro_1_sl[sl] + n_micro_2_sl[sl] + n_micro_3_sl[sl]
37  + sc_.N_aorg_sl[sl] + n_microbial_necromass_sl[sl]
38  + n_humus_1_sl[sl] + n_humus_2_sl[sl] + n_humus_3_sl[sl]);
39  }
40 
41  for (size_t sbl = 0; sbl < sb_.surfacebulk_layer_cnt(); ++sbl)
42  {
43  n_tot += sb_.nh4_sbl[sbl] + sb_.coated_nh4_sbl[sbl]
44  + sb_.no3_sbl[sbl] + sb_.don_sbl[sbl]
45  + sb_.nh3_sbl[sbl] + sb_.urea_sbl[sbl]
46  + sb_.n2o_sbl[sbl] + sb_.no_sbl[sbl];
47  }
48 
49  n_tot += nh3_fl.sum();
50 
51  return n_tot;
52 }
Here is the caller graph for this function:

◆ MeTrX_get_ph_wl()

double ldndc::SoilChemistryMeTrX::MeTrX_get_ph_wl ( )
private
Parameters
[in]None
[out]None
Returns
double

Referenced by MeTrX_nh3_nh4_equilibrium(), MeTrX_write_output_daily(), MeTrX_write_output_layer_daily(), and MeTrX_write_output_subdaily().

529 {
530  if ( cbm::flt_greater_zero( wc_.surface_water))
531  {
532  return cbm::bound( PH_SURFACE_WATER, PH_SURFACE_WATER + ph_delta_pab_wl + ph_delta_urea_wl, PH_MAX);
533  }
534  else
535  {
536  return 7.0;
537  }
538 }
Here is the caller graph for this function:

◆ MeTrX_groundwater_access()

void ldndc::SoilChemistryMeTrX::MeTrX_groundwater_access ( )
private
Parameters
[in]None
[out]None
Returns
void
  • exchange of soil no3 <-> groundwater no3
  • only calculated in case of valid groundwater input

References MeTrX_dissolution(), MeTrX_dissolution_soil(), MeTrX_ebullition(), MeTrX_gas_diffusion(), and MeTrX_liq_diffusion().

Referenced by solve().

543 {
544  if ( gw_ != NULL)
545  {
546  for ( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
547  {
548  if ( sc_.depth_sl[sl] > gw_->watertable_subday( lclock_ref()))
549  {
550  double const no3_gw( gw_->no3_day(lclock_ref()) //given in (mg no3 L-1)
551  * cbm::MN / (cbm::MN + 3.0 * cbm::MO) * cbm::KG_IN_MG //converts no3 from (mg no3) -> (kg n-no3)
552  * (wc_.wc_sl[sl] + wc_.ice_sl[sl]) * sc_.h_sl[sl] * cbm::DM3_IN_M3); //converts water (m3) -> (L)
553 
554  if ( cbm::flt_greater_zero( no3_gw))
555  {
556  double const no3_diff( GROUNDWATER_NUTRIENT_ACCESS_RATE * (no3_gw - no3_an_sl[sl]));
557  no3_an_sl[sl] += no3_diff;
558  day_no3_groundwater_access += no3_diff;
559  sc_.accumulated_no3_leach -= no3_diff;
560  sc_.accumulated_n_no3_leaching_sl[sl] -= no3_diff;
561  }
562  }
563  }
564 
565  if ( have_river_connection)
566  {
567  if ( have_water_table)
568  {
569  for (size_t sbl = 0; sbl < sb_.surfacebulk_layer_cnt(); ++sbl)
570  {
571  DISSOLUTION_ATMOSPHERE( MeTrX_get_atm_eq_liq( o2_atm_eq_liq, h_wl), sb_.o2_sbl[sbl], subdaily_o2_water[subdaily_time_step_]);
572  DISSOLUTION_ATMOSPHERE( MeTrX_get_atm_eq_liq( ch4_atm_eq_liq, h_wl), sb_.ch4_sbl[sbl], subdaily_ch4_water[subdaily_time_step_]);
573  DISSOLUTION_ATMOSPHERE( MeTrX_get_atm_eq_liq( co2_atm_eq_liq, h_wl), sb_.co2_sbl[sbl], subdaily_co2_water[subdaily_time_step_]);
574  DISSOLUTION_ATMOSPHERE( MeTrX_get_atm_eq_liq( nh3_atm_eq_liq, h_wl), sb_.nh3_sbl[sbl], subdaily_nh3_water[subdaily_time_step_]);
575  DISSOLUTION_ATMOSPHERE( MeTrX_get_atm_eq_liq( no_atm_eq_liq, h_wl), sb_.no_sbl[sbl], subdaily_no_water[subdaily_time_step_]);
576  DISSOLUTION_ATMOSPHERE( MeTrX_get_atm_eq_liq( n2o_atm_eq_liq, h_wl), sb_.n2o_sbl[sbl], subdaily_n2o_water[subdaily_time_step_]);
577  }
578  }
579  }
580  }
581 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ MeTrX_iron_oxidation()

void ldndc::SoilChemistryMeTrX::MeTrX_iron_oxidation ( )
private
Parameters
[in]None
[out]None
Returns
void

Referenced by solve().

Here is the caller graph for this function:

◆ MeTrX_iron_reduction()

void ldndc::SoilChemistryMeTrX::MeTrX_iron_reduction ( )
private
Parameters
[in]None
[out]None
Returns
void

Referenced by solve().

Here is the caller graph for this function:

◆ MeTrX_leaching()

void ldndc::SoilChemistryMeTrX::MeTrX_leaching ( )
private

Downwards transport of solutes, litter and humus with percolation water.

Parameters
[in]None
[out]None
Returns
void

Referenced by solve().

25 {
26  /*************************/
27  /* Water table transport */
28  /*************************/
29 
30  if ( have_water_table &&
31  cbm::flt_greater_zero( infiltration))
32  {
33  ldndc_kassert( h_wl > 0.0);
34 
35  accumulated_n_nh4_infiltration_leach_sl[0] -= nh4_an_sl[0] + sc_.coated_nh4_sl[0];
36  accumulated_n_nh3_infiltration_leach_sl[0] -= sc_.nh3_liq_sl[0];
37  accumulated_n_no_infiltration_leach_sl[0] -= an_no_liq_sl[0];
38  accumulated_n_n2o_infiltration_leach_sl[0] -= an_n2o_liq_sl[0];
39  accumulated_n_urea_infiltration_leach_sl[0] -= sc_.urea_sl[0];
40  accumulated_n_no3_infiltration_leach_sl[0] -= no3_an_sl[0];
41  accumulated_n_don_infiltration_leach_sl[0] -= don_an_sl[0];
42 
43  double const leach_fact_sbl( cbm::bound_max( infiltration / h_wl, 0.99));
44  LEACH_DOWN( sb_.ch4_sbl[0], ch4_liq_sl[0], leach_fact_sbl);
45  LEACH_DOWN( sb_.o2_sbl[0], o2_liq_sl[0], leach_fact_sbl);
46  LEACH_DOWN( sb_.nh4_sbl[0], nh4_an_sl[0], leach_fact_sbl);
47  LEACH_DOWN( sb_.coated_nh4_sbl[0], sc_.coated_nh4_sl[0], leach_fact_sbl);
48  LEACH_DOWN( sb_.nh3_sbl[0], sc_.nh3_liq_sl[0], leach_fact_sbl);
49  LEACH_DOWN( sb_.no_sbl[0], an_no_liq_sl[0], leach_fact_sbl);
50  LEACH_DOWN( sb_.n2o_sbl[0], an_n2o_liq_sl[0], leach_fact_sbl);
51  LEACH_DOWN( sb_.urea_sbl[0], sc_.urea_sl[0], leach_fact_sbl);
52  LEACH_DOWN( sb_.no3_sbl[0], no3_an_sl[0], leach_fact_sbl);
53  LEACH_DOWN( sb_.don_sbl[0], don_an_sl[0], leach_fact_sbl);
54  LEACH_DOWN( sb_.doc_sbl[0], sc_.doc_sl[0], leach_fact_sbl);
55  LEACH_DOWN( sb_.co2_sbl[0], co2_liq_sl[0], leach_fact_sbl);
56  LEACH_DOWN( sb_.so4_sbl[0], sc_.so4_sl[0], leach_fact_sbl);
57  LEACH_DOWN( sb_.ni_sbl[0], sc_.ni_sl[0], leach_fact_sbl);
58  LEACH_DOWN( sb_.ui_sbl[0], sc_.ui_sl[0], leach_fact_sbl);
59 
60  accumulated_n_nh4_infiltration_leach_sl[0] += nh4_an_sl[0] + sc_.coated_nh4_sl[0];
61  accumulated_n_nh3_infiltration_leach_sl[0] += sc_.nh3_liq_sl[0];
62  accumulated_n_no_infiltration_leach_sl[0] += an_no_liq_sl[0];
63  accumulated_n_n2o_infiltration_leach_sl[0] += an_n2o_liq_sl[0];
64  accumulated_n_urea_infiltration_leach_sl[0] += sc_.urea_sl[0];
65  accumulated_n_no3_infiltration_leach_sl[0] += no3_an_sl[0];
66  accumulated_n_don_infiltration_leach_sl[0] += don_an_sl[0];
67 
68  for (size_t sbl = 1; sbl < sb_.surfacebulk_layer_cnt(); ++sbl)
69  {
70  size_t const sbl_plus( sbl - 1);
71  LEACH_DOWN( sb_.ch4_sbl[sbl], sb_.ch4_sbl[sbl_plus], leach_fact_sbl);
72  LEACH_DOWN( sb_.o2_sbl[sbl], sb_.o2_sbl[sbl_plus], leach_fact_sbl);
73  LEACH_DOWN( sb_.nh4_sbl[sbl], sb_.nh4_sbl[sbl_plus], leach_fact_sbl);
74  LEACH_DOWN( sb_.coated_nh4_sbl[sbl], sb_.coated_nh4_sbl[sbl_plus], leach_fact_sbl);
75  LEACH_DOWN( sb_.nh3_sbl[sbl], sb_.nh3_sbl[sbl_plus], leach_fact_sbl);
76  LEACH_DOWN( sb_.no_sbl[sbl], sb_.no_sbl[sbl_plus], leach_fact_sbl);
77  LEACH_DOWN( sb_.n2o_sbl[sbl], sb_.n2o_sbl[sbl_plus], leach_fact_sbl);
78  LEACH_DOWN( sb_.urea_sbl[sbl], sb_.urea_sbl[sbl_plus], leach_fact_sbl);
79  LEACH_DOWN( sb_.no3_sbl[sbl], sb_.no3_sbl[sbl_plus], leach_fact_sbl);
80  LEACH_DOWN( sb_.don_sbl[sbl], sb_.don_sbl[sbl_plus], leach_fact_sbl);
81  LEACH_DOWN( sb_.doc_sbl[sbl], sb_.doc_sbl[sbl_plus], leach_fact_sbl);
82  LEACH_DOWN( sb_.co2_sbl[sbl], sb_.co2_sbl[sbl_plus], leach_fact_sbl);
83  LEACH_DOWN( sb_.so4_sbl[sbl], sb_.so4_sbl[sbl_plus], leach_fact_sbl);
84  LEACH_DOWN( sb_.ni_sbl[sbl], sb_.ni_sbl[sbl_plus], leach_fact_sbl);
85  }
86  }
87 
88  /************************/
89  /* Soil water transport */
90  /************************/
91 
92  if ( cbm::flt_greater_zero( waterflux_sl[0]) &&
93  cbm::flt_greater_zero( v_water_sl[0]))
94  {
95  size_t const sl( 0);
96  size_t const sl_plus( 1);
97 
98  double const leach_fact( cbm::bound_min( 0.0, waterflux_sl[sl] / v_water_sl[sl]));
99 
100  double const leach_fact_nh4( cbm::bound_max( leach_fact * sipar_.RETNH4(), 0.9999));
101  double const leach_fact_no3( cbm::bound_max( leach_fact * sipar_.RETNO3(), 0.9999));
102  double const leach_fact_doc( cbm::bound_max( leach_fact * sipar_.RETDOC(), 0.9999));
103  double const leach_fact_mic( cbm::bound_max( leach_fact * sipar_.METRX_RET_MICROBES(), 0.9999));
104  double const leach_fact_lit( cbm::bound_max( leach_fact * sipar_.METRX_RET_LITTER(), 0.9999));
105  double const leach_fact_hum( cbm::bound_max( leach_fact * sipar_.METRX_RET_HUMUS(), 0.9999));
106  double const leach_fact_dissolved_gases( cbm::bound_max( leach_fact, 0.9999));
107 
108  accumulated_n_aorg_leaching_sl[sl] += sc_.N_aorg_sl[sl] * leach_fact_mic;
109  LEACH_DOWN( sc_.C_aorg_sl[sl], sc_.C_aorg_sl[sl_plus], leach_fact_mic);
110  LEACH_DOWN( sc_.N_aorg_sl[sl], sc_.N_aorg_sl[sl_plus], leach_fact_mic);
111 
112  transport_.leach_down_epsilon( sc_.C_micro1_sl[sl], sc_.C_micro1_sl[sl_plus], leach_fact_mic, MeTrX_get_micro_c_decay_max( sc_.C_micro1_sl[sl]));
113  transport_.leach_down_epsilon( sc_.C_micro2_sl[sl], sc_.C_micro2_sl[sl_plus], leach_fact_mic, MeTrX_get_micro_c_decay_max( sc_.C_micro2_sl[sl]));
114  transport_.leach_down_epsilon( sc_.C_micro3_sl[sl], sc_.C_micro3_sl[sl_plus], leach_fact_mic, MeTrX_get_micro_c_decay_max( sc_.C_micro3_sl[sl]));
115 
116  if( n_micro_1_sl[sl] > MeTrX_get_micro_n_decay_max( n_micro_1_sl[sl]) )
117  {
118  accumulated_n_micro_leaching_sl[sl] += ( n_micro_1_sl[sl] - MeTrX_get_micro_n_decay_max( n_micro_1_sl[sl]) ) * leach_fact_mic;
119  }
120  if( n_micro_2_sl[sl] > MeTrX_get_micro_n_decay_max( n_micro_2_sl[sl]) )
121  {
122  accumulated_n_micro_leaching_sl[sl] += ( n_micro_2_sl[sl] - MeTrX_get_micro_n_decay_max( n_micro_2_sl[sl]) ) * leach_fact_mic;
123  }
124  if( n_micro_3_sl[sl] > MeTrX_get_micro_n_decay_max( n_micro_3_sl[sl]) )
125  {
126  accumulated_n_micro_leaching_sl[sl] += ( n_micro_3_sl[sl] - MeTrX_get_micro_n_decay_max( n_micro_3_sl[sl]) ) * leach_fact_mic;
127  }
128  transport_.leach_down_epsilon( n_micro_1_sl[sl], n_micro_1_sl[sl_plus], leach_fact_mic, MeTrX_get_micro_n_decay_max( n_micro_1_sl[sl]));
129  transport_.leach_down_epsilon( n_micro_2_sl[sl], n_micro_2_sl[sl_plus], leach_fact_mic, MeTrX_get_micro_n_decay_max( n_micro_2_sl[sl]));
130  transport_.leach_down_epsilon( n_micro_3_sl[sl], n_micro_3_sl[sl_plus], leach_fact_mic, MeTrX_get_micro_n_decay_max( n_micro_3_sl[sl]));
131 
132  LEACH_DOWN( sc_.C_lit1_sl[sl], sc_.C_lit1_sl[sl_plus], leach_fact_lit);
133  LEACH_DOWN( sc_.C_lit2_sl[sl], sc_.C_lit2_sl[sl_plus], leach_fact_lit);
134  LEACH_DOWN( sc_.C_lit3_sl[sl], sc_.C_lit3_sl[sl_plus], leach_fact_lit);
135 
136  accumulated_n_litter_leaching_sl[sl] += (sc_.N_lit1_sl[sl] + sc_.N_lit2_sl[sl] + sc_.N_lit3_sl[sl]) * leach_fact_lit;
137  LEACH_DOWN( sc_.N_lit1_sl[sl], sc_.N_lit1_sl[sl_plus], leach_fact_lit);
138  LEACH_DOWN( sc_.N_lit2_sl[sl], sc_.N_lit2_sl[sl_plus], leach_fact_lit);
139  LEACH_DOWN( sc_.N_lit3_sl[sl], sc_.N_lit3_sl[sl_plus], leach_fact_lit);
140 
141  LEACH_DOWN( c_humus_1_sl[sl], c_humus_1_sl[sl_plus], leach_fact_hum);
142  LEACH_DOWN( c_humus_2_sl[sl], c_humus_2_sl[sl_plus], leach_fact_hum);
143  LEACH_DOWN( c_humus_3_sl[sl], c_humus_3_sl[sl_plus], leach_fact_hum);
144 
145  accumulated_n_humus_1_leaching_sl[sl] += n_humus_1_sl[sl] * leach_fact_hum;
146  accumulated_n_humus_2_leaching_sl[sl] += n_humus_2_sl[sl] * leach_fact_hum;
147  accumulated_n_humus_3_leaching_sl[sl] += n_humus_3_sl[sl] * leach_fact_hum;
148  LEACH_DOWN( n_humus_1_sl[sl], n_humus_1_sl[sl_plus], leach_fact_hum);
149  LEACH_DOWN( n_humus_2_sl[sl], n_humus_2_sl[sl_plus], leach_fact_hum);
150  LEACH_DOWN( n_humus_3_sl[sl], n_humus_3_sl[sl_plus], leach_fact_hum);
151 
152  accumulated_n_nh4_leaching_sl[sl] += (nh4_ae_sl[sl] + nh4_an_sl[sl] + sc_.coated_nh4_sl[sl]) * leach_fact_nh4;
153  accumulated_n_nh3_leaching_sl[sl] += sc_.nh3_liq_sl[sl] * leach_fact_doc;
154  accumulated_n_urea_leaching_sl[sl] += sc_.urea_sl[sl] * leach_fact_doc;
155  LEACH_DOWN( nh4_ae_sl[sl], nh4_ae_sl[sl_plus], leach_fact_nh4);
156  LEACH_DOWN( nh4_an_sl[sl], nh4_an_sl[sl_plus], leach_fact_nh4);
157  LEACH_DOWN( sc_.coated_nh4_sl[sl], sc_.coated_nh4_sl[sl_plus], leach_fact_nh4);
158  LEACH_DOWN( sc_.nh3_liq_sl[sl], sc_.nh3_liq_sl[sl_plus], leach_fact_doc);
159  LEACH_DOWN( sc_.urea_sl[sl], sc_.urea_sl[sl_plus], leach_fact_doc);
160 
161  sc_.accumulated_n_no3_leaching_sl[sl] += (no3_ae_sl[sl] + no3_an_sl[sl]) * leach_fact_no3;
162  LEACH_DOWN( no3_ae_sl[sl], no3_ae_sl[sl_plus], leach_fact_no3);
163  LEACH_DOWN( no3_an_sl[sl], no3_an_sl[sl_plus], leach_fact_no3);
164 
165  accumulated_n_don_leaching_sl[sl] += (don_ae_sl[sl] + don_an_sl[sl]) * leach_fact_doc;
166  LEACH_DOWN( don_ae_sl[sl], don_ae_sl[sl_plus], leach_fact_doc);
167  LEACH_DOWN( don_an_sl[sl], don_an_sl[sl_plus], leach_fact_doc);
168  LEACH_DOWN( sc_.doc_sl[sl], sc_.doc_sl[sl_plus], leach_fact_doc);
169  LEACH_DOWN( sc_.an_doc_sl[sl], sc_.an_doc_sl[sl_plus], leach_fact_doc);
170  LEACH_DOWN( ae_acetate_sl[sl], ae_acetate_sl[sl_plus], leach_fact_doc);
171  LEACH_DOWN( an_acetate_sl[sl], an_acetate_sl[sl_plus], leach_fact_doc);
172 
173  accumulated_n_no_leaching_sl[sl] += (no_liq_sl[sl]+an_no_liq_sl[sl]) * leach_fact_dissolved_gases;
174  accumulated_n_n2o_leaching_sl[sl] += (n2o_liq_sl[sl]+an_n2o_liq_sl[sl]) * leach_fact_dissolved_gases;
175  LEACH_DOWN( no_liq_sl[sl], no_liq_sl[sl_plus], leach_fact_dissolved_gases);
176  LEACH_DOWN( an_no_liq_sl[sl], an_no_liq_sl[sl_plus], leach_fact_dissolved_gases);
177  LEACH_DOWN( n2o_liq_sl[sl], n2o_liq_sl[sl_plus], leach_fact_dissolved_gases);
178  LEACH_DOWN( an_n2o_liq_sl[sl], an_n2o_liq_sl[sl_plus], leach_fact_dissolved_gases);
179 
180  LEACH_DOWN( ch4_liq_sl[sl], ch4_liq_sl[sl_plus], leach_fact_dissolved_gases);
181  LEACH_DOWN( co2_liq_sl[sl], co2_liq_sl[sl_plus], leach_fact_dissolved_gases);
182  LEACH_DOWN( o2_liq_sl[sl], o2_liq_sl[sl_plus], leach_fact_dissolved_gases);
183 
184  LEACH_DOWN( sc_.so4_sl[sl], sc_.so4_sl[sl_plus], leach_fact_no3);
185  LEACH_DOWN( sc_.ni_sl[sl], sc_.ni_sl[sl_plus], leach_fact_doc);
186  LEACH_DOWN( sc_.ui_sl[sl], sc_.ui_sl[sl_plus], leach_fact_doc);
187  }
188 
189  for( size_t sl = 1; sl < sl_.soil_layer_cnt()-1; ++sl)
190  {
191  if ( !cbm::flt_equal_zero( waterflux_sl[sl]) &&
192  cbm::flt_greater_zero( v_water_sl[sl]))
193  {
194  size_t sl_minus( sl - 1);
195  size_t sl_plus( sl + 1);
196 
197  double const leach_fact( waterflux_sl[sl] / v_water_sl[sl]);
198 
199  double const leach_fact_nh4( cbm::bound(-0.9999, leach_fact * sipar_.RETNH4(), 0.9999));
200  double const leach_fact_no3( cbm::bound(-0.9999, leach_fact * sipar_.RETNO3(), 0.9999));
201  double const leach_fact_doc( cbm::bound(-0.9999, leach_fact * sipar_.RETDOC(), 0.9999));
202  double const leach_fact_mic( cbm::bound(-0.9999, leach_fact * sipar_.METRX_RET_MICROBES(), 0.9999));
203  double const leach_fact_lit( cbm::bound(-0.9999, leach_fact * sipar_.METRX_RET_LITTER(), 0.9999));
204  double const leach_fact_hum( cbm::bound(-0.9999, leach_fact * sipar_.METRX_RET_HUMUS(), 0.9999));
205  double const leach_fact_dissolved_gases( cbm::bound(-0.9999, leach_fact, 0.9999));
206 
207  accumulated_n_aorg_leaching_sl[sl] += sc_.N_aorg_sl[sl] * leach_fact_mic;
208  transport_.leach_up_and_down( sc_.C_aorg_sl[sl_minus], sc_.C_aorg_sl[sl], sc_.C_aorg_sl[sl_plus], leach_fact_mic);
209  transport_.leach_up_and_down( sc_.N_aorg_sl[sl_minus], sc_.N_aorg_sl[sl], sc_.N_aorg_sl[sl_plus], leach_fact_mic);
210 
211  transport_.leach_up_and_down_epsilon( sc_.C_micro1_sl[sl_minus], sc_.C_micro1_sl[sl], sc_.C_micro1_sl[sl_plus], leach_fact_mic, MeTrX_get_micro_c_decay_max( sc_.C_micro1_sl[sl]));
212  transport_.leach_up_and_down_epsilon( sc_.C_micro2_sl[sl_minus], sc_.C_micro2_sl[sl], sc_.C_micro2_sl[sl_plus], leach_fact_mic, MeTrX_get_micro_c_decay_max( sc_.C_micro2_sl[sl]));
213  transport_.leach_up_and_down_epsilon( sc_.C_micro3_sl[sl_minus], sc_.C_micro3_sl[sl], sc_.C_micro3_sl[sl_plus], leach_fact_mic, MeTrX_get_micro_c_decay_max( sc_.C_micro3_sl[sl]));
214 
215  if( n_micro_1_sl[sl] > MeTrX_get_micro_n_decay_max( n_micro_1_sl[sl]) )
216  {
217  accumulated_n_micro_leaching_sl[sl] += ( n_micro_1_sl[sl] - MeTrX_get_micro_n_decay_max( n_micro_1_sl[sl]) ) * leach_fact_mic;
218  }
219  if( n_micro_2_sl[sl] > MeTrX_get_micro_n_decay_max( n_micro_2_sl[sl]) )
220  {
221  accumulated_n_micro_leaching_sl[sl] += ( n_micro_2_sl[sl] - MeTrX_get_micro_n_decay_max( n_micro_2_sl[sl]) ) * leach_fact_mic;
222  }
223  if( n_micro_3_sl[sl] > MeTrX_get_micro_n_decay_max( n_micro_3_sl[sl]) )
224  {
225  accumulated_n_micro_leaching_sl[sl] += ( n_micro_3_sl[sl] - MeTrX_get_micro_n_decay_max( n_micro_3_sl[sl]) ) * leach_fact_mic;
226  }
227  transport_.leach_up_and_down_epsilon( n_micro_1_sl[sl_minus], n_micro_1_sl[sl], n_micro_1_sl[sl_plus], leach_fact_mic, MeTrX_get_micro_n_decay_max( n_micro_1_sl[sl]));
228  transport_.leach_up_and_down_epsilon( n_micro_2_sl[sl_minus], n_micro_2_sl[sl], n_micro_2_sl[sl_plus], leach_fact_mic, MeTrX_get_micro_n_decay_max( n_micro_2_sl[sl]));
229  transport_.leach_up_and_down_epsilon( n_micro_3_sl[sl_minus], n_micro_3_sl[sl], n_micro_3_sl[sl_plus], leach_fact_mic, MeTrX_get_micro_n_decay_max( n_micro_3_sl[sl]));
230 
231  transport_.leach_up_and_down( sc_.C_lit1_sl[sl_minus], sc_.C_lit1_sl[sl], sc_.C_lit1_sl[sl_plus], leach_fact_lit);
232  transport_.leach_up_and_down( sc_.C_lit2_sl[sl_minus], sc_.C_lit2_sl[sl], sc_.C_lit2_sl[sl_plus], leach_fact_lit);
233  transport_.leach_up_and_down( sc_.C_lit3_sl[sl_minus], sc_.C_lit3_sl[sl], sc_.C_lit3_sl[sl_plus], leach_fact_lit);
234 
235  accumulated_n_litter_leaching_sl[sl] += (sc_.N_lit1_sl[sl]+sc_.N_lit2_sl[sl]+sc_.N_lit3_sl[sl]) * leach_fact_lit;
236  transport_.leach_up_and_down( sc_.N_lit1_sl[sl_minus], sc_.N_lit1_sl[sl], sc_.N_lit1_sl[sl_plus], leach_fact_lit);
237  transport_.leach_up_and_down( sc_.N_lit2_sl[sl_minus], sc_.N_lit2_sl[sl], sc_.N_lit2_sl[sl_plus], leach_fact_lit);
238  transport_.leach_up_and_down( sc_.N_lit3_sl[sl_minus], sc_.N_lit3_sl[sl], sc_.N_lit3_sl[sl_plus], leach_fact_lit);
239 
240  transport_.leach_up_and_down( c_humus_1_sl[sl_minus], c_humus_1_sl[sl], c_humus_1_sl[sl_plus], leach_fact_hum);
241  transport_.leach_up_and_down( c_humus_2_sl[sl_minus], c_humus_2_sl[sl], c_humus_2_sl[sl_plus], leach_fact_hum);
242  transport_.leach_up_and_down( c_humus_3_sl[sl_minus], c_humus_3_sl[sl], c_humus_3_sl[sl_plus], leach_fact_hum);
243 
244  accumulated_n_humus_1_leaching_sl[sl] += n_humus_1_sl[sl] * leach_fact_hum;
245  accumulated_n_humus_2_leaching_sl[sl] += n_humus_2_sl[sl] * leach_fact_hum;
246  accumulated_n_humus_3_leaching_sl[sl] += n_humus_3_sl[sl] * leach_fact_hum;
247  transport_.leach_up_and_down( n_humus_1_sl[sl_minus], n_humus_1_sl[sl], n_humus_1_sl[sl_plus], leach_fact_hum);
248  transport_.leach_up_and_down( n_humus_2_sl[sl_minus], n_humus_2_sl[sl], n_humus_2_sl[sl_plus], leach_fact_hum);
249  transport_.leach_up_and_down( n_humus_3_sl[sl_minus], n_humus_3_sl[sl], n_humus_3_sl[sl_plus], leach_fact_hum);
250 
251  accumulated_n_nh4_leaching_sl[sl] += (nh4_ae_sl[sl] + nh4_an_sl[sl] + sc_.coated_nh4_sl[sl]) * leach_fact_nh4;
252  accumulated_n_nh3_leaching_sl[sl] += sc_.nh3_liq_sl[sl] * leach_fact_doc;
253  accumulated_n_urea_leaching_sl[sl] += sc_.urea_sl[sl] * leach_fact_doc;
254  transport_.leach_up_and_down( nh4_ae_sl[sl_minus], nh4_ae_sl[sl], nh4_ae_sl[sl_plus], leach_fact_nh4);
255  transport_.leach_up_and_down( nh4_an_sl[sl_minus], nh4_an_sl[sl], nh4_an_sl[sl_plus], leach_fact_nh4);
256  transport_.leach_up_and_down( sc_.coated_nh4_sl[sl_minus], sc_.coated_nh4_sl[sl], sc_.coated_nh4_sl[sl_plus], leach_fact_nh4);
257  transport_.leach_up_and_down( sc_.nh3_liq_sl[sl_minus], sc_.nh3_liq_sl[sl], sc_.nh3_liq_sl[sl_plus], leach_fact_doc);
258  transport_.leach_up_and_down( sc_.urea_sl[sl_minus], sc_.urea_sl[sl], sc_.urea_sl[sl_plus], leach_fact_doc);
259 
260  sc_.accumulated_n_no3_leaching_sl[sl] += (no3_ae_sl[sl]+no3_an_sl[sl]) * leach_fact_no3;
261  transport_.leach_up_and_down( no3_ae_sl[sl_minus], no3_ae_sl[sl], no3_ae_sl[sl_plus], leach_fact_no3);
262  transport_.leach_up_and_down( no3_an_sl[sl_minus], no3_an_sl[sl], no3_an_sl[sl_plus], leach_fact_no3);
263 
264  accumulated_n_don_leaching_sl[sl] += (don_ae_sl[sl] + don_an_sl[sl]) * leach_fact_doc;
265  transport_.leach_up_and_down( don_ae_sl[sl_minus], don_ae_sl[sl], don_ae_sl[sl_plus], leach_fact_doc);
266  transport_.leach_up_and_down( don_an_sl[sl_minus], don_an_sl[sl], don_an_sl[sl_plus], leach_fact_doc);
267  transport_.leach_up_and_down( sc_.doc_sl[sl_minus], sc_.doc_sl[sl], sc_.doc_sl[sl_plus], leach_fact_doc);
268  transport_.leach_up_and_down( sc_.an_doc_sl[sl_minus], sc_.an_doc_sl[sl], sc_.an_doc_sl[sl_plus], leach_fact_doc);
269  transport_.leach_up_and_down( ae_acetate_sl[sl_minus], ae_acetate_sl[sl], ae_acetate_sl[sl_plus], leach_fact_doc);
270  transport_.leach_up_and_down( an_acetate_sl[sl_minus], an_acetate_sl[sl], an_acetate_sl[sl_plus], leach_fact_doc);
271 
272  accumulated_n_no_leaching_sl[sl] += (no_liq_sl[sl]+an_no_liq_sl[sl]) * leach_fact_dissolved_gases;
273  accumulated_n_n2o_leaching_sl[sl] += (n2o_liq_sl[sl]+an_n2o_liq_sl[sl]) * leach_fact_dissolved_gases;
274  transport_.leach_up_and_down( no_liq_sl[sl_minus], no_liq_sl[sl], no_liq_sl[sl_plus], leach_fact_dissolved_gases);
275  transport_.leach_up_and_down( an_no_liq_sl[sl_minus], an_no_liq_sl[sl], an_no_liq_sl[sl_plus], leach_fact_dissolved_gases);
276  transport_.leach_up_and_down( n2o_liq_sl[sl_minus], n2o_liq_sl[sl], n2o_liq_sl[sl_plus], leach_fact_dissolved_gases);
277  transport_.leach_up_and_down( an_n2o_liq_sl[sl_minus], an_n2o_liq_sl[sl], an_n2o_liq_sl[sl_plus], leach_fact_dissolved_gases);
278 
279  transport_.leach_up_and_down( ch4_liq_sl[sl_minus], ch4_liq_sl[sl], ch4_liq_sl[sl_plus], leach_fact_dissolved_gases);
280  transport_.leach_up_and_down( co2_liq_sl[sl_minus], co2_liq_sl[sl], co2_liq_sl[sl_plus], leach_fact_dissolved_gases);
281  transport_.leach_up_and_down( o2_liq_sl[sl_minus], o2_liq_sl[sl], o2_liq_sl[sl_plus], leach_fact_dissolved_gases);
282 
283  transport_.leach_up_and_down( sc_.so4_sl[sl_minus], sc_.so4_sl[sl], sc_.so4_sl[sl_plus], leach_fact_no3);
284  transport_.leach_up_and_down( sc_.ni_sl[sl_minus], sc_.ni_sl[sl], sc_.ni_sl[sl_plus], leach_fact_doc);
285  transport_.leach_up_and_down( sc_.ui_sl[sl_minus], sc_.ui_sl[sl], sc_.ui_sl[sl_plus], leach_fact_doc);
286  }
287  }
288 
289  size_t sl( sl_.soil_layer_cnt()-1);
290 
291  if ( !cbm::flt_equal_zero( waterflux_sl[sl]) &&
292  cbm::flt_greater_zero( v_water_sl[sl]))
293  {
294  double dummy_out( 0.0); //dummy for substances that are not balanced (no accumulated leaching variable exists)
295  size_t sl_minus( sl_.soil_layer_cnt()-2);
296 
297  double const leach_fact( waterflux_sl[sl] / v_water_sl[sl]);
298 
299  double const leach_fact_nh4( cbm::bound(-0.9999, leach_fact * sipar_.RETNH4(), 0.9999));
300  double const leach_fact_no3( cbm::bound(-0.9999, leach_fact * sipar_.RETNO3(), 0.9999));
301  double const leach_fact_doc( cbm::bound(-0.9999, leach_fact * sipar_.RETDOC(), 0.9999));
302  double const leach_fact_mic( cbm::bound(-0.9999, leach_fact * sipar_.METRX_RET_MICROBES(), 0.9999));
303  double const leach_fact_lit( cbm::bound(-0.9999, leach_fact * sipar_.METRX_RET_LITTER(), 0.9999));
304  double const leach_fact_hum( cbm::bound(-0.9999, leach_fact * sipar_.METRX_RET_HUMUS(), 0.9999));
305  double const leach_fact_dissolved_gases( cbm::bound(-0.9999, leach_fact, 0.9999));
306 
307  accumulated_n_aorg_leaching_sl[sl] += sc_.N_aorg_sl[sl] * leach_fact_mic;
308  transport_.leach_up_and_down( sc_.C_aorg_sl[sl_minus], sc_.C_aorg_sl[sl], sc_.accumulated_doc_leach, leach_fact_mic);
309  transport_.leach_up_and_down( sc_.N_aorg_sl[sl_minus], sc_.N_aorg_sl[sl], sc_.accumulated_don_leach, leach_fact_mic);
310 
311  transport_.leach_up_and_down_epsilon( sc_.C_micro1_sl[sl_minus], sc_.C_micro1_sl[sl], sc_.accumulated_doc_leach, leach_fact_mic, MeTrX_get_micro_c_decay_max( sc_.C_micro1_sl[sl]));
312  transport_.leach_up_and_down_epsilon( sc_.C_micro2_sl[sl_minus], sc_.C_micro2_sl[sl], sc_.accumulated_doc_leach, leach_fact_mic, MeTrX_get_micro_c_decay_max( sc_.C_micro2_sl[sl]));
313  transport_.leach_up_and_down_epsilon( sc_.C_micro3_sl[sl_minus], sc_.C_micro3_sl[sl], sc_.accumulated_doc_leach, leach_fact_mic, MeTrX_get_micro_c_decay_max( sc_.C_micro3_sl[sl]));
314 
315  if( n_micro_1_sl[sl] > MeTrX_get_micro_n_decay_max( n_micro_1_sl[sl]) )
316  {
317  accumulated_n_micro_leaching_sl[sl] += ( n_micro_1_sl[sl] - MeTrX_get_micro_n_decay_max( n_micro_1_sl[sl]) ) * leach_fact_mic;
318  }
319  if( n_micro_2_sl[sl] > MeTrX_get_micro_n_decay_max( n_micro_2_sl[sl]) )
320  {
321  accumulated_n_micro_leaching_sl[sl] += ( n_micro_2_sl[sl] - MeTrX_get_micro_n_decay_max( n_micro_2_sl[sl]) ) * leach_fact_mic;
322  }
323  if( n_micro_3_sl[sl] > MeTrX_get_micro_n_decay_max( n_micro_3_sl[sl]) )
324  {
325  accumulated_n_micro_leaching_sl[sl] += ( n_micro_3_sl[sl] - MeTrX_get_micro_n_decay_max( n_micro_3_sl[sl]) ) * leach_fact_mic;
326  }
327  transport_.leach_up_and_down_epsilon( n_micro_1_sl[sl_minus], n_micro_1_sl[sl], sc_.accumulated_don_leach, leach_fact_mic, MeTrX_get_micro_n_decay_max( n_micro_1_sl[sl]));
328  transport_.leach_up_and_down_epsilon( n_micro_2_sl[sl_minus], n_micro_2_sl[sl], sc_.accumulated_don_leach, leach_fact_mic, MeTrX_get_micro_n_decay_max( n_micro_2_sl[sl]));
329  transport_.leach_up_and_down_epsilon( n_micro_3_sl[sl_minus], n_micro_3_sl[sl], sc_.accumulated_don_leach, leach_fact_mic, MeTrX_get_micro_n_decay_max( n_micro_3_sl[sl]));
330 
331  transport_.leach_up_and_down( sc_.C_lit1_sl[sl_minus], sc_.C_lit1_sl[sl], sc_.accumulated_doc_leach, leach_fact_lit);
332  transport_.leach_up_and_down( sc_.C_lit2_sl[sl_minus], sc_.C_lit2_sl[sl], sc_.accumulated_doc_leach, leach_fact_lit);
333  transport_.leach_up_and_down( sc_.C_lit3_sl[sl_minus], sc_.C_lit3_sl[sl], sc_.accumulated_doc_leach, leach_fact_lit);
334 
335  accumulated_n_litter_leaching_sl[sl] += (sc_.N_lit1_sl[sl]+sc_.N_lit2_sl[sl]+sc_.N_lit3_sl[sl]) * leach_fact_lit;
336  transport_.leach_up_and_down( sc_.N_lit1_sl[sl_minus], sc_.N_lit1_sl[sl], sc_.accumulated_don_leach, leach_fact_lit);
337  transport_.leach_up_and_down( sc_.N_lit2_sl[sl_minus], sc_.N_lit2_sl[sl], sc_.accumulated_don_leach, leach_fact_lit);
338  transport_.leach_up_and_down( sc_.N_lit3_sl[sl_minus], sc_.N_lit3_sl[sl], sc_.accumulated_don_leach, leach_fact_lit);
339 
340  transport_.leach_up_and_down( c_humus_1_sl[sl_minus], c_humus_1_sl[sl], sc_.accumulated_doc_leach, leach_fact_hum);
341  transport_.leach_up_and_down( c_humus_2_sl[sl_minus], c_humus_2_sl[sl], sc_.accumulated_doc_leach, leach_fact_hum);
342  transport_.leach_up_and_down( c_humus_3_sl[sl_minus], c_humus_3_sl[sl], sc_.accumulated_doc_leach, leach_fact_hum);
343 
344  accumulated_n_humus_1_leaching_sl[sl] += n_humus_1_sl[sl] * leach_fact_hum;
345  accumulated_n_humus_2_leaching_sl[sl] += n_humus_2_sl[sl] * leach_fact_hum;
346  accumulated_n_humus_3_leaching_sl[sl] += n_humus_3_sl[sl] * leach_fact_hum;
347  transport_.leach_up_and_down( n_humus_1_sl[sl_minus], n_humus_1_sl[sl], sc_.accumulated_don_leach, leach_fact_hum);
348  transport_.leach_up_and_down( n_humus_2_sl[sl_minus], n_humus_2_sl[sl], sc_.accumulated_don_leach, leach_fact_hum);
349  transport_.leach_up_and_down( n_humus_2_sl[sl_minus], n_humus_2_sl[sl], sc_.accumulated_don_leach, leach_fact_hum);
350 
351  accumulated_n_nh4_leaching_sl[sl] += (nh4_ae_sl[sl] + nh4_an_sl[sl] + sc_.coated_nh4_sl[sl]) * leach_fact_nh4;
352  accumulated_n_nh3_leaching_sl[sl] += sc_.nh3_liq_sl[sl] * leach_fact_doc;
353  accumulated_n_urea_leaching_sl[sl] += sc_.urea_sl[sl] * leach_fact_doc;
354  transport_.leach_up_and_down( nh4_ae_sl[sl_minus], nh4_ae_sl[sl], sc_.accumulated_nh4_leach, leach_fact_nh4);
355  transport_.leach_up_and_down( nh4_an_sl[sl_minus], nh4_an_sl[sl], sc_.accumulated_nh4_leach, leach_fact_nh4);
356  transport_.leach_up_and_down( sc_.coated_nh4_sl[sl_minus], sc_.coated_nh4_sl[sl], sc_.accumulated_nh4_leach, leach_fact_nh4);
357  transport_.leach_up_and_down( sc_.nh3_liq_sl[sl_minus], sc_.nh3_liq_sl[sl], day_leach_nh3, leach_fact_doc);
358  transport_.leach_up_and_down( sc_.urea_sl[sl_minus], sc_.urea_sl[sl], day_leach_urea, leach_fact_doc);
359 
360  sc_.accumulated_n_no3_leaching_sl[sl] += (no3_ae_sl[sl]+no3_an_sl[sl]) * leach_fact_no3;
361  transport_.leach_up_and_down( no3_ae_sl[sl_minus], no3_ae_sl[sl], sc_.accumulated_no3_leach, leach_fact_no3);
362  transport_.leach_up_and_down( no3_an_sl[sl_minus], no3_an_sl[sl], sc_.accumulated_no3_leach, leach_fact_no3);
363 
364  accumulated_n_don_leaching_sl[sl] += (don_ae_sl[sl] + don_an_sl[sl]) * leach_fact_doc;
365  transport_.leach_up_and_down( don_ae_sl[sl_minus], don_ae_sl[sl], sc_.accumulated_don_leach, leach_fact_doc);
366  transport_.leach_up_and_down( don_an_sl[sl_minus], don_an_sl[sl], sc_.accumulated_don_leach, leach_fact_doc);
367  transport_.leach_up_and_down( sc_.doc_sl[sl_minus], sc_.doc_sl[sl], sc_.accumulated_doc_leach, leach_fact_doc);
368  transport_.leach_up_and_down( sc_.an_doc_sl[sl_minus], sc_.an_doc_sl[sl], sc_.accumulated_doc_leach, leach_fact_doc);
369  transport_.leach_up_and_down( ae_acetate_sl[sl_minus], ae_acetate_sl[sl], sc_.accumulated_doc_leach, leach_fact_doc);
370  transport_.leach_up_and_down( an_acetate_sl[sl_minus], an_acetate_sl[sl], sc_.accumulated_doc_leach, leach_fact_doc);
371 
372  accumulated_n_no_leaching_sl[sl] += (no_liq_sl[sl]+an_no_liq_sl[sl]) * leach_fact_dissolved_gases;
373  accumulated_n_n2o_leaching_sl[sl] += (n2o_liq_sl[sl]+an_n2o_liq_sl[sl]) * leach_fact_dissolved_gases;
374  transport_.leach_up_and_down( no_liq_sl[sl_minus], no_liq_sl[sl], day_leach_no, leach_fact_dissolved_gases);
375  transport_.leach_up_and_down( an_no_liq_sl[sl_minus], an_no_liq_sl[sl], day_leach_no, leach_fact_dissolved_gases);
376  transport_.leach_up_and_down( n2o_liq_sl[sl_minus], n2o_liq_sl[sl], day_leach_n2o, leach_fact_dissolved_gases);
377  transport_.leach_up_and_down( an_n2o_liq_sl[sl_minus], an_n2o_liq_sl[sl], day_leach_n2o, leach_fact_dissolved_gases);
378  transport_.leach_up_and_down( o2_liq_sl[sl_minus], o2_liq_sl[sl], day_leach_o2, leach_fact_dissolved_gases);
379 
380  transport_.leach_up_and_down( ch4_liq_sl[sl_minus], ch4_liq_sl[sl], subdaily_ch4_leach[subdaily_time_step_], leach_fact_dissolved_gases);
381  transport_.leach_up_and_down( co2_liq_sl[sl_minus], co2_liq_sl[sl], subdaily_co2_leach[subdaily_time_step_], leach_fact_dissolved_gases);
382 
383  transport_.leach_up_and_down( sc_.so4_sl[sl_minus], sc_.so4_sl[sl], sc_.accumulated_so4_leach, leach_fact_no3);
384  transport_.leach_up_and_down( sc_.ni_sl[sl_minus], sc_.ni_sl[sl], dummy_out, leach_fact_doc);
385  transport_.leach_up_and_down( sc_.ui_sl[sl_minus], sc_.ui_sl[sl], dummy_out, leach_fact_doc);
386  }
387 }
Here is the caller graph for this function:

◆ MeTrX_liq_diffusion()

void ldndc::SoilChemistryMeTrX::MeTrX_liq_diffusion ( )
private
Parameters
[in]None
[out]None
Returns
void

Referenced by MeTrX_groundwater_access(), and solve().

Here is the caller graph for this function:

◆ MeTrX_manure()

lerr_t ldndc::SoilChemistryMeTrX::MeTrX_manure ( )
private
Parameters
[in]None
[out]None
Returns
error code

Referenced by solve().

265 {
266  EventAttributes const * ev_manure = NULL;
267  while (( ev_manure = this->m_ManureEvents.pop()) != NULL)
268  {
269  double new_manure_n( -sc_.accumulated_n_fertilizer);
270  double new_manure_c( -sc_.accumulated_c_fertilizer);
271 
272  double me_c = ev_manure->get( "/carbon", -1.0);
273  if ( cbm::flt_less( me_c, 0.0))
274  {
275  KLOGERROR( "manure event: carbon and nitrogen amount must be greater 0",
276  " [carbon=",me_c,"]");
277  return LDNDC_ERR_FAIL;
278  }
279  double me_cn = ev_manure->get( "/carbon-nitrogen-ratio", -1.0);
280  if ( cbm::flt_less( me_cn, 0.0))
281  {
282  KLOGERROR( "manure event: carbon/nitrogen ratio must be greater 0",
283  " [carbon/nitrogen ratio=",me_cn,"]");
284  return LDNDC_ERR_FAIL;
285  }
286 
287  double add_c( me_c * cbm::HA_IN_M2);
288  double add_n( add_c / me_cn);
289 
290  sc_.accumulated_c_fertilizer += add_c;
291  sc_.accumulated_n_fertilizer += add_n;
292 
293  double add_n_nh4( 0.0);
294  double add_n_no3( 0.0);
295  double add_n_don( 0.0);
296  double add_n_urea( 0.0);
297 
298  double add_c_doc( 0.0);
299 
300  double add_c_aorg( 0.0);
301  double add_n_aorg( 0.0);
302 
303  double add_c_lit_1( 0.0);
304  double add_c_lit_2( 0.0);
305  double add_c_lit_3( 0.0);
306 
307  double add_n_lit_1( 0.0);
308  double add_n_lit_2( 0.0);
309  double add_n_lit_3( 0.0);
310 
311  double ph_manure = ev_manure->get( "/ph", -1.0);
312 
313  cbm::string_t const & manure = ev_manure->get( "/type", "-");
314  if ( manure == "slurry" )
315  {
316  double const avail_n = ev_manure->get( "/nitrogen-available", sipar_.FRAC_LABILE_N_SLURRY());
317  if ( !cbm::flt_greater_zero( avail_n))
318  {
319  KLOGERROR( "manure event (",manure,"): fraction of available nitrogen must be at least 0",
320  " [available nitrogen=",avail_n,"]");
321  return LDNDC_ERR_FAIL;
322  }
323  double const avail_c = ev_manure->get( "/carbon-available", sipar_.FRAC_LABILE_C_SLURRY());
324  if ( !cbm::flt_greater_zero( avail_c))
325  {
326  KLOGERROR( "manure event (",manure,"): fraction of available carbon must be at least 0",
327  " [available carbon=",avail_c,"]");
328  return LDNDC_ERR_FAIL;
329  }
330 
331  double const liq_n = avail_n * add_n;
332  double const f_urea = ev_manure->get( "/urea-fraction", sipar_.LIQUREA_SLURRY());
333  add_n_urea = f_urea * liq_n;
334  double const f_nh4 = ev_manure->get( "/nh4-fraction", sipar_.LIQNH4_SLURRY());
335  add_n_nh4 = f_nh4 * liq_n;
336  double const f_don = ev_manure->get( "/don-fraction", sipar_.LIQDON_SLURRY());
337  add_n_don = f_don * liq_n;
338  double const f_no3 = ev_manure->get( "/no3-fraction", sipar_.LIQNO3_SLURRY());
339  add_n_no3 = f_no3 * liq_n;
340 
341  if (cbm::flt_not_equal_zero( add_n_urea + add_n_nh4 + add_n_don + add_n_no3 - liq_n))
342  {
343  KLOGERROR( "manure event (",manure,"): fractions of liquid nitrogen do not add up to 1.0!",
344  " check UREA fraction, NH4 fraction, DON fraction and NO3 fraction");
345  return LDNDC_ERR_FAIL;
346  }
347 
348  add_c_doc = avail_c * add_c;
349 
350  double const add_c_res( add_c - add_c_doc);
351  double const add_n_res( add_n - add_n_don - add_n_nh4 - add_n_no3 - add_n_urea);
352 
353  double const f_lignin = ev_manure->get( "/lignin-fraction", 0.2); // Bhogal et al. (2011), Levi-Minzi et al. (1986), Probert et al. (2005)
354  double const frac_c_lit_3( f_lignin);
355  double const f_cellulose = ev_manure->get( "/cellulose-fraction", 0.6); // Bhogal et al. (2011), Levi-Minzi et al. (1986)
356  double const frac_c_lit_2( f_cellulose);
357  double const frac_c_lit_1( 1.0 - frac_c_lit_2 - frac_c_lit_3);
358 
359  if (( f_lignin + f_cellulose) > 1.0)
360  {
361  KLOGERROR( "manure event (",manure,"): fractions of litter do not add up to 1.0!",
362  " check lignin fraction and cellulose fraction");
363  return LDNDC_ERR_FAIL;
364  }
365 
366  add_c_lit_1 += ( frac_c_lit_1 * add_c_res);
367  add_c_lit_2 += ( frac_c_lit_2 * add_c_res);
368  add_c_lit_3 += ( frac_c_lit_3 * add_c_res);
369 
370  add_n_lit_1 += ( frac_c_lit_1 * add_n_res);
371  add_n_lit_2 += ( frac_c_lit_2 * add_n_res);
372  add_n_lit_3 += ( frac_c_lit_3 * add_n_res);
373  }
374  else if ( manure == "green" )
375  {
376  add_c_lit_1 = 0.2 * add_c;
377  add_c_lit_2 = 0.7 * add_c;
378  add_c_lit_3 = 0.1 * add_c;
379 
380  add_n_lit_1 = 0.2 * add_n;
381  add_n_lit_2 = 0.7 * add_n;
382  add_n_lit_3 = 0.1 * add_n;
383  }
384  else if ( manure == "straw" )
385  {
386  add_c_lit_1 = 0.2 * add_c;
387  add_c_lit_2 = 0.7 * add_c;
388  add_c_lit_3 = 0.1 * add_c;
389 
390  add_n_lit_1 = 0.2 * add_n;
391  add_n_lit_2 = 0.7 * add_n;
392  add_n_lit_3 = 0.1 * add_n;
393  }
394  else if ( manure == "farmyard" )
395  {
396  double const avail_n = ev_manure->get( "/nitrogen-available", sipar_.FRAC_LABILE_N_FARMYARD());
397  if ( !cbm::flt_greater_zero( avail_n))
398  {
399  KLOGERROR( "manure event (",manure,"): fraction of available nitrogen must be at least 0",
400  " [available nitrogen=",avail_n,"]");
401  return LDNDC_ERR_FAIL;
402  }
403  double const avail_c = ev_manure->get( "/carbon-available", sipar_.FRAC_LABILE_C_FARMYARD());
404  if ( !cbm::flt_greater_zero( avail_c))
405  {
406  KLOGERROR( "manure event (",manure,"): fraction of available carbon must be at least 0",
407  " [available carbon=",avail_c,"]");
408  return LDNDC_ERR_FAIL;
409  }
410 
411  double const liq_n = avail_n * add_n;
412  double const f_urea = ev_manure->get( "/urea-fraction", sipar_.LIQUREA_FARMYARD());
413  add_n_urea = f_urea * liq_n;
414  double const f_nh4 = ev_manure->get( "/nh4-fraction", sipar_.LIQNH4_FARMYARD());
415  add_n_nh4 = f_nh4 * liq_n;
416  double const f_don = ev_manure->get( "/don-fraction", sipar_.LIQDON_FARMYARD());
417  add_n_don = f_don * liq_n;
418  double const f_no3 = ev_manure->get( "/no3-fraction", sipar_.LIQNO3_FARMYARD());
419  add_n_no3 = f_no3 * liq_n;
420 
421  if (cbm::flt_not_equal_zero( add_n_urea + add_n_nh4 + add_n_don + add_n_no3 - liq_n))
422  {
423  KLOGERROR( "manure event (",manure,"): fractions of liquid nitrogen do not add up to 1.0!",
424  " check UREA fraction, NH4 fraction, DON fraction and NO3 fraction");
425  return LDNDC_ERR_FAIL;
426  }
427 
428  add_c_doc = avail_c * add_c;
429 
430  double const add_c_res( add_c - add_c_doc);
431  double const add_n_res( add_n - add_n_don - add_n_nh4 - add_n_no3 - add_n_urea);
432 
433  double const f_lignin = ev_manure->get( "/lignin-fraction", 0.2); // Bhogal et al. (2011), Levi-Minzi et al. (1986), Probert et al. (2005)
434  double const frac_c_lit_3( f_lignin);
435  double const f_cellulose = ev_manure->get( "/cellulose-fraction", 0.6); // Bhogal et al. (2011), Levi-Minzi et al. (1986)
436  double const frac_c_lit_2( f_cellulose);
437  double const frac_c_lit_1( 1.0 - frac_c_lit_2 - frac_c_lit_3);
438 
439  if (( f_lignin + f_cellulose) > 1.0)
440  {
441  KLOGERROR( "manure event (",manure,"): fractions of litter do not add up to 1.0!",
442  " check lignin fraction and cellulose fraction");
443  return LDNDC_ERR_FAIL;
444  }
445 
446  add_c_lit_1 += ( frac_c_lit_1 * add_c_res);
447  add_c_lit_2 += ( frac_c_lit_2 * add_c_res);
448  add_c_lit_3 += ( frac_c_lit_3 * add_c_res);
449 
450  add_n_lit_1 += ( frac_c_lit_1 * add_n_res);
451  add_n_lit_2 += ( frac_c_lit_2 * add_n_res);
452  add_n_lit_3 += ( frac_c_lit_3 * add_n_res);
453  }
454  else if ( manure == "compost" )
455  {
456  double const avail_n = ev_manure->get( "/nitrogen-available", sipar_.FRAC_LABILE_N_COMPOST());
457  if ( avail_n < 0.0)
458  {
459  KLOGERROR( "manure event (",manure,"): fraction of available nitrogen must be at least 0",
460  " [available nitrogen=",avail_n,"]");
461  return LDNDC_ERR_FAIL;
462  }
463  double const avail_c = ev_manure->get( "/carbon-available", sipar_.FRAC_LABILE_C_COMPOST());
464  if ( avail_c < 0.0)
465  {
466  KLOGERROR( "manure event (",manure,"): fraction of available carbon must be at least 0",
467  " [available carbon=",avail_c,"]");
468  return LDNDC_ERR_FAIL;
469  }
470 
471  double const liq_n = avail_n * add_n;
472  double const f_urea = ev_manure->get( "/urea-fraction", sipar_.LIQUREA_COMPOST());
473  add_n_urea = f_urea * liq_n;
474  double const f_nh4 = ev_manure->get( "/nh4-fraction", sipar_.LIQNH4_COMPOST());
475  add_n_nh4 = f_nh4 * liq_n;
476  double const f_don = ev_manure->get( "/don-fraction", sipar_.LIQDON_COMPOST());
477  add_n_don = f_don * liq_n;
478  double const f_no3 = ev_manure->get( "/no3-fraction", sipar_.LIQNO3_COMPOST());
479  add_n_no3 = f_no3 * liq_n;
480 
481  if (cbm::flt_not_equal_zero( add_n_urea+add_n_nh4+add_n_don+add_n_no3-liq_n))
482  {
483  KLOGERROR( "manure event (",manure,"): fractions of liquid nitrogen do not add up to 1.0!",
484  " check UREA fraction, NH4 fraction, DON fraction and NO3 fraction");
485  return LDNDC_ERR_FAIL;
486  }
487 
488  add_c_doc = ( avail_c * add_c);
489 
490  double const add_c_res( add_c - add_c_doc);
491  double const add_n_res( add_n - add_n_don - add_n_nh4 - add_n_no3 - add_n_urea);
492 
493  double const f_lignin = ev_manure->get( "/lignin-fraction", 0.8);
494  double const frac_c_lit_3( f_lignin);
495  double const f_cellulose = ev_manure->get( "/cellulose-fraction", 0.1);
496  double const frac_c_lit_2( f_cellulose);
497  double const frac_c_lit_1( 1.0 - frac_c_lit_2 - frac_c_lit_3);
498 
499  if (( f_lignin + f_cellulose) > 1.0)
500  {
501  KLOGERROR( "manure event (",manure,"): fractions of litter do not add up to 1.0!",
502  " check lignin fraction and cellulose fraction");
503  return LDNDC_ERR_FAIL;
504  }
505 
506  add_c_lit_1 += ( frac_c_lit_1 * add_c_res);
507  add_c_lit_2 += ( frac_c_lit_2 * add_c_res);
508  add_c_lit_3 += ( frac_c_lit_3 * add_c_res);
509 
510  add_n_lit_1 += ( frac_c_lit_1 * add_n_res);
511  add_n_lit_2 += ( frac_c_lit_2 * add_n_res);
512  add_n_lit_3 += ( frac_c_lit_3 * add_n_res);
513  }
514  else if ( manure == "generic" )
515  {
516  double const avail_n_default( (sipar_.FRAC_LABILE_N_SLURRY() + sipar_.FRAC_LABILE_N_FARMYARD()) / 2.0);
517  double const avail_n = ev_manure->get( "/nitrogen-available", avail_n_default);
518  if ( !cbm::flt_greater_zero( avail_n))
519  {
520  KLOGERROR( "manure event (",manure,"): fraction of available nitrogen must be at least 0",
521  " [available nitrogen=",avail_n,"]");
522  return LDNDC_ERR_FAIL;
523  }
524  double const avail_c_default( (sipar_.FRAC_LABILE_C_SLURRY() + sipar_.FRAC_LABILE_C_FARMYARD()) / 2.0);
525  double const avail_c = ev_manure->get( "/carbon-available", avail_c_default);
526  if ( !cbm::flt_greater_zero( avail_c))
527  {
528  KLOGERROR( "manure event (",manure,"): fraction of available carbon must be at least 0",
529  " [available carbon=",avail_c,"]");
530  return LDNDC_ERR_FAIL;
531  }
532 
533  double const liq_n = avail_n * add_n;
534 
535  double const f_urea_default( (sipar_.LIQUREA_SLURRY() + sipar_.LIQUREA_FARMYARD()) / 2.0);
536  double const f_urea = ev_manure->get( "/urea-fraction", f_urea_default);
537  add_n_urea = f_urea * liq_n;
538 
539  double const f_nh4_default( (sipar_.LIQNH4_SLURRY() + sipar_.LIQNH4_FARMYARD()) / 2.0);
540  double const f_nh4 = ev_manure->get( "/nh4-fraction", f_nh4_default);
541  add_n_nh4 = f_nh4 * liq_n;
542 
543  double const f_don_default( (sipar_.LIQDON_SLURRY() + sipar_.LIQDON_FARMYARD()) / 2.0);
544  double const f_don = ev_manure->get( "/don-fraction", f_don_default);
545  add_n_don = f_don * liq_n;
546 
547  double const f_no3_default( (sipar_.LIQNO3_SLURRY() + sipar_.LIQNO3_FARMYARD()) / 2.0);
548  double const f_no3 = ev_manure->get( "/no3-fraction", f_no3_default);
549  add_n_no3 = f_no3 * liq_n;
550 
551  if (cbm::flt_not_equal_zero( add_n_urea + add_n_nh4 + add_n_don + add_n_no3 - liq_n))
552  {
553  KLOGERROR( "manure event (",manure,"): fractions of liquid nitrogen do not add up to 1.0!",
554  " check UREA fraction, NH4 fraction, DON fraction and NO3 fraction");
555  return LDNDC_ERR_FAIL;
556  }
557 
558  add_c_doc = avail_c * add_c;
559 
560  double const add_c_res( add_c - add_c_doc);
561  double const add_n_res( add_n - add_n_don - add_n_nh4 - add_n_no3 - add_n_urea);
562 
563  double const f_lignin = ev_manure->get( "/lignin-fraction", 0.2);
564  double const frac_c_lit_3( f_lignin);
565  double const f_cellulose = ev_manure->get( "/cellulose-fraction", 0.6);
566  double const frac_c_lit_2( f_cellulose);
567  double const frac_c_lit_1( 1.0 - frac_c_lit_2 - frac_c_lit_3);
568 
569  if (( f_lignin + f_cellulose) > 1.0)
570  {
571  KLOGERROR( "manure event (",manure,"): fractions of litter do not add up to 1.0!",
572  " check lignin fraction and cellulose fraction");
573  return LDNDC_ERR_FAIL;
574  }
575 
576  add_c_lit_1 += ( frac_c_lit_1 * add_c_res);
577  add_c_lit_2 += ( frac_c_lit_2 * add_c_res);
578  add_c_lit_3 += ( frac_c_lit_3 * add_c_res);
579 
580  add_n_lit_1 += ( frac_c_lit_1 * add_n_res);
581  add_n_lit_2 += ( frac_c_lit_2 * add_n_res);
582  add_n_lit_3 += ( frac_c_lit_3 * add_n_res);
583  }
584  else
585  {
586  KLOGWARN( "Unknown manure type \"",manure,"\". Skipping event!");
587  break;
588  }
589 
590  double const depth( ev_manure->get( "/depth", 0.0));
591 
592  size_t l_0 = 0;
593  size_t l_1 = 1;
594  if ( cbm::flt_equal_zero( depth))
595  {
596  l_0 = 0;
597  l_1 = 1;
598  for( size_t sl = 1; sl < sl_.soil_layer_cnt(); ++sl)
599  {
600  if ( sc_.depth_sl[sl] <= 0.01)
601  {
602  l_1 = sl;
603  }
604  else
605  {
606  break;
607  }
608  }
609  }
610  else
611  {
612  //l_0 not allowed to be deeper than last but one soil layer
613  l_0 = sl_.soil_layer_cnt()-2;
614  //find first layer (from top) having at least depth <depth(fert)>
615  for ( size_t l = 0; l < sl_.soil_layer_cnt()-1; ++l)
616  {
617  if ( cbm::flt_greater_equal( sc_.depth_sl[l], depth))
618  {
619  l_0 = l;
620  break;
621  }
622  }
623  //l_1 must at least one layer below l_0
624  l_1 = l_0 + 1;
625  for ( size_t l = l_0 + 1; l < sl_.soil_layer_cnt(); ++l)
626  {
627  /* distribute at least among 4cm soil profile */
628  if ( cbm::flt_greater_equal( sc_.depth_sl[l], depth + 0.04))
629  {
630  l_1 = l;
631  break;
632  }
633  }
634  }
635 
636  for ( size_t sl = l_0; sl < l_1; ++sl)
637  {
638  double const layer_fraction( 1.0 / double(l_1 - l_0));
639  if ( cbm::flt_greater_zero( ph_manure))
640  {
641  sc_.ph_sl[sl] = ph_manure;
642  }
643  double const layer_fraction_ae( (1.0 - sc_.anvf_sl[sl]) * layer_fraction);
644  double const layer_fraction_an( sc_.anvf_sl[sl] * layer_fraction);
645 
646  don_ae_sl[sl] += add_n_don * layer_fraction_ae;
647  don_an_sl[sl] += add_n_don * layer_fraction_an;
648  nh4_ae_sl[sl] += add_n_nh4 * layer_fraction_ae;
649  nh4_an_sl[sl] += add_n_nh4 * layer_fraction_an;
650  no3_ae_sl[sl] += add_n_no3 * layer_fraction_ae;
651  no3_an_sl[sl] += add_n_no3 * layer_fraction_an;
652  sc_.urea_sl[sl] += add_n_urea * layer_fraction;
653 
654  sc_.doc_sl[sl] += add_c_doc * layer_fraction_ae;
655  sc_.an_doc_sl[sl] += add_c_doc * layer_fraction_an;
656 
657  sc_.C_aorg_sl[sl] += add_c_aorg * layer_fraction;
658  sc_.N_aorg_sl[sl] += add_n_aorg * layer_fraction;
659 
660  sc_.C_lit1_sl[sl] += add_c_lit_1 * layer_fraction;
661  sc_.C_lit2_sl[sl] += add_c_lit_2 * layer_fraction;
662  sc_.C_lit3_sl[sl] += add_c_lit_3 * layer_fraction;
663 
664  sc_.N_lit1_sl[sl] += add_n_lit_1 * layer_fraction;
665  sc_.N_lit2_sl[sl] += add_n_lit_2 * layer_fraction;
666  sc_.N_lit3_sl[sl] += add_n_lit_3 * layer_fraction;
667 
668  accumulated_n_nh4_fertilization_sl[sl] += add_n_nh4 * layer_fraction;
669  accumulated_n_no3_fertilization_sl[sl] += add_n_no3 * layer_fraction;
670  accumulated_n_don_fertilization_sl[sl] += add_n_don * layer_fraction;
671  accumulated_n_urea_fertilization_sl[sl] += add_n_urea * layer_fraction;
672  accumulated_n_litter_fertilization_sl[sl] += (add_n_lit_1 + add_n_lit_2 + add_n_lit_3) * layer_fraction;
673  accumulated_n_aorg_fertilization_sl[sl] += add_n_aorg * layer_fraction;
674  }
675 
676  cbm::state_scratch_t * mcom = io_kcomm->get_scratch();
677 
678  new_manure_n += sc_.accumulated_n_fertilizer;
679  double old_manure_n( 0.0);
680  mcom->get( "manure:amountN", &old_manure_n, 0.0);
681  mcom->set( "manure:amountN", old_manure_n + (new_manure_n * cbm::M2_IN_HA));
682 
683  new_manure_c += sc_.accumulated_c_fertilizer;
684  double old_manure_c( 0.0);
685  mcom->get( "manure:amountC", &old_manure_c, 0.0);
686  mcom->set( "manure:amountC", old_manure_c + (new_manure_c * cbm::M2_IN_HA));
687  }
688 
689  return LDNDC_ERR_OK;
690 }
Here is the caller graph for this function:

◆ MeTrX_metabolism()

lerr_t ldndc::SoilChemistryMeTrX::MeTrX_metabolism ( )
private
Parameters
[in]None
[out]None
Returns
error code

Referenced by solve().

188 {
189  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
190  {
191  double const metabolism_rate( 0.1 * FTS_TOT_);
192 
193  double const mic_12( sc_.C_micro1_sl[sl] + sc_.C_micro2_sl[sl]);
194  double const mic_23( sc_.C_micro2_sl[sl] + sc_.C_micro3_sl[sl]);
195 
196  if ( cbm::flt_greater_zero( mic_12))
197  {
198  double const fact_mic_12( sc_.anvf_sl[sl]);
199  double trans_12( (fact_mic_12 * mic_12 - sc_.C_micro2_sl[sl]) * metabolism_rate);
200  if ( cbm::flt_greater_zero( trans_12))
201  {
202  double const trans_max( cbm::bound_min( 0.0, sc_.C_micro1_sl[sl] - MICRO_C_MIN));
203  trans_12 = cbm::bound_max( trans_12, trans_max);
204  sc_.C_micro1_sl[sl] -= trans_12;
205  sc_.C_micro2_sl[sl] += trans_12;
206  }
207  else
208  {
209  double const trans_max( cbm::bound_min( 0.0, sc_.C_micro2_sl[sl] - MICRO_C_MIN));
210  trans_12 = cbm::bound_max( -trans_12, trans_max);
211  sc_.C_micro2_sl[sl] -= trans_12;
212  sc_.C_micro1_sl[sl] += trans_12;
213  }
214  }
215 
216  if ( cbm::flt_greater_zero( mic_23))
217  {
218  double const fact_mic_23( 1.0 - no3_an_sl[sl] / (no3_an_sl[sl] + (NO3_MOLAR_MAX_FE_RED * sc_.h_sl[sl] * M_N_SCALE)));
219  double trans_23( (fact_mic_23 * mic_23 - sc_.C_micro3_sl[sl]) * metabolism_rate);
220  if ( cbm::flt_greater_zero( trans_23))
221  {
222  double const trans_max( cbm::bound_min( 0.0, sc_.C_micro2_sl[sl] - MICRO_C_MIN));
223  trans_23 = cbm::bound_max( trans_23, trans_max);
224  sc_.C_micro2_sl[sl] -= trans_23;
225  sc_.C_micro3_sl[sl] += trans_23;
226  }
227  else
228  {
229  double const trans_max( cbm::bound_min( 0.0, sc_.C_micro3_sl[sl] - MICRO_C_MIN));
230  trans_23 = cbm::bound_max( -trans_23, trans_max);
231  sc_.C_micro3_sl[sl] -= trans_23;
232  sc_.C_micro2_sl[sl] += trans_23;
233  }
234  }
235  }
236  return LDNDC_ERR_OK;
237 }
Here is the caller graph for this function:

◆ MeTrX_microbial_dynamics()

void ldndc::SoilChemistryMeTrX::MeTrX_microbial_dynamics ( )
private
Parameters
[in]None
[out]None
Returns
void

Referenced by solve().

Here is the caller graph for this function:

◆ MeTrX_nh3_nh4_equilibrium()

void ldndc::SoilChemistryMeTrX::MeTrX_nh3_nh4_equilibrium ( )
private
Parameters
[in]None
[out]None
Returns
void

References MeTrX_get_ph_wl().

Referenced by solve().

33 {
34  if ( have_water_table)
35  {
36  double ph( MeTrX_get_ph_wl());
37  for ( size_t wl = 0; wl < sb_.surfacebulk_layer_cnt(); wl++)
38  {
39  double const k_a( pow( 10.0,(-2728.3 / (mc_temp_sl[0] + cbm::D_IN_K) - 0.094219))); // Sadeghi et al. (1988) (for 5 < ph < 10)
40 
41  double const n_tot( sb_.nh4_sbl[wl] + sb_.nh3_sbl[wl]);
42  double const frac_nh3( cbm::bound_max( 1.0 / (1.0 + (pow(10.0, - ph) / k_a)), 0.99));
43 
44  double const delta_nh3( frac_nh3 * n_tot - sb_.nh3_sbl[wl]);
45  if( cbm::flt_greater( delta_nh3, 0.0))
46  {
47  sb_.nh3_sbl[wl] += delta_nh3;
48  sb_.nh4_sbl[wl] = cbm::bound_min( 0.0, sb_.nh4_sbl[wl] - delta_nh3);
49  accumulated_n_nh4_nh3_conversion_sbl[wl] += delta_nh3;
50  }
51  else if( cbm::flt_less( delta_nh3, 0.0))
52  {
53  sb_.nh3_sbl[wl] = cbm::bound_min( 0.0, sb_.nh3_sbl[wl] + delta_nh3);
54  sb_.nh4_sbl[wl] -= delta_nh3;
55  accumulated_n_nh3_nh4_conversion_sbl[wl] -= delta_nh3;
56  }
57  }
58  }
59 
60  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
61  {
62  double const k_a( pow( 10.0, -2728.3 / (mc_temp_sl[sl] + cbm::D_IN_K) - 0.094219));
63  double const nh4_tot( nh4_ae_sl[sl] + nh4_an_sl[sl]);
64  double const n_tot( nh4_tot + sc_.nh3_liq_sl[sl]);
65  double const frac_nh3( cbm::bound_max( 1.0 / (1.0 + (pow(10.0, - sc_.ph_sl[sl]) / k_a)), 0.99));
66 
67  double const delta_nh3( frac_nh3 * n_tot - sc_.nh3_liq_sl[sl]);
68  if ( cbm::flt_greater( delta_nh3, 0.0))
69  {
70  sc_.nh3_liq_sl[sl] += delta_nh3;
71  double const delta_nh4_ae( nh4_ae_sl[sl] / nh4_tot * delta_nh3);
72  double const delta_nh4_an( delta_nh3 - delta_nh4_ae);
73  nh4_ae_sl[sl] = cbm::bound_min( 0.0, nh4_ae_sl[sl] - delta_nh4_ae);
74  nh4_an_sl[sl] = cbm::bound_min( 0.0, nh4_an_sl[sl] - delta_nh4_an);
75  accumulated_n_nh4_nh3_conversion_sl[sl] += delta_nh3;
76  }
77  else if ( cbm::flt_less( delta_nh3, 0.0))
78  {
79  sc_.nh3_liq_sl[sl] = cbm::bound_min( 0.0, sc_.nh3_liq_sl[sl] + delta_nh3);
80  nh4_ae_sl[sl] -= delta_nh3 * (1.0 - sc_.anvf_sl[sl]);
81  nh4_an_sl[sl] -= delta_nh3 * sc_.anvf_sl[sl];
82  accumulated_n_nh3_nh4_conversion_sl[sl] -= delta_nh3;
83  }
84  }
85 }
double MeTrX_get_ph_wl()
Definition: soilchemistry-metrx-physics-chemistry.cpp:528
Here is the call graph for this function:
Here is the caller graph for this function:

◆ MeTrX_nitrification()

void ldndc::SoilChemistryMeTrX::MeTrX_nitrification ( )
private
Parameters
[in]None
[out]None
Returns
void

Referenced by solve().

Here is the caller graph for this function:

◆ MeTrX_nitrogen_fertilizer_release()

lerr_t ldndc::SoilChemistryMeTrX::MeTrX_nitrogen_fertilizer_release ( )
private

Transforms nitrogen from slow release nitrogen fertilizer to nh4.

Parameters
[in]None
[out]None
Returns
void

Referenced by solve().

947 {
948  double const coated_nh4_sbl_sum( sb_.coated_nh4_sbl.sum());
949  double const coated_nh4_sl_sum( sc_.coated_nh4_sl.sum());
950  double const coated_nh4_sum( coated_nh4_sbl_sum + coated_nh4_sl_sum);
951  if ( !cbm::flt_greater_zero( coated_nh4_sum))
952  { return LDNDC_ERR_OK; }
953 
954  if ( cbm::flt_greater_zero( coated_nh4_sbl_sum))
955  {
956  for ( size_t sbl = 0; sbl < sb_.surfacebulk_layer_cnt(); ++sbl)
957  {
958  crnf_.update_crnf( 1.0, mc_temp_sl[0], FTS_TOT_, sb_.nh4_sbl[sbl] / coated_nh4_sum);
959  }
960  }
961 
962  if ( cbm::flt_greater_zero( coated_nh4_sl_sum))
963  {
964  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
965  {
966  crnf_.update_crnf( MeTrX_get_wfps( sl), mc_temp_sl[sl], FTS_TOT_, sc_.coated_nh4_sl[sl] / coated_nh4_sum);
967  }
968  }
969 
970  double coated_nh4_release( crnf_.get_crnf_release( coated_nh4_sum));
971  if ( !cbm::flt_greater_zero( coated_nh4_release))
972  { return LDNDC_ERR_OK; }
973 
974  double const scale( coated_nh4_release / coated_nh4_sum);
975 
976  if ( cbm::flt_greater( scale, 0.99))
977  {
978  if ( cbm::flt_greater_zero( coated_nh4_sbl_sum))
979  {
980  for ( size_t sbl = 0; sbl < sb_.surfacebulk_layer_cnt(); ++sbl)
981  {
982  sb_.nh4_sbl[sbl] += sb_.coated_nh4_sbl[sbl];
983  sb_.coated_nh4_sbl[sbl] = 0.0;
984  }
985  }
986 
987  if ( cbm::flt_greater_zero( coated_nh4_sl_sum))
988  {
989  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
990  {
991  nh4_ae_sl[sl] += sc_.coated_nh4_sl[sl] * (1.0 - sc_.anvf_sl[sl]);
992  nh4_an_sl[sl] += sc_.coated_nh4_sl[sl] * sc_.anvf_sl[sl];
993  sc_.coated_nh4_sl[sl] = 0.0;
994  }
995  }
996  }
997  else
998  {
999  if ( cbm::flt_greater_zero( coated_nh4_sbl_sum))
1000  {
1001  for ( size_t sbl = 0; sbl < sb_.surfacebulk_layer_cnt(); ++sbl)
1002  {
1003  if ( cbm::flt_greater_zero( sb_.coated_nh4_sbl[sbl]))
1004  {
1005  double const n_transform( scale * sb_.coated_nh4_sbl[sbl]);
1006  sb_.coated_nh4_sbl[sbl] -= n_transform;
1007  sb_.nh4_sbl[sbl] += n_transform;
1008  }
1009  }
1010  }
1011 
1012  if ( cbm::flt_greater_zero( coated_nh4_sl_sum))
1013  {
1014  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
1015  {
1016  if ( cbm::flt_greater_zero( sc_.coated_nh4_sl[sl]))
1017  {
1018  double const n_transform( scale * sc_.coated_nh4_sl[sl]);
1019  sc_.coated_nh4_sl[sl] -= n_transform;
1020  nh4_ae_sl[sl] += n_transform * (1.0 - sc_.anvf_sl[sl]);
1021  nh4_an_sl[sl] += n_transform * sc_.anvf_sl[sl];
1022  }
1023  }
1024  }
1025  }
1026 
1027  return LDNDC_ERR_OK;
1028 }
Here is the caller graph for this function:

◆ MeTrX_pertubation()

lerr_t ldndc::SoilChemistryMeTrX::MeTrX_pertubation ( )
private
Parameters
[in]None
[out]None
Returns
error code

References MeTrX_anaerobic_volume().

Referenced by solve().

1367 {
1368  //Pertubation is only calculated once per day since it is a very slow process
1369  if ( lclock()->subday() == 1)
1370  {
1371  size_t sl_max_1( sl_.soil_layer_cnt()-1);
1372  double nmicro1_lowest_sl(n_micro_1_sl[sl_max_1]);
1373  double nmicro2_lowest_sl(n_micro_2_sl[sl_max_1]);
1374  double nmicro3_lowest_sl(n_micro_3_sl[sl_max_1]);
1375  double naorg_lowest_sl(sc_.N_aorg_sl[sl_max_1]);
1376  double nlit1_lowest_sl(sc_.N_lit1_sl[sl_max_1]);
1377  double nlit2_lowest_sl(sc_.N_lit2_sl[sl_max_1]);
1378  double nlit3_lowest_sl(sc_.N_lit3_sl[sl_max_1]);
1379  double nhum1_lowest_sl(n_humus_1_sl[sl_max_1]);
1380  double nhum2_lowest_sl(n_humus_2_sl[sl_max_1]);
1381  double nhum3_lowest_sl(n_humus_3_sl[sl_max_1]);
1382 
1383  lerr_t rc = transport_.pertubation(1.0, D_eff_dailyturbation_sl, sc_.C_micro1_sl, sc_.h_sl, interface_delta_x_soil_sl);
1384  if ( rc){ return rc; }
1385  rc = transport_.pertubation(1.0, D_eff_dailyturbation_sl, n_micro_1_sl, sc_.h_sl, interface_delta_x_soil_sl);
1386  if ( rc){ return rc; }
1387 
1388  rc = transport_.pertubation(1.0, D_eff_dailyturbation_sl, sc_.C_micro2_sl, sc_.h_sl, interface_delta_x_soil_sl);
1389  if ( rc){ return rc; }
1390  rc = transport_.pertubation(1.0, D_eff_dailyturbation_sl, n_micro_2_sl, sc_.h_sl, interface_delta_x_soil_sl);
1391  if ( rc){ return rc; }
1392 
1393  rc = transport_.pertubation(1.0, D_eff_dailyturbation_sl, sc_.C_micro3_sl, sc_.h_sl, interface_delta_x_soil_sl);
1394  if ( rc){ return rc; }
1395  rc = transport_.pertubation(1.0, D_eff_dailyturbation_sl, n_micro_3_sl, sc_.h_sl, interface_delta_x_soil_sl);
1396  if ( rc){ return rc; }
1397 
1398  rc = transport_.pertubation(1.0, D_eff_dailyturbation_sl, sc_.C_aorg_sl, sc_.h_sl, interface_delta_x_soil_sl);
1399  if ( rc){ return rc; }
1400  rc = transport_.pertubation(1.0, D_eff_dailyturbation_sl, sc_.N_aorg_sl, sc_.h_sl, interface_delta_x_soil_sl);
1401  if ( rc){ return rc; }
1402 
1403  rc = transport_.pertubation(1.0, D_eff_dailyturbation_sl, sc_.C_lit1_sl, sc_.h_sl, interface_delta_x_soil_sl);
1404  if ( rc){ return rc; }
1405  rc = transport_.pertubation(1.0, D_eff_dailyturbation_sl, sc_.N_lit1_sl, sc_.h_sl, interface_delta_x_soil_sl);
1406  if ( rc){ return rc; }
1407 
1408  rc = transport_.pertubation(1.0, D_eff_dailyturbation_sl, sc_.C_lit2_sl, sc_.h_sl, interface_delta_x_soil_sl);
1409  if ( rc){ return rc; }
1410  rc = transport_.pertubation(1.0, D_eff_dailyturbation_sl, sc_.N_lit2_sl, sc_.h_sl, interface_delta_x_soil_sl);
1411  if ( rc){ return rc; }
1412 
1413  rc = transport_.pertubation(1.0, D_eff_dailyturbation_sl, sc_.C_lit3_sl, sc_.h_sl, interface_delta_x_soil_sl);
1414  if ( rc){ return rc; }
1415  rc = transport_.pertubation(1.0, D_eff_dailyturbation_sl, sc_.N_lit3_sl, sc_.h_sl, interface_delta_x_soil_sl);
1416  if ( rc){ return rc; }
1417 
1418  rc = transport_.pertubation(1.0, D_eff_dailyturbation_sl, c_humus_1_sl, sc_.h_sl, interface_delta_x_soil_sl);
1419  if ( rc){ return rc; }
1420  rc = transport_.pertubation(1.0, D_eff_dailyturbation_sl, n_humus_1_sl, sc_.h_sl, interface_delta_x_soil_sl);
1421  if ( rc){ return rc; }
1422 
1423  rc = transport_.pertubation(1.0, D_eff_dailyturbation_sl, c_humus_2_sl, sc_.h_sl, interface_delta_x_soil_sl);
1424  if ( rc){ return rc; }
1425  rc = transport_.pertubation(1.0, D_eff_dailyturbation_sl, n_humus_2_sl, sc_.h_sl, interface_delta_x_soil_sl);
1426  if ( rc){ return rc; }
1427 
1428  rc = transport_.pertubation(1.0, D_eff_dailyturbation_sl, c_humus_3_sl, sc_.h_sl, interface_delta_x_soil_sl);
1429  if ( rc){ return rc; }
1430  rc = transport_.pertubation(1.0, D_eff_dailyturbation_sl, n_humus_3_sl, sc_.h_sl, interface_delta_x_soil_sl);
1431  if ( rc){ return rc; }
1432 
1433  if ( output_writer_.write_fluxes())
1434  {
1435  /* nmicro */
1436  transport_.calculate_soil_perturbation_fluxes( sl_.soil_layer_cnt(), 1.0, sc_.h_sl, interface_delta_x_soil_sl, D_eff_dailyturbation_sl, n_micro_1_sl, nmicro1_lowest_sl, communicate_sl);
1437  for (size_t sl = 0; sl < sl_.soil_layer_cnt(); sl++)
1438  {
1439  accumulated_n_micro_perturbation_sl[sl] += communicate_sl[sl];
1440  }
1441  transport_.calculate_soil_perturbation_fluxes( sl_.soil_layer_cnt(), 1.0, sc_.h_sl, interface_delta_x_soil_sl, D_eff_dailyturbation_sl, n_micro_2_sl, nmicro2_lowest_sl, communicate_sl);
1442  for (size_t sl = 0; sl < sl_.soil_layer_cnt(); sl++)
1443  {
1444  accumulated_n_micro_perturbation_sl[sl] += communicate_sl[sl];
1445  }
1446  transport_.calculate_soil_perturbation_fluxes( sl_.soil_layer_cnt(), 1.0, sc_.h_sl, interface_delta_x_soil_sl, D_eff_dailyturbation_sl, n_micro_3_sl, nmicro3_lowest_sl, communicate_sl);
1447  for (size_t sl = 0; sl < sl_.soil_layer_cnt(); sl++)
1448  {
1449  accumulated_n_micro_perturbation_sl[sl] += communicate_sl[sl];
1450  }
1451 
1452  /* naorg */
1453  transport_.calculate_soil_perturbation_fluxes( sl_.soil_layer_cnt(), 1.0, sc_.h_sl, interface_delta_x_soil_sl, D_eff_dailyturbation_sl, sc_.N_aorg_sl, naorg_lowest_sl, communicate_sl);
1454  for (size_t sl = 0; sl < sl_.soil_layer_cnt(); sl++)
1455  {
1456  accumulated_n_aorg_perturbation_sl[sl] += communicate_sl[sl];
1457  }
1458 
1459  /*litter*/
1460  transport_.calculate_soil_perturbation_fluxes( sl_.soil_layer_cnt(), 1.0, sc_.h_sl, interface_delta_x_soil_sl, D_eff_dailyturbation_sl, sc_.N_lit1_sl, nlit1_lowest_sl, communicate_sl);
1461  for (size_t sl = 0; sl < sl_.soil_layer_cnt(); sl++)
1462  {
1463  accumulated_n_litter_perturbation_sl[sl] += communicate_sl[sl];
1464  }
1465  transport_.calculate_soil_perturbation_fluxes( sl_.soil_layer_cnt(), 1.0, sc_.h_sl, interface_delta_x_soil_sl, D_eff_dailyturbation_sl, sc_.N_lit2_sl, nlit2_lowest_sl, communicate_sl);
1466  for (size_t sl = 0; sl < sl_.soil_layer_cnt(); sl++)
1467  {
1468  accumulated_n_litter_perturbation_sl[sl] += communicate_sl[sl];
1469  }
1470  transport_.calculate_soil_perturbation_fluxes( sl_.soil_layer_cnt(), 1.0, sc_.h_sl, interface_delta_x_soil_sl, D_eff_dailyturbation_sl, sc_.N_lit3_sl, nlit3_lowest_sl, communicate_sl);
1471  for (size_t sl = 0; sl < sl_.soil_layer_cnt(); sl++)
1472  {
1473  accumulated_n_litter_perturbation_sl[sl] += communicate_sl[sl];
1474  }
1475 
1476  /*humus*/
1477  transport_.calculate_soil_perturbation_fluxes( sl_.soil_layer_cnt(), 1.0, sc_.h_sl, interface_delta_x_soil_sl, D_eff_dailyturbation_sl, n_humus_1_sl, nhum1_lowest_sl, communicate_sl);
1478  for (size_t sl = 0; sl < sl_.soil_layer_cnt(); sl++)
1479  {
1480  accumulated_n_humus_1_perturbation_sl[sl] += communicate_sl[sl];
1481  }
1482  transport_.calculate_soil_perturbation_fluxes( sl_.soil_layer_cnt(), 1.0, sc_.h_sl, interface_delta_x_soil_sl, D_eff_dailyturbation_sl, n_humus_2_sl, nhum2_lowest_sl, communicate_sl);
1483  for (size_t sl = 0; sl < sl_.soil_layer_cnt(); sl++)
1484  {
1485  accumulated_n_humus_2_perturbation_sl[sl] += communicate_sl[sl];
1486  }
1487  transport_.calculate_soil_perturbation_fluxes( sl_.soil_layer_cnt(), 1.0, sc_.h_sl, interface_delta_x_soil_sl, D_eff_dailyturbation_sl, n_humus_3_sl, nhum3_lowest_sl, communicate_sl);
1488  for (size_t sl = 0; sl < sl_.soil_layer_cnt(); sl++)
1489  {
1490  accumulated_n_humus_3_perturbation_sl[sl] += communicate_sl[sl];
1491  }
1492  }
1493  }
1494  return LDNDC_ERR_OK;
1495 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ MeTrX_pH_calculation()

void ldndc::SoilChemistryMeTrX::MeTrX_pH_calculation ( )
private
Parameters
[in]None
[out]None
Returns
void

References MeTrX_get_ph_sl().

Referenced by solve().

543 {
544  for ( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
545  {
546  sc_.ph_sl[sl] = MeTrX_get_ph_sl( sl);
547  }
548 }
double MeTrX_get_ph_sl(size_t)
Returns dynamic pH-value of given soil layer.
Definition: soilchemistry-metrx-physics-chemistry.cpp:520
Here is the call graph for this function:
Here is the caller graph for this function:

◆ MeTrX_physics()

lerr_t ldndc::SoilChemistryMeTrX::MeTrX_physics ( )
private
Parameters
[in]None
[out]None
Returns
error code

References ldndc::d_eff_air_a(), ldndc::d_eff_air_millington_and_quirk_1961(), and TNORM.

Referenced by solve().

158 {
159  /*****************************/
160  /* Water-, Ice-, Air-Content */
161  /*****************************/
162 
163  for (size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
164  {
165  double const v_ice_old( v_ice_sl[sl]);
166  double const v_pores( sc_.h_sl[sl] * sc_.poro_sl[sl]);
167  v_water_sl[sl] = cbm::bound_min( 0.01 * v_pores, wc_.wc_sl[sl] / cbm::DWAT * sc_.h_sl[sl]);
168  v_ice_sl[sl] = cbm::bound_min( 0.0, wc_.ice_sl[sl] / cbm::DICE * sc_.h_sl[sl]);
169  v_air_sl[sl] = cbm::bound_min( 0.05 * v_pores, v_pores - v_water_sl[sl] - v_ice_sl[sl]);
170 
171  pore_connectivity_sl[sl] = cbm::bound(
172  0.001,
173  1.0 - exp( -sipar_.METRX_F_CONNECTIVITY_2() *
174  ((v_air_sl[sl] / sc_.h_sl[sl]) - sipar_.METRX_F_CONNECTIVITY_1())),
175  0.999);
176 
177  if ( have_freeze_thaw)
178  {
179  if ( cbm::flt_greater( v_ice_sl[sl], v_ice_old))
180  {
181  double const freeze_fraction( (v_ice_sl[sl] - v_ice_old) / v_ice_sl[sl]);
182 
183  double const delta_doc( freeze_fraction * (sc_.doc_sl[sl] + sc_.an_doc_sl[sl]));
184  doc_ice_sl[sl] += delta_doc;
185  sc_.doc_sl[sl] *= (1.0 - freeze_fraction);
186  sc_.an_doc_sl[sl] *= (1.0 - freeze_fraction);
187 
188  double const delta_acetate( freeze_fraction * (ae_acetate_sl[sl] + an_acetate_sl[sl]));
189  acetate_ice_sl[sl] += delta_acetate;
190  ae_acetate_sl[sl] *= (1.0 - freeze_fraction);
191  an_acetate_sl[sl] *= (1.0 - freeze_fraction);
192 
193  double const delta_no3( freeze_fraction * (no3_ae_sl[sl] + no3_an_sl[sl]));
194  no3_ice_sl[sl] += delta_no3;
195  no3_ae_sl[sl] *= (1.0 - freeze_fraction);
196  no3_an_sl[sl] *= (1.0 - freeze_fraction);
197 
198  double const delta_nh4( freeze_fraction * (nh4_ae_sl[sl] + nh4_an_sl[sl]));
199  nh4_ice_sl[sl] += delta_nh4;
200  nh4_ae_sl[sl] *= (1.0 - freeze_fraction);
201  nh4_an_sl[sl] *= (1.0 - freeze_fraction);
202 
203  double const delta_don( freeze_fraction * (don_ae_sl[sl] + don_an_sl[sl]));
204  don_ice_sl[sl] += delta_don;
205  don_ae_sl[sl] *= (1.0 - freeze_fraction);
206  don_an_sl[sl] *= (1.0 - freeze_fraction);
207  }
208  else if ( cbm::flt_less( v_ice_sl[sl], v_ice_old))
209  {
210  double const melt_fraction( (v_ice_old > 0.0)? (v_ice_old - v_ice_sl[sl]) / v_ice_old : 1.0);
211 
212  double const delta_doc( melt_fraction * doc_ice_sl[sl]);
213  sc_.doc_sl[sl] += delta_doc * (1.0 - sc_.anvf_sl[sl]);
214  sc_.an_doc_sl[sl] += delta_doc * sc_.anvf_sl[sl];
215  doc_ice_sl[sl] *= (1.0 - melt_fraction);
216 
217  double const delta_acetate( melt_fraction * acetate_ice_sl[sl]);
218  ae_acetate_sl[sl] += delta_acetate * (1.0 - sc_.anvf_sl[sl]);
219  an_acetate_sl[sl] += delta_acetate * sc_.anvf_sl[sl];
220  acetate_ice_sl[sl] *= (1.0 - melt_fraction);
221 
222  double const delta_no3( melt_fraction * no3_ice_sl[sl]);
223  no3_ae_sl[sl] += delta_no3 * (1.0 - sc_.anvf_sl[sl]);
224  no3_an_sl[sl] += delta_no3 * sc_.anvf_sl[sl];
225  no3_ice_sl[sl] *= (1.0 - melt_fraction);
226 
227  double const delta_nh4( melt_fraction * nh4_ice_sl[sl]);
228  nh4_ae_sl[sl] += delta_nh4 * (1.0 - sc_.anvf_sl[sl]);
229  nh4_an_sl[sl] += delta_nh4 * sc_.anvf_sl[sl];
230  nh4_ice_sl[sl] *= (1.0 - melt_fraction);
231 
232  double const delta_don( melt_fraction * don_ice_sl[sl]);
233  don_ae_sl[sl] += delta_don * (1.0 - sc_.anvf_sl[sl]);
234  don_an_sl[sl] += delta_don * sc_.anvf_sl[sl];
235  don_ice_sl[sl] *= (1.0 - melt_fraction);
236  }
237  }
238  }
239 
240  size_t sl_max( sl_.soil_layer_cnt()-1);
241  for (size_t sl = 0; sl < sl_max; ++sl)
242  {
243  interface_air_sl[sl] = cbm::harmonic_mean2( v_air_sl[sl]/sc_.h_sl[sl], v_air_sl[sl+1]/sc_.h_sl[sl+1]);
244  interface_delta_x_air_sl[sl] = interface_air_sl[sl] / delta_x[sl];
245  interface_delta_x_water_sl[sl] = cbm::harmonic_mean2( v_water_sl[sl]/sc_.h_sl[sl], v_water_sl[sl+1]/sc_.h_sl[sl+1]) / delta_x[sl];
246  interface_delta_x_soil_sl[sl] = 1.0;
247  }
248  interface_air_sl[sl_max] = v_air_sl[sl_max]/sc_.h_sl[sl_max];
249  interface_delta_x_air_sl[sl_max] = interface_air_sl[sl_max] / delta_x[sl_max];
250  interface_delta_x_water_sl[sl_max] = v_water_sl[sl_max]/sc_.h_sl[sl_max] / delta_x[sl_max];
251  interface_delta_x_soil_sl[sl_max] = 1.0;
252 
253 
254  double interface_delta_x_atm_soil( 0.0);
255  double interface_delta_x_fl_soil( 0.0);
256  double interface_delta_x_sbl_soil( 0.0);
257 
258  if ( have_water_table)
259  {
260  interface_delta_x_sbl_soil = (cbm::harmonic_mean2( 1.0, v_water_sl[0]/sc_.h_sl[0]) / cbm::arithmetic_mean2( h_wl, sc_.h_sl[0]));
261  }
262  else
263  {
264  /* Set atmospheric Dirichlet boundary condition at ground level */
265  interface_delta_x_atm_soil = (cbm::harmonic_mean2( 1.0, v_air_sl[0]/sc_.h_sl[0]) / (0.5 * sc_.h_sl[0]));
266  interface_delta_x_fl_soil = (cbm::harmonic_mean2( 1.0, v_air_sl[0]/sc_.h_sl[0]) / cbm::arithmetic_mean2( ph_.h_fl[0], sc_.h_sl[0]));
267  }
268 
269 
270 
271  /************************************/
272  /* Effective Diffusion Coefficients */
273  /************************************/
274 
275  /* Plant mediated diffusion */
276 
277  for ( PlantIterator vt = this->m_veg->begin(); vt != this->m_veg->end(); ++vt)
278  {
279  MoBiLE_Plant *p = *vt;
280  if ( cbm::flt_greater_zero( p->root_tc))
281  {
282  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
283  {
284  D_eff_plant_sl[sl] = (p->root_tc * p->fFrt_sl[sl]);
285  }
286  have_plant_diffusion = true;
287  }
288  else
289  {
290  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
291  {
292  D_eff_plant_sl[sl] = 0.0;
293  }
294  have_plant_diffusion = false;
295  }
296  }
297 
298 
299  /* Soil diffusion */
300 
301  /* Effective diffusion coefficients relates to the tortuosity of the soil matrix.
302  * Formular is taken from Lai, S.H., J.M. Tiedje, and A.E. Erickson. 1976.
303  * In situ measurement of gas diffusion coefficient in soils, Soil Sci. Soc. Am. J., 40:3–6
304  * tortuosity = theta^(7/3)
305  * theta refers to soil gas content: volume_gas / volume_soil
306  *
307  * Stone content is considered in order to derive characteristic gas content for soil matrix
308  * only, i.e., excluding the stone fraction of the soil. Stone fractions are implicitly incorporated into
309  * the gaseous diffusion by the reduction of the diffusive interface area between soil layers
310  */
311  if ( d_eff_method == "parameter")
312  {
313  for (size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
314  {
315  double const air_content( v_air_sl[sl] / (sc_.h_sl[sl] * (1.0 - sc_.stone_frac_sl[sl])));
316  double const d_eff( d_eff_air_a( 7.0/3.0, air_content)
317  * pow((mc_temp_sl[sl] + cbm::D_IN_K) / TNORM, sipar_.TEXP())) ;
318 
319  /* Empirical reduction of gaseous diffsuion */
320  double const till_effect( MeTrX_get_wfps( sl) + (1.0 - MeTrX_get_wfps( sl)) * sc_.till_effect_sl[sl]);
321  D_eff_air_sl[sl] = cbm::bound_max( sipar_.METRX_D_EFF_REDUCTION() * d_eff * till_effect, 1.0);
322  }
323  }
324  else if ( d_eff_method == "millington_and_quirk_1961")
325  {
326  for (size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
327  {
328  double const air_content( v_air_sl[sl] / (sc_.h_sl[sl] * (1.0 - sc_.stone_frac_sl[sl])));
329  double const d_eff( d_eff_air_millington_and_quirk_1961( air_content, sc_.poro_sl[sl])
330  * pow((mc_temp_sl[sl] + cbm::D_IN_K) / TNORM, sipar_.TEXP())) ;
331 
332  /* Empirical reduction of gaseous diffsuion */
333  double const till_effect( MeTrX_get_wfps( sl) + (1.0 - MeTrX_get_wfps( sl)) * sc_.till_effect_sl[sl]);
334  D_eff_air_sl[sl] = cbm::bound_max( sipar_.METRX_D_EFF_REDUCTION() * d_eff * till_effect, 1.0);
335  }
336  }
337  else
338  {
339  KLOGERROR("invalid effective diffusion approach: [", d_eff_method,"]");
340  return LDNDC_ERR_FAIL;
341  }
342 
343  if (wc_.surface_ice > 0.01)
344  {
345  D_eff_air_sl[0] *= 0.01 / wc_.surface_ice;
346  }
347  for (size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
348  {
349  /* Preliminary set to any value */
350  D_eff_water_sl[sl] = pow( MeTrX_get_wfps( sl), 2.0);
351 
352  //pertubation / earthworms activity decreases with depth and soil water saturation
353  D_eff_dailyturbation_sl[sl] = std::exp( - sc_.depth_sl[sl] / sipar_.METRX_F_PERTUBATION_EXP())
354  * sipar_.METRX_F_PERTUBATION_MIX() * (1.0 - MeTrX_get_wfps( sl));
355  }
356 
357  /*******************************/
358  /* Update transport properties */
359  /*******************************/
360 
361  transport_.update_diffusion( D_eff_plant_sl, D_eff_air_sl,
362  v_air_sl,
363  soil_gas_advection_sl,
364  interface_delta_x_air_sl,
365  interface_delta_x_atm_soil,
366  interface_delta_x_fl_soil,
367  interface_delta_x_sbl_soil,
368  h_wl,
369  have_water_table);
370  transport_.update_advection( interface_air_sl);
371 
372  double const d_wind_scale( 1.0 + (*mc_wind) / ((*mc_wind) + 5.0) * 2.0);
373  transport_.wind_stimulation = d_wind_scale;
374 
375  for ( std::map< std::string , double>::iterator it = sc_.n_subdivision.begin();
376  it != sc_.n_subdivision.end(); )
377  {
378  it->second -= 0.02 * FTS_TOT_;
379  if ( !cbm::flt_greater_zero( it->second))
380  {
381  sc_.n_subdivision.erase( it++);
382  }
383  else{ ++it; }
384  }
385 
386  return LDNDC_ERR_OK;
387 }
static const double TNORM
Definition: soilchemistry-metrx.h:33
double d_eff_air_millington_and_quirk_1961(double const &, double const &)
Returns effective diffusion coefficient after .
Definition: ld_effective_diffusion_coefficient.cpp:40
double d_eff_air_a(double const &, double const &)
Returns effective diffusion coefficient depending on gas content.
Definition: ld_effective_diffusion_coefficient.cpp:16
Here is the call graph for this function:
Here is the caller graph for this function:

◆ MeTrX_receive_state()

lerr_t ldndc::SoilChemistryMeTrX::MeTrX_receive_state ( )
private
Parameters
[in]None
[out]None
Returns
error code

Referenced by MeTrX_update().

271 {
272  for ( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
273  {
274  if ( cbm::flt_greater_zero( sc_.nh4_sl[sl]))
275  {
276  double const nh4_old( nh4_ae_sl[sl] + nh4_an_sl[sl]);
277  if ( cbm::flt_greater_zero( nh4_old))
278  {
279  nh4_ae_sl[sl] = cbm::bound_min( 0.0, nh4_ae_sl[sl] / nh4_old * sc_.nh4_sl[sl]);
280  nh4_an_sl[sl] = cbm::bound_min( 0.0, sc_.nh4_sl[sl] - nh4_ae_sl[sl]);
281  }
282  else
283  {
284  nh4_ae_sl[sl] = (1.0 - sc_.anvf_sl[sl]) * sc_.nh4_sl[sl];
285  nh4_an_sl[sl] = sc_.anvf_sl[sl] * sc_.nh4_sl[sl];
286  }
287  }
288  else
289  {
290  nh4_ae_sl[sl] = 0.0;
291  nh4_an_sl[sl] = 0.0;
292  }
293 
294  if ( cbm::flt_greater_zero( sc_.don_sl[sl]))
295  {
296  double const don_old( don_ae_sl[sl] + don_an_sl[sl]);
297  if ( cbm::flt_greater_zero( don_old))
298  {
299  don_ae_sl[sl] = cbm::bound_min( 0.0, don_ae_sl[sl] / don_old * sc_.don_sl[sl]);
300  don_an_sl[sl] = cbm::bound_min( 0.0, sc_.don_sl[sl] - don_ae_sl[sl]);
301  }
302  else
303  {
304  don_ae_sl[sl] = (1.0 - sc_.anvf_sl[sl]) * sc_.don_sl[sl];
305  don_an_sl[sl] = sc_.anvf_sl[sl] * sc_.don_sl[sl];
306  }
307  }
308  else
309  {
310  don_ae_sl[sl] = 0.0;
311  don_an_sl[sl] = 0.0;
312  }
313 
314  double no3_tot( sc_.no3_sl[sl] + sc_.an_no3_sl[sl]);
315  if ( cbm::flt_greater_zero( no3_tot))
316  {
317  double const no3_old( no3_ae_sl[sl] + no3_an_sl[sl]);
318  if ( cbm::flt_greater_zero( no3_old))
319  {
320  no3_ae_sl[sl] = cbm::bound_min( 0.0, no3_ae_sl[sl] / no3_old * no3_tot);
321  no3_an_sl[sl] = cbm::bound_min( 0.0, no3_tot - no3_ae_sl[sl]);
322  }
323  else
324  {
325  no3_ae_sl[sl] = (1.0 - sc_.anvf_sl[sl]) * no3_tot;
326  no3_an_sl[sl] = sc_.anvf_sl[sl] * no3_tot;
327  }
328  }
329  else
330  {
331  no3_ae_sl[sl] = 0.0;
332  no3_an_sl[sl] = 0.0;
333  }
334  }
335 
336  return LDNDC_ERR_OK;
337 }
Here is the caller graph for this function:

◆ MeTrX_reset()

lerr_t ldndc::SoilChemistryMeTrX::MeTrX_reset ( )
private
Parameters
[in]None
[out]None
Returns
void

References MeTrX_reset_daily(), and MeTrX_reset_subdaily().

Referenced by solve().

37 {
38  co2_auto_sl = 0.0;
39  co2_hetero_sl = 0.0;
40 
41  if ( timemode_ == TMODE_SUBDAILY)
42  {
43  if ( lclock()->is_position( TMODE_PRE_DAILY))
44  {
47  }
48  }
49  else
50  {
53  }
54 
55  return LDNDC_ERR_OK;
56 }
lerr_t MeTrX_reset_subdaily()
Definition: soilchemistry-metrx-reset.cpp:64
lerr_t MeTrX_reset_daily()
Definition: soilchemistry-metrx-reset.cpp:113
Here is the call graph for this function:
Here is the caller graph for this function:

◆ MeTrX_reset_daily()

lerr_t ldndc::SoilChemistryMeTrX::MeTrX_reset_daily ( )
private
Parameters
[in]None
[out]None
Returns
void

Referenced by MeTrX_reset().

114 {
115  /* Soil layer variables */
116  for (size_t sl = 0; sl < sl_.soil_layer_cnt(); sl++)
117  {
118  plant_o2_consumption_sl[sl] = 0.0;
119 
120  day_nitrify_n2o_sl[sl] = 0.0;
121  day_nit_no2_no3_sl[sl] = 0.0;
122 
123  day_acetate_cons_fe3_sl[sl] = 0.0;
124  day_h2_c_eq_cons_fe3_sl[sl] = 0.0;
125  day_fe2_oxidation_sl[sl] = 0.0;
126 
127  day_acetate_prod_sl[sl] = 0.0;
128 
129  day_ch4_oxidation_sl[sl] = 0.0;
130 
131  day_h2_c_eq_prod_sl[sl] = 0.0;
132  day_ch4_production_acetate_sl[sl] = 0.0;
133  day_ch4_production_hydrogen_sl[sl] = 0.0;
134 
135  day_doc_prod_sl[sl] = 0.0;
136  day_denit_factor_c_sl[sl] = 0.0;
137  day_denit_factor_n_sl[sl] = 0.0;
138  }
139 
140  // Groundwater access
141  day_no3_groundwater_access = 0.0;
142 
143  // Mineralisation
144  day_min_n_decomp = 0.0;
145  day_min_n_aorg = 0.0;
146  day_min_n_mic_1 = 0.0;
147  day_min_n_mic_2 = 0.0;
148  day_min_n_mic_3 = 0.0;
149 
150  // Assimilation
151  day_assi_n_mic_1 = 0.0;
152  day_assi_n_mic_2 = 0.0;
153  day_assi_n_mic_3 = 0.0;
154  day_assi_c_mic_1 = 0.0;
155  day_assi_c_mic_2 = 0.0;
156  day_assi_c_mic_3 = 0.0;
157 
158  // Nitrification
159  day_nit_nh4_no2 = 0.0;
160  day_nit_no2_no = 0.0;
161  day_nit_no2_n2o = 0.0;
162  day_nit_no2_no3_sl = 0.0;
163 
164  // Denitrification
165  day_denit_no3_no2 = 0.0;
166  day_denit_no2_no = 0.0;
167  day_denit_no2_n2o = 0.0;
168  day_denit_no2_n2 = 0.0;
169  day_denit_no_n2o = 0.0;
170  day_denit_no_n2 = 0.0;
171  day_denit_n2o_n2 = 0.0;
172  day_chemodenit_no2_no = 0.0;
173 
174  // Respiration / Fermentation / Methanogenesis
175  day_co2_prod_mic_1_growth = 0.0;
176  day_co2_prod_mic_1_maintenance = 0.0;
177  day_co2_prod_mic_2 = 0.0;
178  day_co2_prod_mic_3_acetate_prod = 0.0;
179  day_co2_prod_mic_3_acetate_cons = 0.0;
180  day_co2_prod_ch4_prod = 0.0;
181  day_co2_prod_ch4_cons = 0.0;
182 
183  // Leaching
184  day_leach_o2 = 0.0;
185  day_leach_n2o = 0.0;
186  day_leach_n2 = 0.0;
187  day_leach_no = 0.0;
188  day_leach_nh3 = 0.0;
189  day_leach_urea = 0.0;
190 
191  // litter
192  dC_root_exsudates = 0.0;
193  dC_litter_algae = 0.0;
194 
195  // Decomposition
196  day_decomp_c_lit_1 = 0.0;
197  day_decomp_c_lit_2 = 0.0;
198  day_decomp_c_lit_3 = 0.0;
199  day_decomp_n_lit_1 = 0.0;
200  day_decomp_n_lit_2 = 0.0;
201  day_decomp_n_lit_3 = 0.0;
202  day_decomp_c_hum_1_sl = 0.0;
203  day_decomp_c_hum_2_sl = 0.0;
204  day_decomp_c_hum_3_sl = 0.0;
205  day_decay_c_mic_sl = 0.0;
206  day_decomp_n_hum_1 = 0.0;
207  day_decomp_n_hum_2 = 0.0;
208  day_decomp_n_hum_3 = 0.0;
209 
210  // Humification
211  day_c_humify_doc_hum_1_sl = 0.0;
212  day_c_humify_sol_hum_1_sl = 0.0;
213  day_c_humify_cel_hum_1_sl = 0.0;
214  day_c_humify_lig_hum_1_sl = 0.0;
215  day_c_humify_lig_hum_2_sl = 0.0;
216  day_c_humify_mic_hum_1_sl = 0.0;
217  day_c_humify_mic_hum_2_sl = 0.0;
218  day_c_humify_hum_1_hum_2_sl = 0.0;
219  day_c_humify_hum_2_hum_3_sl = 0.0;
220 
221  // Algae
222  day_n_fix_algae = 0.0;
223  day_c_fix_algae = 0.0;
224 
225  // DOC production
226  day_doc_prod_decomp_litter = 0.0;
227  day_doc_prod_decomp_humus = 0.0;
228  day_doc_prod_decomp_aorg = 0.0;
229 
230  return LDNDC_ERR_OK;
231 }
Here is the caller graph for this function:

◆ MeTrX_reset_subdaily()

lerr_t ldndc::SoilChemistryMeTrX::MeTrX_reset_subdaily ( )
private
Parameters
[in]None
[out]None
Returns
void

Referenced by MeTrX_reset().

65 {
66  for (size_t ts = 0; ts < TOTAL_TIME_STEPS; ts++)
67  {
68  subdaily_co2_bubbling[ts] = 0.0;
69  subdaily_co2_plant[ts] = 0.0;
70  subdaily_co2_soil[ts] = 0.0;
71  subdaily_co2_water[ts] = 0.0;
72  subdaily_co2_leach[ts] = 0.0;
73 
74  subdaily_ch4_bubbling[ts] = 0.0;
75  subdaily_ch4_plant[ts] = 0.0;
76  subdaily_ch4_soil[ts] = 0.0;
77  subdaily_ch4_water[ts] = 0.0;
78  subdaily_ch4_leach[ts] = 0.0;
79  subdaily_ch4_prod[ts] = 0.0;
80  subdaily_ch4_ox[ts] = 0.0;
81  subdaily_acetate_prod[ts] = 0.0;
82  subdaily_doc_prod[ts] = 0.0;
83  subdaily_plant_o2_cons[ts] = 0.0;
84  subdaily_flood_o2_conc[ts] = 0.0;
85  subdaily_algae_o2_prod[ts] = 0.0;
86  subdaily_o2_bubbling[ts] = 0.0;
87  subdaily_o2_plant[ts] = 0.0;
88  subdaily_o2_soil[ts] = 0.0;
89  subdaily_o2_water[ts] = 0.0;
90  subdaily_n2o_bubbling[ts] = 0.0;
91  subdaily_n2o_plant[ts] = 0.0;
92  subdaily_n2o_soil[ts] = 0.0;
93  subdaily_n2o_water[ts] = 0.0;
94  subdaily_no_bubbling[ts] = 0.0;
95  subdaily_no_plant[ts] = 0.0;
96  subdaily_no_soil[ts] = 0.0;
97  subdaily_no_water[ts] = 0.0;
98  subdaily_nh3_bubbling[ts] = 0.0;
99  subdaily_nh3_plant[ts] = 0.0;
100  subdaily_nh3_soil[ts] = 0.0;
101  subdaily_nh3_water[ts] = 0.0;
102  }
103 
104  return LDNDC_ERR_OK;
105 }
Here is the caller graph for this function:

◆ MeTrX_send_state()

lerr_t ldndc::SoilChemistryMeTrX::MeTrX_send_state ( )
private
Parameters
[in]None
[out]None
Returns
error code

Referenced by MeTrX_write_rates().

346 {
347  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
348  {
349  sc_.nh4_sl[sl] = nh4_ae_sl[sl] + nh4_an_sl[sl];
350  sc_.don_sl[sl] = don_ae_sl[sl] + don_an_sl[sl];
351  sc_.no3_sl[sl] = no3_ae_sl[sl] + no3_an_sl[sl];
352  sc_.an_no3_sl[sl] = 0.0;
353  }
354 
355  return LDNDC_ERR_OK;
356 }
Here is the caller graph for this function:

◆ MeTrX_soil_organic_matter_turnover()

void ldndc::SoilChemistryMeTrX::MeTrX_soil_organic_matter_turnover ( )
private
Parameters
[in]None
[out]None
Returns
void

Referenced by solve().

Here is the caller graph for this function:

◆ MeTrX_spinup()

lerr_t ldndc::SoilChemistryMeTrX::MeTrX_spinup ( )
private
Parameters
[in]None
[out]None
Returns
void

Referenced by solve().

69 {
70  if ( spinup_.execute_spinup( lclock()))
71  {
72  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
73  {
74  accumulated_n_litter_spinup_sl[sl] -= sc_.n_wood_sl[sl];
75  }
76 
77  /* WOOD */
78  double c_wood( sc_.c_wood);
79  double n_wood( sc_.n_wood);
80  if ( cbm::flt_greater_zero( spinup_.exit_wood) &&
81  cbm::flt_equal_zero( (spinup_.executed_months_+1) % 12))
82  {
83  double const fraction( 0.5);
84  double const c_wood_temp( cbm::bound( 0.5, spinup_.enter_wood / spinup_.exit_wood, 1.5) * sc_.c_wood);
85  sc_.c_wood = c_wood_temp * fraction + c_wood * (1.0 - fraction);
86 
87  double const n_demand_wood( cbm::flt_greater_zero( n_wood) ?
88  sc_.c_wood / (c_wood / n_wood)
89  : 0.0);
90  sc_.n_wood = n_demand_wood;
91 
92  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
93  {
94  double c_wood_sl( sc_.c_wood_sl[sl]);
95  double n_wood_sl( sc_.n_wood_sl[sl]);
96 
97  double const c_wood_sl_temp( cbm::bound( 0.5, spinup_.enter_wood / spinup_.exit_wood, 1.5) * sc_.c_wood_sl[sl]);
98  sc_.c_wood_sl[sl] = c_wood_sl_temp * 0.5 + c_wood_sl * 0.5;
99 
100  double const n_demand_wood_sl( cbm::flt_greater_zero( n_wood_sl) ?
101  sc_.c_wood_sl[sl] / (c_wood_sl / n_wood_sl)
102  : 0.0);
103  sc_.n_wood_sl[sl] = n_demand_wood_sl;
104  }
105  }
106 
107  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
108  {
109  accumulated_n_litter_spinup_sl[sl] += sc_.n_wood_sl[sl];
110  }
111 
112  /* HUMUS */
113  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
114  {
115  int const steps( 10);
116  for ( int i = 0; i < steps; ++i)
117  {
118  //double c_sol( sc_.an_doc_sl[sl] + sc_.doc_sl[sl] + an_acetate_sl[sl] + ae_acetate_sl[sl]);
119  //double c_to_hum_1 = c_humus_1_sl[sl] / (c_humus_1_sl[sl] + c_humus_2_sl[sl] + c_humus_3_sl[sl]) * 0.9 * c_sol;
120  //double c_to_hum_2 = c_humus_2_sl[sl] / (c_humus_1_sl[sl] + c_humus_2_sl[sl] + c_humus_3_sl[sl]) * 0.9 * c_sol;
121  //double c_to_hum_3 = c_humus_3_sl[sl] / (c_humus_1_sl[sl] + c_humus_2_sl[sl] + c_humus_3_sl[sl]) * 0.9 * c_sol;
122  //sc_.an_doc_sl[sl] *= 0.1;
123  //sc_.doc_sl[sl] *= 0.1;
124  //an_acetate_sl[sl] *= 0.1;
125  //ae_acetate_sl[sl] *= 0.1;
126  double c_hum_1( c_humus_1_sl[sl]);
127  double n_hum_1( n_humus_1_sl[sl]);
128  double c_hum_2( c_humus_2_sl[sl]);
129  double n_hum_2( n_humus_2_sl[sl]);
130  double c_hum_3( c_humus_3_sl[sl]);
131  double n_hum_3( n_humus_3_sl[sl]);
132 
133  double const c_tot( c_hum_1 + c_hum_2 + c_hum_3);
134  double const n_tot( n_hum_1 + n_hum_2 + n_hum_3);
135 
136  int spinup_steps_per_year( 12);
137  double const delta_c_hum_1( c_hum_1 / (c_hum_1 + c_hum_2) * spinup_.decompose_hum_1[sl] / spinup_.decompose_hum_1.sum()
138  * spinup_delta_c / spinup_steps_per_year);
139  double const delta_c_hum_2( c_hum_2 / (c_hum_1 + c_hum_2) * spinup_.decompose_hum_2[sl] / spinup_.decompose_hum_2.sum()
140  * spinup_delta_c / spinup_steps_per_year);
141 
142  double const c_humus_1_tmp( cbm::bound_min( -1.0e-9, spinup_.humify_c_to_humus_1_sl[sl] - delta_c_hum_1)
143  / (spinup_.decompose_hum_1[sl] + spinup_.humify_humus_1_to_humus_2_sl[sl]));
144 
145  double const c_humus_2_tmp( cbm::bound_min( -1.0e-9, spinup_.humify_c_to_humus_2_sl[sl]
146  + spinup_.humify_humus_1_to_humus_2_sl[sl] * c_humus_1_sl[sl]
147  - delta_c_hum_2)
148  / (spinup_.decompose_hum_2[sl] + spinup_.humify_humus_2_to_humus_3_sl[sl]));
149 
150  //change less with time
151  double const fraction( 1.0 / steps);
152 
153  //use upper limit for humus pool 1
154  c_humus_1_sl[sl] = cbm::bound_max( c_humus_1_tmp * fraction + c_hum_1 * (1.0 - fraction), 0.2 * c_tot);
155  c_humus_2_sl[sl] = cbm::bound_max( c_humus_2_tmp * fraction + c_hum_2 * (1.0 - fraction), 0.95 * (c_tot - c_humus_1_sl[sl]));
156  c_humus_3_sl[sl] = c_tot - c_humus_1_sl[sl] -c_humus_2_sl[sl];
157 
158  double const n_demand_humus_1( c_humus_1_sl[sl] / cn_hum_1_sl[sl]);
159  double const n_demand_humus_2( c_humus_2_sl[sl] / cn_hum_2_sl[sl]);
160  double const n_demand_humus_3( c_humus_3_sl[sl] / cn_hum_3_sl[sl]);
161  double const n_demand_tot( n_demand_humus_1 + n_demand_humus_2 + n_demand_humus_3);
162 
163  accumulated_n_humus_1_spinup_sl[sl] -= n_humus_1_sl[sl];
164  accumulated_n_humus_2_spinup_sl[sl] -= n_humus_2_sl[sl];
165  accumulated_n_humus_3_spinup_sl[sl] -= n_humus_3_sl[sl];
166 
167  n_humus_1_sl[sl] = n_demand_humus_1 / n_demand_tot * n_tot;
168  n_humus_2_sl[sl] = n_demand_humus_2 / n_demand_tot * n_tot;
169  n_humus_3_sl[sl] = n_demand_humus_3 / n_demand_tot * n_tot;
170 
171  accumulated_n_humus_1_spinup_sl[sl] += n_humus_1_sl[sl];
172  accumulated_n_humus_2_spinup_sl[sl] += n_humus_2_sl[sl];
173  accumulated_n_humus_3_spinup_sl[sl] += n_humus_3_sl[sl];
174 
175  //adapt only target cn of recalcitrant pools
176  cn_hum_2_sl[sl] = c_humus_2_sl[sl] / n_humus_2_sl[sl];
177  cn_hum_3_sl[sl] = c_humus_3_sl[sl] / n_humus_3_sl[sl];
178  }
179 
180  spinup_.cn_humus_2_temp_sl[sl] += cn_hum_2_sl[sl];
181  spinup_.cn_humus_3_temp_sl[sl] += cn_hum_3_sl[sl];
182 
183  spinup_.c_humus_1_temp_sl[sl] += c_humus_1_sl[sl];
184  spinup_.c_humus_2_temp_sl[sl] += c_humus_2_sl[sl];
185  spinup_.c_humus_3_temp_sl[sl] += c_humus_3_sl[sl];
186  }
187 
188  spinup_.executed_months_ += 1;
189 
190  if ( true)//spinup_.executed_months_ == spinup_.spinup_months())
191  {
192  double const c_hum_tot( c_humus_1_sl.sum() + c_humus_2_sl.sum() + c_humus_3_sl.sum());
193  double const c_hum_1_acc_tot( spinup_.c_humus_1_temp_sl.sum());
194  double const c_hum_2_acc_tot( spinup_.c_humus_2_temp_sl.sum());
195  double const c_hum_3_acc_tot( spinup_.c_humus_3_temp_sl.sum());
196  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
197  {
198  double const c_hum_acc_tot( c_hum_1_acc_tot + c_hum_2_acc_tot + c_hum_3_acc_tot);
199 
200  double const c_hum_1_tot( c_hum_1_acc_tot / c_hum_acc_tot * c_hum_tot);
201  double const c_hum_2_tot( c_hum_2_acc_tot / c_hum_acc_tot * c_hum_tot);
202  double const c_hum_3_tot( c_hum_3_acc_tot / c_hum_acc_tot * c_hum_tot);
203 
204  c_humus_1_sl[sl] = spinup_.c_humus_1_temp_sl[sl] / c_hum_1_acc_tot * c_hum_1_tot;
205  c_humus_2_sl[sl] = spinup_.c_humus_2_temp_sl[sl] / c_hum_2_acc_tot * c_hum_2_tot;
206  c_humus_3_sl[sl] = spinup_.c_humus_3_temp_sl[sl] / c_hum_3_acc_tot * c_hum_3_tot;
207  }
208 
209  double const c_difference( c_hum_tot - (c_humus_1_sl.sum() + c_humus_2_sl.sum() + c_humus_3_sl.sum()));
210  if ( cbm::flt_greater( c_difference, 1.0e-10))
211  {
212  KLOGERROR( name(),": C-leakage during spinup: ", c_difference*cbm::M2_IN_HA, "[kg C ha-1]");
213  }
214 
215  double const n_old_total( n_humus_1_sl.sum() + n_humus_2_sl.sum() + n_humus_3_sl.sum());
216  double n_new_total( 0.0);
217  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
218  {
219  cn_hum_2_sl[sl] = spinup_.cn_humus_2_temp_sl[sl] / spinup_.executed_months_;
220  cn_hum_3_sl[sl] = spinup_.cn_humus_3_temp_sl[sl] / spinup_.executed_months_;
221 
222  n_new_total += c_humus_1_sl[sl] / cn_hum_1_sl[sl];
223  n_new_total += c_humus_2_sl[sl] / cn_hum_2_sl[sl];
224  n_new_total += c_humus_3_sl[sl] / cn_hum_3_sl[sl];
225  }
226 
227  double const scale( n_old_total / n_new_total);
228  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
229  {
230  accumulated_n_humus_1_spinup_sl[sl] -= n_humus_1_sl[sl];
231  accumulated_n_humus_2_spinup_sl[sl] -= n_humus_2_sl[sl];
232  accumulated_n_humus_3_spinup_sl[sl] -= n_humus_3_sl[sl];
233 
234  n_humus_1_sl[sl] = c_humus_1_sl[sl] / cn_hum_1_sl[sl] * scale;
235  n_humus_2_sl[sl] = c_humus_2_sl[sl] / cn_hum_2_sl[sl] * scale;
236  n_humus_3_sl[sl] = c_humus_3_sl[sl] / cn_hum_3_sl[sl] * scale;
237 
238  accumulated_n_humus_1_spinup_sl[sl] += n_humus_1_sl[sl];
239  accumulated_n_humus_2_spinup_sl[sl] += n_humus_2_sl[sl];
240  accumulated_n_humus_3_spinup_sl[sl] += n_humus_3_sl[sl];
241  }
242 
243  double const n_difference( n_old_total - (n_humus_1_sl.sum() + n_humus_2_sl.sum() + n_humus_3_sl.sum()));
244  if ( cbm::flt_greater( c_difference, 1.0e-10))
245  {
246  KLOGERROR( name(),": N-leakage during spinup: ", n_difference*cbm::M2_IN_HA, "[kg N ha-1]");
247  }
248 
249  if (spinup_.executed_months_ == spinup_.spinup_months())
250  {
251  spinup_.stop_spinup();
252  }
253  }
254 
255  spinup_.reset();
256  }
257 
258  return LDNDC_ERR_OK;
259 }
Here is the caller graph for this function:

◆ MeTrX_till()

lerr_t ldndc::SoilChemistryMeTrX::MeTrX_till ( )
private
Parameters
[in]None
[out]None
Returns
error code

Referenced by solve().

703 {
704  if ( cbm::flt_greater( sc_.till_effect_sl[0], 1.01))
705  {
706  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
707  {
708  sc_.till_effect_sl[sl] = cbm::bound_min( 1.0, sc_.till_effect_sl[sl] * (1.0 - (sipar_.METRX_TILL_STIMULATION_2() / this->lclock()->time_resolution())));
709  }
710  }
711  else if ( cbm::flt_greater( sc_.till_effect_sl[0], 1.0))
712  {
713  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
714  {
715  sc_.till_effect_sl[sl] = 1.0;
716  }
717  }
718 
719  EventAttributes const * ev_till = NULL;
720  while (( ev_till = this->m_TillEvents.pop()) != NULL)
721  {
722  /***************************/
723  /* tilling depth and layer */
724  /***************************/
725 
726  double till_depth( ev_till->get( "/depth", 0.0));
727  if ( till_depth > 0.5)
728  {
729  KLOGINFO( "tilling depth greater than 0.5m, reset to 0.5m [depth=",till_depth, "m,time=",lclock_ref().to_string(),"]");
730  till_depth = 0.5;
731  }
732 
733  unsigned int till_layer( SL_SURFACE_DISTRIBUTION);
734  if ( cbm::flt_greater_zero( till_depth))
735  {
736  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
737  {
738  if ( sc_.depth_sl[sl] <= till_depth)
739  {
740  sc_.till_effect_sl[sl] = sipar_.METRX_TILL_STIMULATION_1();
741  till_layer = std::max( SL_SURFACE_DISTRIBUTION, sl);
742  }
743  else { break; }
744  }
745  }
746 
747  /**************************************************/
748  /* stubble, root and surface litter incorporation */
749  /**************************************************/
750 
751  bool todo( true);
752  if ( todo)
753  {
754  sc_.C_lit1_sl[0] += sc_.c_stubble_lit1 + sc_.c_raw_lit_1_sl.sum();
755  sc_.C_lit2_sl[0] += sc_.c_stubble_lit2 + sc_.c_raw_lit_2_sl.sum();
756  sc_.C_lit3_sl[0] += sc_.c_stubble_lit3 + sc_.c_raw_lit_3_sl.sum();
757 
758  sc_.N_lit1_sl[0] += sc_.n_stubble_lit1 + sc_.n_raw_lit_1_sl.sum();
759  sc_.N_lit2_sl[0] += sc_.n_stubble_lit2 + sc_.n_raw_lit_2_sl.sum();
760  sc_.N_lit3_sl[0] += sc_.n_stubble_lit3 + sc_.n_raw_lit_3_sl.sum();
761  }
762  else
763  {
764  sc_.c_raw_lit_1_sl[0] += sc_.c_stubble_lit1;
765  sc_.c_raw_lit_2_sl[0] += sc_.c_stubble_lit2;
766  sc_.c_raw_lit_3_sl[0] += sc_.c_stubble_lit3;
767 
768  sc_.n_raw_lit_1_sl[0] += sc_.n_stubble_lit1;
769  sc_.n_raw_lit_2_sl[0] += sc_.n_stubble_lit2;
770  sc_.n_raw_lit_3_sl[0] += sc_.n_stubble_lit3;
771  }
772 
773  accumulated_n_surface_litter_incorporation_via_tilling_sl[0] += sc_.n_stubble_lit1 + sc_.n_stubble_lit2 + sc_.n_stubble_lit3 ;
774  accumulated_n_litter_tilling_sl[0] += sc_.n_raw_lit_1_sl.sum() + sc_.n_raw_lit_2_sl.sum() + sc_.n_raw_lit_3_sl.sum();
775 
776  sc_.c_stubble_lit1 = sc_.c_stubble_lit2 = sc_.c_stubble_lit3 = 0.0;
777  sc_.n_stubble_lit1 = sc_.n_stubble_lit2 = sc_.n_stubble_lit3 = 0.0;
778 
779  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
780  {
781  accumulated_n_litter_tilling_sl[sl] -= sc_.N_lit1_sl[sl] + sc_.N_lit2_sl[sl] + sc_.N_lit3_sl[sl] + sc_.n_raw_lit_1_sl[sl] + sc_.n_raw_lit_2_sl[sl] + sc_.n_raw_lit_3_sl[sl];
782  accumulated_n_aorg_tilling_sl[sl] -= sc_.N_aorg_sl[sl];
783  accumulated_n_humus_1_tilling_sl[sl] -= n_humus_1_sl[sl];
784  accumulated_n_humus_2_tilling_sl[sl] -= n_humus_2_sl[sl];
785  accumulated_n_humus_3_tilling_sl[sl] -= n_humus_3_sl[sl];
786  accumulated_n_no3_tilling_sl[sl] -= no3_ae_sl[sl] + no3_an_sl[sl];
787  accumulated_n_no2_tilling_sl[sl] -= sc_.no2_sl[sl] + sc_.an_no2_sl[sl];
788  accumulated_n_no_tilling_sl[sl] -= no_gas_sl[sl] + no_liq_sl[sl] + an_no_gas_sl[sl] + an_no_liq_sl[sl];
789  accumulated_n_n2o_tilling_sl[sl] -= n2o_gas_sl[sl] + n2o_liq_sl[sl] + an_n2o_gas_sl[sl] + an_n2o_liq_sl[sl];
790  accumulated_n_urea_tilling_sl[sl] -= sc_.urea_sl[sl];
791  accumulated_n_don_tilling_sl[sl] -= don_ae_sl[sl] + don_an_sl[sl];
792  accumulated_n_nh4_tilling_sl[sl] -= nh4_ae_sl[sl] + nh4_an_sl[sl] + sc_.clay_nh4_sl[sl];
793  accumulated_n_nh3_tilling_sl[sl] -= sc_.nh3_gas_sl[sl] + sc_.nh3_liq_sl[sl];
794  accumulated_n_microbes_tilling_sl[sl] -= n_micro_1_sl[sl] + n_micro_2_sl[sl] + n_micro_3_sl[sl];
795  }
796 
797  if ( todo)
798  {
799  sc_.c_raw_lit_1_sl = sc_.c_raw_lit_2_sl = sc_.c_raw_lit_3_sl = 0.0;
800  sc_.n_raw_lit_1_sl = sc_.n_raw_lit_2_sl = sc_.n_raw_lit_3_sl = 0.0;
801  }
802 
803  /****************************************/
804  /* rearranging soil pools after tilling */
805  /****************************************/
806 
807  lvector_t< double > pool_buf[] =
808  {
809  sc_.fe2_sl, sc_.fe3_sl,
810  sc_.c_raw_lit_1_sl, sc_.c_raw_lit_2_sl, sc_.c_raw_lit_3_sl,
811  sc_.n_raw_lit_1_sl, sc_.n_raw_lit_2_sl, sc_.n_raw_lit_3_sl,
812  sc_.C_lit1_sl, sc_.C_lit2_sl, sc_.C_lit3_sl,
813  sc_.N_lit1_sl, sc_.N_lit2_sl, sc_.N_lit3_sl,
814  sc_.C_aorg_sl, sc_.N_aorg_sl,
815  sc_.C_micro1_sl, sc_.C_micro2_sl, sc_.C_micro3_sl,
816  n_micro_1_sl, n_micro_2_sl, n_micro_3_sl,
817  c_humus_1_sl, c_humus_2_sl, c_humus_3_sl,
818  n_humus_1_sl, n_humus_2_sl, n_humus_3_sl,
819  sc_.doc_sl, sc_.an_doc_sl,
820  ae_acetate_sl, an_acetate_sl,
821  no3_ae_sl, no3_an_sl,
822  sc_.no2_sl, sc_.an_no2_sl,
823  don_ae_sl, don_an_sl,
824  nh4_ae_sl, nh4_an_sl, sc_.clay_nh4_sl,
825  sc_.urea_sl, sc_.nh3_gas_sl, sc_.nh3_liq_sl,
826  no_gas_sl, no_liq_sl, an_no_gas_sl, an_no_liq_sl,
827  n2o_gas_sl, n2o_liq_sl, an_n2o_gas_sl, an_n2o_liq_sl
828  };
829 
830  size_t const pools_cnt( sizeof( pool_buf) / sizeof(lvector_t< double >));
831  for ( size_t k = 0; k < pools_cnt; ++k)
832  {
833  // summing up pool down to tilling depth
834  double pool_sum( pool_buf[k].sum( till_layer) / sc_.depth_sl[till_layer-1]);
835  for ( size_t l = 0; l < till_layer; l++)
836  {
837  pool_buf[k][l] = pool_sum * sc_.h_sl[l];
838  }
839  }
840 
841  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
842  {
843  accumulated_n_litter_tilling_sl[sl] += sc_.N_lit1_sl[sl] + sc_.N_lit2_sl[sl] + sc_.N_lit3_sl[sl] + sc_.n_raw_lit_1_sl[sl] + sc_.n_raw_lit_2_sl[sl] + sc_.n_raw_lit_3_sl[sl];
844  accumulated_n_aorg_tilling_sl[sl] += sc_.N_aorg_sl[sl];
845  accumulated_n_humus_1_tilling_sl[sl] += n_humus_1_sl[sl];
846  accumulated_n_humus_2_tilling_sl[sl] += n_humus_2_sl[sl];
847  accumulated_n_humus_3_tilling_sl[sl] += n_humus_3_sl[sl];
848  accumulated_n_no3_tilling_sl[sl] += no3_ae_sl[sl] + no3_an_sl[sl];
849  accumulated_n_no2_tilling_sl[sl] += sc_.no2_sl[sl] + sc_.an_no2_sl[sl];
850  accumulated_n_no_tilling_sl[sl] += no_gas_sl[sl] + no_liq_sl[sl] + an_no_gas_sl[sl] + an_no_liq_sl[sl];
851  accumulated_n_n2o_tilling_sl[sl] += n2o_gas_sl[sl] + n2o_liq_sl[sl] + an_n2o_gas_sl[sl] + an_n2o_liq_sl[sl];
852  accumulated_n_urea_tilling_sl[sl] += sc_.urea_sl[sl];
853  accumulated_n_don_tilling_sl[sl] += don_ae_sl[sl] + don_an_sl[sl];
854  accumulated_n_nh4_tilling_sl[sl] += nh4_ae_sl[sl] + nh4_an_sl[sl] + sc_.clay_nh4_sl[sl];
855  accumulated_n_nh3_tilling_sl[sl] += sc_.nh3_gas_sl[sl] + sc_.nh3_liq_sl[sl];
856  accumulated_n_microbes_tilling_sl[sl] += n_micro_1_sl[sl] + n_micro_2_sl[sl] + n_micro_3_sl[sl];
857  }
858  }
859 
860  return LDNDC_ERR_OK;
861 }
Here is the caller graph for this function:

◆ MeTrX_update()

lerr_t ldndc::SoilChemistryMeTrX::MeTrX_update ( )
private
Parameters
[in]None
[out]None
Returns
error code

References MeTrX_receive_state(), MeTrX_update_soil_discretization(), ldndc::update_litter_height(), and ldndc::wood_initialization().

Referenced by solve().

64 {
65  lerr_t rc = MeTrX_receive_state();
66  if ( rc)
67  {
68  return LDNDC_ERR_FAIL;
69  }
70 
71  /* vertical discretization */
72  if ( !have_no_litter_height_change)
73  {
74  lerr_t rc_litter = update_litter_height( sl_, wc_, sc_);
75  if ( rc_litter){ return LDNDC_ERR_FAIL; }
76 
77  //lerr_t rc_soil = update_soil_height( sl_, wc_, sc_);
78  //if ( rc_soil){ return LDNDC_ERR_FAIL; }
79 
81  }
82 
83  /* module specific variables from global state */
84  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
85  {
86  /* use liq/gas distribution from previous time step */
87  UPDATE_STATE( no_liq_sl[sl], no_gas_sl[sl], sc_.no_sl[sl]);
88  UPDATE_STATE( an_no_liq_sl[sl], an_no_gas_sl[sl], sc_.an_no_sl[sl]);
89  UPDATE_STATE( n2o_liq_sl[sl], n2o_gas_sl[sl], sc_.n2o_sl[sl]);
90  UPDATE_STATE( an_n2o_liq_sl[sl], an_n2o_gas_sl[sl], sc_.an_n2o_sl[sl]);
91 
92  CHECK_FOR_ZERO( sc_.C_lit1_sl[sl]);
93  CHECK_FOR_ZERO( sc_.C_lit2_sl[sl]);
94  CHECK_FOR_ZERO( sc_.C_lit3_sl[sl]);
95  CHECK_FOR_ZERO( sc_.N_lit1_sl[sl]);
96  CHECK_FOR_ZERO( sc_.N_lit2_sl[sl]);
97  CHECK_FOR_ZERO( sc_.N_lit3_sl[sl]);
98  }
99 
100  /* water table */
101  if ( cbm::flt_greater( wc_.surface_water, 0.01) &&
102  (sb_.surfacebulk_layer_cnt() > 0))
103  {
104  have_water_table = true;
105 
106  // for simplicity of calculations changing watertable
107  // alters heigth of single waterlayer and not number of layers
108  h_wl = (wc_.surface_water / (double)sb_.surfacebulk_layer_cnt());
109  }
110  else if ( !cbm::flt_greater( wc_.surface_ice, 0.0))
111  {
112  have_water_table = false;
113  h_wl = 0.0;
114 
115  double const clear_ch4( sb_.ch4_sbl.sum());
116  sb_.ch4_sbl = 0.0;
117  double const clear_o2( sb_.o2_sbl.sum());
118  sb_.o2_sbl = 0.0;
119  double const clear_nh4( sb_.nh4_sbl.sum());
120  sb_.nh4_sbl = 0.0;
121  double const clear_nh3( sb_.nh3_sbl.sum());
122  sb_.nh3_sbl = 0.0;
123  double const clear_urea( sb_.urea_sbl.sum());
124  sb_.urea_sbl = 0.0;
125  double const clear_no3( sb_.no3_sbl.sum());
126  sb_.no3_sbl = 0.0;
127  double const clear_don( sb_.don_sbl.sum());
128  sb_.don_sbl = 0.0;
129  double const clear_doc( sb_.doc_sbl.sum());
130  sb_.doc_sbl = 0.0;
131  double const clear_co2( sb_.co2_sbl.sum());
132  sb_.co2_sbl = 0.0;
133  double const clear_so4( sb_.so4_sbl.sum());
134  sb_.so4_sbl = 0.0;
135 
136  for( size_t sl = 0; sl <= SL_SURFACE_DISTRIBUTION; ++sl)
137  {
138  ch4_liq_sl[sl] += clear_ch4 * SL_SURFACE_DISTRIBUTION_INVERSE;
139  o2_liq_sl[sl] += clear_o2 * SL_SURFACE_DISTRIBUTION_INVERSE;
140  nh4_ae_sl[sl] += clear_nh4 * SL_SURFACE_DISTRIBUTION_INVERSE;
141  sc_.nh3_liq_sl[sl] += clear_nh3 * SL_SURFACE_DISTRIBUTION_INVERSE;
142  sc_.urea_sl[sl] += clear_urea * SL_SURFACE_DISTRIBUTION_INVERSE;
143  no3_ae_sl[sl] += clear_no3 * SL_SURFACE_DISTRIBUTION_INVERSE;
144  don_ae_sl[sl] += clear_don * SL_SURFACE_DISTRIBUTION_INVERSE;
145  sc_.doc_sl[sl] += clear_doc * SL_SURFACE_DISTRIBUTION_INVERSE;
146  co2_liq_sl[sl] += clear_co2 * SL_SURFACE_DISTRIBUTION_INVERSE;
147  sc_.so4_sl[sl] += clear_so4 * SL_SURFACE_DISTRIBUTION_INVERSE;
148 
149  accumulated_n_nh4_infiltration_phys_sl[sl] += clear_nh4 * SL_SURFACE_DISTRIBUTION_INVERSE;
150  accumulated_n_nh3_infiltration_phys_sl[sl] += clear_nh3 * SL_SURFACE_DISTRIBUTION_INVERSE;
151  accumulated_n_urea_infiltration_phys_sl[sl] += clear_urea * SL_SURFACE_DISTRIBUTION_INVERSE;
152  accumulated_n_no3_infiltration_phys_sl[sl] += clear_no3 * SL_SURFACE_DISTRIBUTION_INVERSE;
153  accumulated_n_don_infiltration_phys_sl[sl] += clear_don * SL_SURFACE_DISTRIBUTION_INVERSE;
154  }
155  }
156 
157  /* water fluxes */
158  infiltration = wc_.accumulated_infiltration - accumulated_infiltration_old;
159  accumulated_infiltration_old = wc_.accumulated_infiltration;
160  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
161  {
162  waterflux_sl[sl] = wc_.accumulated_waterflux_sl[sl] - accumulated_waterflux_old_sl[sl];
163  accumulated_waterflux_old_sl[sl] = wc_.accumulated_waterflux_sl[sl];
164  }
165 
166  /* nitrogen deposition */
167  if ( cbm::flt_greater_zero( wc_.surface_water) || cbm::flt_greater_zero( wc_.surface_ice))
168  {
169  accumulated_n_nh4_throughfall_sbl[0] += ph_.accumulated_nh4_throughfall - accumulated_n_nh4_throughfall_old;
170  accumulated_n_no3_throughfall_sbl[0] += ph_.accumulated_no3_throughfall - accumulated_n_no3_throughfall_old;
171  }
172  else
173  {
174  accumulated_n_nh4_throughfall_sl[0] += ph_.accumulated_nh4_throughfall - accumulated_n_nh4_throughfall_old;
175  accumulated_n_no3_throughfall_sl[0] += ph_.accumulated_no3_throughfall - accumulated_n_no3_throughfall_old;
176  }
177  accumulated_n_nh4_throughfall_old = ph_.accumulated_nh4_throughfall;
178  accumulated_n_no3_throughfall_old = ph_.accumulated_no3_throughfall;
179 
180  /* carbon/nitrogen flux planting */
181  EventAttributes const * ev_plant = NULL;
182  while (( ev_plant = this->m_PlantEvents.pop()) != NULL)
183  {
184  MoBiLE_Plant *p = m_veg->get_plant( ev_plant->get( "/name", "?"));
185  if ( p)
186  {
187  accumulated_n_to_living_plant_and_algae_from_extern_sl[0] += p->total_nitrogen();
188 
189  if ( spinup_.spinup_stage( this->lclock()))
190  {
191  site::input_class_site_t const *s_site( io_kcomm->get_input_class< site::input_class_site_t >());
192  ldndc::wood_initialization(sl_, p, sc_, s_site->soil_use_history());
193  }
194  }
195  }
196 
197  /* carbon/nitrogen flux harvest/cutting */
198  accumulated_n_export_harvest_cutting_grazing += ph_.accumulated_n_export_harvest - accumulated_n_export_harvest_old;
199  accumulated_n_export_harvest_old = ph_.accumulated_n_export_harvest;
200 
201  /* carbon/nitrogen flux litterfall */
202  if ( spinup_.spinup_stage( this->lclock()))
203  {
204  double const delta_c_wood( sc_.accumulated_c_litter_wood_above - accumulated_c_litter_wood_above_old);
205  if ( cbm::flt_greater_zero( delta_c_wood))
206  {
207  spinup_.enter_wood += delta_c_wood;
208  }
209  }
210  accumulated_c_litter_wood_above_old = sc_.accumulated_c_litter_wood_above;
211  accumulated_n_litter_from_plants_above_wood = sc_.accumulated_n_litter_wood_above;
212  accumulated_n_litter_from_plants_above_rawlitter = sc_.accumulated_n_litter_above;
213  accumulated_n_litter_from_plants_above_stubble = sc_.accumulated_n_litter_stubble;
214  for ( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
215  {
216  accumulated_n_litter_from_plants_below_rawlitter_sl[sl] = sc_.accumulated_n_litter_below_sl[sl];
217  accumulated_n_litter_from_plants_below_wood_sl[sl] = sc_.accumulated_n_litter_wood_below_sl[sl];
218  }
219 
220  /* carbon/nitrogen flux root exsudation */
221  double const delta_c_exsudation( sc_.accumulated_c_root_exsudates_sl.sum() -
222  accumulated_c_root_exsudates_old_sl.sum());
223  if ( cbm::flt_greater_zero( delta_c_exsudation))
224  {
225  dC_root_exsudates += delta_c_exsudation;
226  subdaily_doc_prod[subdaily_time_step_] += delta_c_exsudation;
227  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
228  {
229  double const delta_c_exsudation_sl( sc_.accumulated_c_root_exsudates_sl[sl] - accumulated_c_root_exsudates_old_sl[sl]);
230  day_doc_prod_sl[sl] += delta_c_exsudation_sl;
231  accumulated_c_root_exsudates_old_sl[sl] = sc_.accumulated_c_root_exsudates_sl[sl];
232  }
233  }
234 
235  /* litter layer characterization */
236  double bio_coniferous( 0.0);
237  double bio_deciduous( 0.0);
238  for ( PlantIterator vt = this->m_veg->begin(); vt != this->m_veg->end(); ++vt)
239  {
240  MoBiLE_Plant *p( *vt);
241  if ( (*p)->DECIDUOUS())
242  {
243  bio_deciduous += p->aboveground_biomass();
244  }
245  else
246  {
247  bio_coniferous += p->aboveground_biomass();
248  }
249  }
250  double const bio_tot( bio_deciduous + bio_coniferous);
251  if ( cbm::flt_greater_zero( bio_tot))
252  {
253  double const frac_deciduous( bio_deciduous / bio_tot);
254  double const frac_coniferous( 1.0 - frac_deciduous);
255  for (size_t sl = 0; sl <= SL_SURFACE_DISTRIBUTION; ++sl)
256  {
257  litter_type_fact_sl[sl] = (frac_deciduous + sipar_.METRX_KR_REDUCTION_CONIFEROUS() * frac_coniferous);
258  }
259  }
260 
261  return LDNDC_ERR_OK;
262 }
lerr_t update_litter_height(soillayers::input_class_soillayers_t const &, substate_watercycle_t &, substate_soilchemistry_t &)
Detailed description provided here .
Definition: ld_litterheight.cpp:26
lerr_t MeTrX_update_soil_discretization()
Definition: soilchemistry-metrx-reset.cpp:19
lerr_t wood_initialization(soillayers::input_class_soillayers_t const &, MoBiLE_Plant *, substate_soilchemistry_t &, ecosystem_type_e)
Initialization of aboveground and belowground wood debris, derived from existing vegetation.
Definition: ld_wood_initialization.cpp:18
lerr_t MeTrX_receive_state()
Definition: soilchemistry-metrx-communicate.cpp:270
Here is the call graph for this function:
Here is the caller graph for this function:

◆ MeTrX_update_soil_discretization()

lerr_t ldndc::SoilChemistryMeTrX::MeTrX_update_soil_discretization ( )
private
Parameters
[in]None
[out]None
Returns
error code

Referenced by MeTrX_update().

20 {
21  for( size_t sl = 0; sl < sl_.soil_layer_cnt()-1; ++sl)
22  {
23  delta_x[sl] = cbm::arithmetic_mean2( sc_.h_sl[sl], sc_.h_sl[sl+1]);
24  }
25  delta_x[sl_.soil_layer_cnt()-1] = sc_.h_sl[sl_.soil_layer_cnt()-1];
26 
27  return LDNDC_ERR_OK;
28 }
Here is the caller graph for this function:

◆ MeTrX_urea_hydrolysis()

void ldndc::SoilChemistryMeTrX::MeTrX_urea_hydrolysis ( )
private
Parameters
[in]None
[out]None
Returns
void

Referenced by solve().

880 {
881  if ( have_water_table)
882  {
883  double urea_hydrolysis_sum( 0.0);
884  for ( size_t wl = 0; wl < sb_.surfacebulk_layer_cnt(); ++wl)
885  {
886  if ( cbm::flt_greater_zero( sb_.urea_sbl[wl]))
887  {
888  crnf_.update_urease_inhibition( mc_temp_sl[0] * FTS_TOT_, sb_.ui_sbl.sum(), sb_.ui_sbl[wl]);
889  double const fact_t( std::exp( -sipar_.METRX_F_DECOMP_T_EXP_1() * pow(1.0 - mc_temp_sl[0] / sipar_.METRX_F_DECOMP_T_EXP_2(), 2.0)));
890  double const urease_inhibition( crnf_.get_urease_inhibition( sb_.ui_sbl[wl]));
891  double const k_mm( cbm::flt_greater_zero( urease_inhibition) ?
892  (sipar_.METRX_KMM_UREA_HYDROLYSIS() +
893  urease_inhibition * sipar_.METRX_KMM_UREA_HYDROLYSIS_INHIBITION()) * h_wl :
894  sipar_.METRX_KMM_UREA_HYDROLYSIS() * h_wl);
895  double const fact_urea( sb_.urea_sbl[wl] / (sb_.urea_sbl[wl] + k_mm));
896  double const urea_hydrolysis( cbm::bound_max( sipar_.METRX_KR_UREA_HYDROLYSIS() * fact_urea * fact_t * sb_.urea_sbl[wl] * FTS_TOT_,
897  0.99 * sb_.urea_sbl[wl]));
898 
899  sb_.urea_sbl[wl] -= urea_hydrolysis;
900  sb_.nh4_sbl[wl] += urea_hydrolysis;
901  accumulated_n_urea_nh4_hydrolysis_sbl[0] += urea_hydrolysis;
902  urea_hydrolysis_sum += urea_hydrolysis;
903  }
904  else
905  {
906  sb_.urea_sbl[wl] = 0.0;
907  }
908  }
909  ph_delta_urea_wl = cbm::bound( 0.0, urea_hydrolysis_sum / (sipar_.METRX_KMM_PH_INCREASE_FROM_UREA() * wc_.surface_water), PH_MAX-PH_SURFACE_WATER);
910  }
911 
912  for ( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
913  {
914  if ( cbm::flt_greater_zero( sc_.urea_sl[sl]))
915  {
916  crnf_.update_urease_inhibition( mc_temp_sl[sl] * FTS_TOT_, sc_.ui_sl.sum(), sc_.ui_sl[sl]);
917  double const fact_t( std::exp( -sipar_.METRX_F_DECOMP_T_EXP_1() * pow(1.0 - mc_temp_sl[sl] / sipar_.METRX_F_DECOMP_T_EXP_2(), 2.0)));
918  double const urease_inhibition( crnf_.get_urease_inhibition( sc_.ui_sl[sl]));
919  double const k_mm( cbm::flt_greater_zero( urease_inhibition) ?
920  (sipar_.METRX_KMM_UREA_HYDROLYSIS() +
921  urease_inhibition * sipar_.METRX_KMM_UREA_HYDROLYSIS_INHIBITION()) * sc_.h_sl[sl] :
922  sipar_.METRX_KMM_UREA_HYDROLYSIS() * sc_.h_sl[sl]);
923  double const fact_urea( sc_.urea_sl[sl] / (sc_.urea_sl[sl] + k_mm));
924  double const urea_hydrolysis( cbm::bound_max( sipar_.METRX_KR_UREA_HYDROLYSIS() * fact_urea * fact_t * sc_.urea_sl[sl] * FTS_TOT_, 0.99 * sc_.urea_sl[sl]));
925 
926  sc_.urea_sl[sl] -= urea_hydrolysis;
927  nh4_ae_sl[sl] += urea_hydrolysis * (1.0 - sc_.anvf_sl[sl]);
928  nh4_an_sl[sl] += urea_hydrolysis * sc_.anvf_sl[sl];
929  accumulated_n_urea_nh4_hydrolysis_sl[sl] += urea_hydrolysis;
930  ph_delta_urea_sl[sl] = cbm::bound( 0.0, urea_hydrolysis / (sipar_.METRX_KMM_PH_INCREASE_FROM_UREA() * sc_.h_sl[sl]), PH_MAX-sc_.phi_sl[sl]);
931  }
932  else
933  {
934  sc_.urea_sl[sl] = 0.0;
935  ph_delta_urea_sl[sl] = 0.0;
936  }
937  }
938 }
Here is the caller graph for this function:

◆ MeTrX_write_output()

lerr_t ldndc::SoilChemistryMeTrX::MeTrX_write_output ( )
private
Parameters
[in]None
[out]None
Returns
error code

References MeTrX_write_output_daily(), MeTrX_write_output_fluxes(), MeTrX_write_output_layer_daily(), MeTrX_write_output_layer_yearly(), MeTrX_write_output_pools(), MeTrX_write_output_subdaily(), and MeTrX_write_output_yearly().

Referenced by solve().

17 {
18  if ( !output_data_ || !this->output_writer_.active())
19  {
20  return LDNDC_ERR_OK;
21  }
22 
23  if ( output_writer_.write_subdaily())
24  {
25  lerr_t rc_out = MeTrX_write_output_subdaily();
26  if ( rc_out){ return LDNDC_ERR_FAIL; }
27  }
28 
29  if ( output_writer_.write_fluxes())
30  {
31  lerr_t rc_out = MeTrX_write_output_fluxes();
32  if ( rc_out){ return LDNDC_ERR_FAIL; }
33  }
34 
35  if ( lclock()->is_position( TMODE_POST_DAILY))
36  {
37  if ( output_writer_.write_pools())
38  {
39  lerr_t rc_out = MeTrX_write_output_pools();
40  if ( rc_out){ return LDNDC_ERR_FAIL; }
41  }
42 
43  if ( output_writer_.write_daily())
44  {
45  lerr_t rc_out = MeTrX_write_output_daily();
46  if ( rc_out){ return LDNDC_ERR_FAIL; }
47  }
48 
49  if ( output_writer_.write_layer_daily())
50  {
51  lerr_t rc_out = MeTrX_write_output_layer_daily();
52  if ( rc_out){ return LDNDC_ERR_FAIL; }
53  }
54  }
55 
56  if ( lclock()->is_position( TMODE_POST_YEARLY))
57  {
58  if ( output_writer_.write_yearly())
59  {
60  lerr_t rc_out = MeTrX_write_output_yearly();
61  if ( rc_out){ return LDNDC_ERR_FAIL; }
62  }
63 
64  if ( output_writer_.write_layer_yearly())
65  {
66  lerr_t rc_out = MeTrX_write_output_layer_yearly();
67  if ( rc_out){ return LDNDC_ERR_FAIL; }
68  }
69  }
70 
71  return LDNDC_ERR_OK;
72 }
lerr_t MeTrX_write_output_layer_yearly()
Definition: soilchemistry-metrx-output.cpp:618
lerr_t MeTrX_write_output_subdaily()
Definition: soilchemistry-metrx-output.cpp:960
lerr_t MeTrX_write_output_pools()
Definition: soilchemistry-metrx-output.cpp:645
lerr_t MeTrX_write_output_daily()
Definition: soilchemistry-metrx-output.cpp:76
lerr_t MeTrX_write_output_fluxes()
Definition: soilchemistry-metrx-output.cpp:714
lerr_t MeTrX_write_output_layer_daily()
Definition: soilchemistry-metrx-output.cpp:445
lerr_t MeTrX_write_output_yearly()
Definition: soilchemistry-metrx-output.cpp:401
Here is the call graph for this function:
Here is the caller graph for this function:

◆ MeTrX_write_output_daily()

lerr_t ldndc::SoilChemistryMeTrX::MeTrX_write_output_daily ( )
private
Parameters
[in]None
[out]None
Returns
error code

References MeTrX_get_ph_wl().

Referenced by MeTrX_write_output().

77 {
78 #define METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT(__val__) LDNDC_OUTPUT_SET_COLUMN_((__val__),=,output_data_,1)
79  LDNDC_OUTPUT_SET_COLUMN_INDEX(0);
80 
81  double const clit1( sc_.C_lit1_sl.sum() + sc_.c_raw_lit_1_sl.sum());
82  double const clit2( sc_.C_lit2_sl.sum() + sc_.c_raw_lit_2_sl.sum());
83  double const clit3( sc_.C_lit3_sl.sum() + sc_.c_raw_lit_3_sl.sum());
84  double const nlit1( sc_.N_lit1_sl.sum() + sc_.n_raw_lit_1_sl.sum());
85  double const nlit2( sc_.N_lit2_sl.sum() + sc_.n_raw_lit_2_sl.sum());
86  double const nlit3( sc_.N_lit3_sl.sum() + sc_.n_raw_lit_3_sl.sum());
87 
88  double const cmic1( sc_.C_micro1_sl.sum());
89  double const cmic2( sc_.C_micro2_sl.sum());
90  double const cmic3( sc_.C_micro3_sl.sum());
91  double const nmic1( n_micro_1_sl.sum());
92  double const nmic2( n_micro_2_sl.sum());
93  double const nmic3( n_micro_3_sl.sum());
94 
95  double const cstub( sc_.c_stubble_lit1+sc_.c_stubble_lit2+sc_.c_stubble_lit3);
96  double const nstub( sc_.n_stubble_lit1+sc_.n_stubble_lit2+sc_.n_stubble_lit3);
97 
98  double const chum1( c_humus_1_sl.sum());
99  double const chum2( c_humus_2_sl.sum());
100  double const chum3( c_humus_3_sl.sum());
101  double const nhum1( n_humus_1_sl.sum());
102  double const nhum2( n_humus_2_sl.sum());
103  double const nhum3( n_humus_3_sl.sum());
104 
105  double const caorg( sc_.C_aorg_sl.sum());
106  double const naorg( sc_.N_aorg_sl.sum());
107 
108  double const cwood( sc_.c_wood_sl.sum()+sc_.c_wood);
109  double const nwood( sc_.n_wood_sl.sum()+sc_.n_wood);
110 
111  double const n_algae_tot( n_algae + n_dead_algae);
112  double const don_sum( don_ae_sl.sum()+don_an_sl.sum()+sb_.don_sbl.sum());
113  double const nh4_sum( nh4_ae_sl.sum()+nh4_an_sl.sum()+sb_.nh4_sbl.sum());
114  double const nh4_clay_sum( sc_.clay_nh4_sl.sum());
115  double const coated_nh4_sum( sc_.coated_nh4_sl.sum());
116  double const urea_sum( sc_.urea_sl.sum()+sb_.urea_sbl.sum());
117  double const no2_sum( sc_.no2_sl.sum());
118  double const an_no2_sum( sc_.an_no2_sl.sum());
119  double const no3_sum( no3_ae_sl.sum());
120  double const an_no3_sum( no3_an_sl.sum()+sb_.no3_sbl.sum());
121  double const n2o_sum( n2o_gas_sl.sum()+n2o_liq_sl.sum());
122  double const an_n2o_sum( an_n2o_gas_sl.sum()+an_n2o_liq_sl.sum());
123  double const no_sum( no_gas_sl.sum()+no_liq_sl.sum());
124  double const an_no_sum( an_no_gas_sl.sum()+an_no_liq_sl.sum());
125  double const nh3_gas_sum( sc_.nh3_gas_sl.sum());
126  double const nh3_liq_sum( sc_.nh3_liq_sl.sum()+sb_.nh3_sbl.sum());
127 
128  double const n_sbl( sb_.don_sbl.sum() + sb_.nh4_sbl.sum()
129  + sb_.urea_sbl.sum() + sb_.no3_sbl.sum() + sb_.nh3_sbl.sum());
130  double const nsol( nh4_sum + nh4_clay_sum + don_sum
131  + nh3_gas_sum + nh3_liq_sum + urea_sum
132  + no3_sum + an_no3_sum + no2_sum + an_no2_sum
133  + n2o_sum + an_n2o_sum + no_sum + an_no_sum);
134 
135  double const c_algae_tot( c_algae + c_dead_algae);
136  double const doc_sum( sc_.doc_sl.sum());
137  double const an_doc_sum( sc_.an_doc_sl.sum());
138  double const acetate_sum( ae_acetate_sl.sum() + an_acetate_sl.sum());
139  double const ch4_gas_sum( ch4_gas_sl.sum());
140  double const ch4_liq_sum( ch4_liq_sl.sum());
141 
142  double const csol( doc_sum + an_doc_sum + acetate_sum + ch4_gas_sum + ch4_liq_sum);
143 
144  double soc20( 0.0);
145  double soc40( 0.0);
146  double totn20( 0.0);
147  double totn40( 0.0);
148  double soilmass20( 0.0);
149  double soilmass40( 0.0);
150  double anvf_avg( 0.0);
151 #ifdef METRX_ANVF_TYPES
152  double anvf_avg_pnet( 0.0);
153  double anvf_avg_dndc_can( 0.0);
154  double anvf_avg_nloss( 0.0);
155 #endif
156  double pore_connect_avg( 0.0);
157  double d_eff_avg( 0.0);
158  double wfps_avg( 0.0);
159  double air_avg( 0.0);
160  double root_conduct_avg( 0.0);
161  double o2_sum( 0.0);
162  double depth_sum( 0.0);
163 
164  double nitrification_inhibition( 0.0);
165  double urease_inhibition( 0.0);
166 
167  double mineral_efficiency_scale_sum( 0.0);
168  double mineral_efficiency( 0.0);
169  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
170  {
171  double const c_mic_sum( sc_.C_micro1_sl[sl] + sc_.C_micro2_sl[sl] + sc_.C_micro3_sl[sl]);
172  double const n_mic_sum( n_micro_1_sl[sl] + n_micro_2_sl[sl] + n_micro_3_sl[sl]);
173  mineral_efficiency += MeTrX_get_mineral_efficiency( c_mic_sum / n_mic_sum, cn_opt_mic_sl[sl]) * c_mic_sum;
174  mineral_efficiency_scale_sum += c_mic_sum;
175 
176  anvf_avg += sc_.anvf_sl[sl] * sc_.h_sl[sl];
177 #ifdef METRX_ANVF_TYPES
178  anvf_avg_pnet += anvf_pnet_sl[sl] * sc_.h_sl[sl];
179  anvf_avg_dndc_can += anvf_dndccan_sl[sl] * sc_.h_sl[sl];
180  anvf_avg_nloss += anvf_nloss_sl[sl] * sc_.h_sl[sl];
181 #endif
182  pore_connect_avg += pore_connectivity_sl[sl] * sc_.h_sl[sl];
183  d_eff_avg += D_eff_air_sl[sl] * sc_.h_sl[sl];
184  wfps_avg += MeTrX_get_wfps( sl) * sc_.h_sl[sl];
185  air_avg += (v_air_sl[sl] / sc_.h_sl[sl]) * sc_.h_sl[sl];
186  root_conduct_avg += D_eff_plant_sl[sl] * sc_.h_sl[sl];
187  o2_sum += o2_gas_sl[sl] + o2_liq_sl[sl];
188  depth_sum += sc_.h_sl[sl];
189 
190  if ( cbm::flt_less_equal( sc_.depth_sl[sl], 0.2))
191  {
192  soc20 += (sc_.C_aorg_sl[sl] +c_humus_1_sl[sl]+c_humus_2_sl[sl]+c_humus_3_sl[sl]
193  +sc_.C_micro1_sl[sl]+sc_.C_micro2_sl[sl]+sc_.C_micro3_sl[sl]
194  +sc_.C_lit1_sl[sl]+sc_.C_lit2_sl[sl]+sc_.C_lit3_sl[sl]);
195  totn20 += (sc_.N_aorg_sl[sl] +n_humus_1_sl[sl]+n_humus_2_sl[sl]+n_humus_3_sl[sl]
196  +sc_.N_micro_sl[sl] +sc_.N_lit1_sl[sl]+sc_.N_lit2_sl[sl]+sc_.N_lit3_sl[sl]);
197  soilmass20 += (sc_.dens_sl[sl] * cbm::DM3_IN_M3 * sc_.h_sl[sl]);
198  }
199 
200  if ( cbm::flt_less_equal( sc_.depth_sl[sl], 0.4))
201  {
202  soc40 += (sc_.C_aorg_sl[sl] +c_humus_1_sl[sl]+c_humus_2_sl[sl]+c_humus_3_sl[sl]
203  +sc_.C_micro1_sl[sl]+sc_.C_micro2_sl[sl]+sc_.C_micro3_sl[sl]
204  +sc_.C_lit1_sl[sl]+sc_.C_lit2_sl[sl]+sc_.C_lit3_sl[sl]);
205  totn40 += (sc_.N_aorg_sl[sl] +n_humus_1_sl[sl]+n_humus_2_sl[sl]+n_humus_3_sl[sl]
206  +sc_.N_micro_sl[sl] +sc_.N_lit1_sl[sl]+sc_.N_lit2_sl[sl]+sc_.N_lit3_sl[sl]);
207  soilmass40 += (sc_.dens_sl[sl] * cbm::DM3_IN_M3 * sc_.h_sl[sl]);
208  }
209  }
210 
211  int ui_counter( 0);
212  int ni_counter( 0);
213  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
214  {
215  double const ui_inhibition( crnf_.get_urease_inhibition( sc_.ui_sl[sl]));
216  if ( cbm::flt_greater_zero( ui_inhibition))
217  {
218  ui_counter += 1;
219  urease_inhibition += ui_inhibition;
220  }
221  double const ni_inhibition( crnf_.get_nitrification_inhibition( sc_.ni_sl[sl]));
222  if ( cbm::flt_greater_zero( ni_inhibition))
223  {
224  ni_counter += 1;
225  nitrification_inhibition += ni_inhibition;
226  }
227  }
228 
229  if ( ui_counter > 0)
230  {
231  urease_inhibition /= ui_counter;
232  }
233  if ( ni_counter > 0)
234  {
235  nitrification_inhibition /= ni_counter;
236  }
237 
238  double const litter_height( (sl_.soil_layers_in_litter_cnt() > 0) ? sc_.depth_sl[sl_.soil_layers_in_litter_cnt()-1] : 0.0);
239  anvf_avg /= depth_sum;
240 #ifdef METRX_ANVF_TYPES
241  anvf_avg_pnet /= depth_sum;
242  anvf_avg_dndc_can /= depth_sum;
243  anvf_avg_nloss /= depth_sum;
244 #endif
245  pore_connect_avg /= depth_sum;
246  d_eff_avg /= depth_sum;
247  wfps_avg /= depth_sum;
248  air_avg /= depth_sum;
249  root_conduct_avg /= depth_sum;
250 
251  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( anvf_avg);
252 #ifdef METRX_ANVF_TYPES
253  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( anvf_avg_pnet);
254  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( anvf_avg_dndc_can);
255  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( anvf_avg_nloss);
256 #endif
257  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( pore_connect_avg);
258  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( d_eff_avg);
259  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( wfps_avg);
260  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( air_avg);
261  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( root_conduct_avg);
262  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( o2_sum * cbm::M2_IN_HA);
263  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( crnf_.get_crnf_teff_mean());
264  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( crnf_.get_crnf_release_fraction_mean());
265  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nitrification_inhibition);
266  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( urease_inhibition);
267  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( mineral_efficiency / (mineral_efficiency_scale_sum * sl_.soil_layer_cnt()));
268  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( don_sum * cbm::M2_IN_HA);
269  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nh4_sum * cbm::M2_IN_HA);
270  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nh4_clay_sum * cbm::M2_IN_HA);
271  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( coated_nh4_sum * cbm::M2_IN_HA);
272  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( urea_sum * cbm::M2_IN_HA);
273  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( no2_sum * cbm::M2_IN_HA);
274  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( an_no2_sum * cbm::M2_IN_HA);
275  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( no3_sum * cbm::M2_IN_HA);
276  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( an_no3_sum * cbm::M2_IN_HA);
277  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( n2o_sum * cbm::M2_IN_HA);
278  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( an_n2o_sum * cbm::M2_IN_HA);
279  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( no_sum * cbm::M2_IN_HA);
280  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( an_no_sum * cbm::M2_IN_HA);
281  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nh3_gas_sum * cbm::M2_IN_HA);
282  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nh3_liq_sum * cbm::M2_IN_HA);
283  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( doc_sum * cbm::M2_IN_HA);
284  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( an_doc_sum * cbm::M2_IN_HA);
285  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( acetate_sum * cbm::M2_IN_HA);
286  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( ch4_gas_sum * cbm::M2_IN_HA);
287  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( ch4_liq_sum * cbm::M2_IN_HA);
288  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( caorg * cbm::M2_IN_HA);
289  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( naorg * cbm::M2_IN_HA);
290  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( cmic1 * cbm::M2_IN_HA);
291  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( cmic2 * cbm::M2_IN_HA);
292  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( cmic3 * cbm::M2_IN_HA);
293  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nmic1 * cbm::M2_IN_HA);
294  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nmic2 * cbm::M2_IN_HA);
295  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nmic3 * cbm::M2_IN_HA);
296  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( chum1 * cbm::M2_IN_HA);
297  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( chum2 * cbm::M2_IN_HA);
298  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( chum3 * cbm::M2_IN_HA);
299  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nhum1 * cbm::M2_IN_HA);
300  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nhum2 * cbm::M2_IN_HA);
301  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nhum3 * cbm::M2_IN_HA);
302  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( clit1 * cbm::M2_IN_HA);
303  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( clit2 * cbm::M2_IN_HA);
304  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( clit3 * cbm::M2_IN_HA);
305  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nlit1 * cbm::M2_IN_HA);
306  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nlit2 * cbm::M2_IN_HA);
307  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nlit3 * cbm::M2_IN_HA);
308  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_algae_tot * cbm::M2_IN_HA);
309  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( n_algae_tot * cbm::M2_IN_HA);
310  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( cstub * cbm::M2_IN_HA);
311  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nstub * cbm::M2_IN_HA);
312  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( (cwood+caorg+cmic1+cmic2+cmic3+chum1+chum2+chum3+clit1+clit2+clit3+c_algae+cstub+csol) * cbm::M2_IN_HA);
313  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( (nwood+naorg+nmic1+nmic2+nmic3+nhum1+nhum2+nhum3+nlit1+nlit2+nlit3+n_algae+nstub+nsol) * cbm::M2_IN_HA);
314 
315  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( n_sbl * cbm::M2_IN_HA);
316 
317  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( soc20 / soilmass20);
318  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( soc40 / soilmass40);
319  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( totn20 / soilmass20);
320  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( totn40 / soilmass40);
321  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.fe2_sl.sum() * cbm::M2_IN_HA);
322  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.fe3_sl.sum() * cbm::M2_IN_HA);
323  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.till_effect_sl.sum() / sl_.soil_layer_cnt());
324  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( freeze_thaw_fact_sl.sum());
325  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( litter_height);
326  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( MeTrX_get_ph_wl());
327  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.ph_sl[0]);
328  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_no3_groundwater_access * cbm::M2_IN_HA);
329  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( (day_assi_n_mic_1+day_assi_n_mic_2+day_assi_n_mic_3) * cbm::M2_IN_HA);
330  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_nit_nh4_no2 * cbm::M2_IN_HA);
331  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_nit_no2_no3_sl.sum() * cbm::M2_IN_HA);
332  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_nit_no2_no * cbm::M2_IN_HA);
333  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_nit_no2_n2o * cbm::M2_IN_HA);
334  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_denit_no3_no2 * cbm::M2_IN_HA);
335  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_denit_no2_no * cbm::M2_IN_HA);
336  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_denit_no2_n2o * cbm::M2_IN_HA);
337  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_denit_no2_n2 * cbm::M2_IN_HA);
338  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_denit_no_n2o * cbm::M2_IN_HA);
339  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_denit_no_n2 * cbm::M2_IN_HA);
340  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_denit_n2o_n2 * cbm::M2_IN_HA);
341  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_chemodenit_no2_no * cbm::M2_IN_HA);
342  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_ch4_oxidation_sl.sum() * cbm::M2_IN_HA);
343  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_ch4_production_hydrogen_sl.sum() * cbm::M2_IN_HA);
344  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_ch4_production_acetate_sl.sum() * cbm::M2_IN_HA);
345  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_ch4_plant.sum() * cbm::M2_IN_HA);
346  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_ch4_soil.sum() * cbm::M2_IN_HA);
347  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_ch4_water.sum() * cbm::M2_IN_HA);
348  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_ch4_bubbling.sum() * cbm::M2_IN_HA);
349  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_ch4_leach.sum() * cbm::M2_IN_HA);
350  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_o2_plant.sum() * cbm::M2_IN_HA);
351 
352  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( (sc_.accumulated_c_litter_stubble + sc_.accumulated_c_litter_wood_above - accumulated_c_litter_above_old) * cbm::M2_IN_HA);
353  accumulated_c_litter_above_old = sc_.accumulated_c_litter_stubble + sc_.accumulated_c_litter_wood_above;
354 
355  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( (sc_.accumulated_c_litter_below_sl.sum() + sc_.accumulated_c_litter_wood_below_sl.sum() - accumulated_c_litter_below_old) * cbm::M2_IN_HA);
356  accumulated_c_litter_below_old = sc_.accumulated_c_litter_below_sl.sum() + sc_.accumulated_c_litter_wood_below_sl.sum();
357 
358  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_c_fix_algae * cbm::M2_IN_HA);
359  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_n_fix_algae * cbm::M2_IN_HA);
360  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( (day_decomp_c_lit_1+day_decomp_c_lit_2+day_decomp_c_lit_3) * cbm::M2_IN_HA);
361  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_decay_c_mic_sl.sum()*cbm::M2_IN_HA);
362  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_co2_prod_mic_1_growth * cbm::M2_IN_HA);
363  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_co2_prod_mic_1_maintenance * cbm::M2_IN_HA);
364  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_co2_prod_mic_2 * cbm::M2_IN_HA);
365  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_co2_prod_mic_3_acetate_prod * cbm::M2_IN_HA);
366  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_co2_prod_mic_3_acetate_cons * cbm::M2_IN_HA);
367  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_co2_prod_ch4_prod * cbm::M2_IN_HA);
368  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_co2_prod_ch4_cons * cbm::M2_IN_HA);
369  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_h2_c_eq_prod_sl.sum() * cbm::M2_IN_HA);
370  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_acetate_prod_sl.sum() * cbm::M2_IN_HA);
371  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_acetate_cons_fe3_sl.sum() * cbm::M2_IN_HA/FE3_ACETATE_REDUCTION_RATIO);
372  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_h2_c_eq_cons_fe3_sl.sum() * cbm::M2_IN_HA/FE3_ACETATE_REDUCTION_RATIO);
373  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_doc_prod_decomp_litter * cbm::M2_IN_HA);
374  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_doc_prod_decomp_humus * cbm::M2_IN_HA);
375  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_doc_prod_decomp_aorg * cbm::M2_IN_HA);
376  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( dC_root_exsudates * cbm::M2_IN_HA);
377  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_doc_prod_sl.sum() * cbm::M2_IN_HA);
378  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_c_humify_doc_hum_1_sl.sum() * cbm::M2_IN_HA);
379  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_c_humify_sol_hum_1_sl.sum() * cbm::M2_IN_HA);
380  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_c_humify_cel_hum_1_sl.sum() * cbm::M2_IN_HA);
381  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_c_humify_lig_hum_1_sl.sum() * cbm::M2_IN_HA);
382  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_c_humify_lig_hum_2_sl.sum() * cbm::M2_IN_HA);
383  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_c_humify_mic_hum_1_sl.sum() * cbm::M2_IN_HA);
384  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_c_humify_mic_hum_2_sl.sum() * cbm::M2_IN_HA);
385  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_c_humify_hum_1_hum_2_sl.sum() * cbm::M2_IN_HA);
386  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_c_humify_hum_2_hum_3_sl.sum() * cbm::M2_IN_HA);
387  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_min_n_decomp * cbm::M2_IN_HA);
388  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_min_n_aorg * cbm::M2_IN_HA);
389  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_min_n_mic_1 * cbm::M2_IN_HA);
390  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_min_n_mic_2 * cbm::M2_IN_HA);
391  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_min_n_mic_3 * cbm::M2_IN_HA);
392  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_assi_c_mic_1 * cbm::M2_IN_HA);
393  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_assi_c_mic_2 * cbm::M2_IN_HA);
394  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_assi_c_mic_3 * cbm::M2_IN_HA);
395 
396  return output_writer_.write_daily( output_data_);
397 }
double MeTrX_get_ph_wl()
Definition: soilchemistry-metrx-physics-chemistry.cpp:528
Here is the call graph for this function:
Here is the caller graph for this function:

◆ MeTrX_write_output_fluxes()

lerr_t ldndc::SoilChemistryMeTrX::MeTrX_write_output_fluxes ( )
private
Parameters
[in]None
[out]None
Returns
error code

Referenced by MeTrX_write_output().

715 {
716 #define METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH(__val__) \
717 { \
718 double const delta_val( __val__ - output_writer_.output_writer_fluxes.__val__); \
719 LDNDC_OUTPUT_SET_COLUMN_((delta_val),=,output_data_,1); \
720 output_writer_.output_writer_fluxes.__val__ = __val__; \
721 } \
722 
723 #define METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH_2(__val1__,__val2__) \
724 { \
725 double const delta_val( __val1__ - output_writer_.output_writer_fluxes.__val2__); \
726 LDNDC_OUTPUT_SET_COLUMN_((delta_val),=,output_data_,1); \
727 output_writer_.output_writer_fluxes.__val2__ = __val1__; \
728 } \
729 
730  for ( size_t l = 0; l < sl_.soil_layer_cnt(); ++l)
731  {
732  LDNDC_OUTPUT_SET_COLUMN_INDEX(0);
733  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( -sc_.depth_sl[l]);
734 
735  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_nh4_throughfall_sl[l]);
736  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_no3_throughfall_sl[l]);
737  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_nh4_throughfall_sbl[l]);
738  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_no3_throughfall_sbl[l]);
739 
740  //N fluxes in plant/algae
741  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_to_living_plant_and_algae_from_extern_sl[l]);
742  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH_2( ph_.accumulated_nh4_uptake_sl[l], accumulated_n_plant_nh4_uptake_sl[l]);
743  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH_2( ph_.accumulated_no3_uptake_sl[l], accumulated_n_plant_no3_uptake_sl[l]);
744  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH_2( ph_.accumulated_nh3_uptake_sl[l], accumulated_n_plant_nh3_uptake_sl[l]);
745  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH_2( ph_.accumulated_don_uptake_sl[l], accumulated_n_plant_don_uptake_sl[l]);
746  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_algae_nh4_uptake_sbl[l]);
747  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_algae_no3_uptake_sbl[l]);
748  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_algae_nh3_uptake_sbl[l]);
749 
750  //N fluxes from plant to raw litter, stubble and wood
751  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_litter_from_plants_below_rawlitter_sl[l]);
752  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_litter_from_plants_below_wood_sl[l]);
753  if ( l == 0)
754  {
755  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_litter_from_plants_above_rawlitter);
756  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_litter_from_plants_above_wood);
757  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_litter_from_plants_above_stubble);
758  }
759  else
760  {
761  LDNDC_OUTPUT_SET_COLUMN_(0.0,=,output_data_,1);
762  LDNDC_OUTPUT_SET_COLUMN_(0.0,=,output_data_,1);
763  LDNDC_OUTPUT_SET_COLUMN_(0.0,=,output_data_,1);
764  }
765 
766  //N fluxes from raw litter to soil litter
767  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_aboveground_raw_litter_fragmentation_sl[l]);
768  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_belowground_raw_litter_fragmentation_sl[l]);
769 
770  //N fluxes from grazer and algae
771  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_litter_from_algae_sl[l]);
772  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_litter_from_dung_sl[l]);
773  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_urea_from_dung_sl[l]);
774 
775  //N exported via harvesting, cutting and grazing
776  if ( l == 0)
777  {
778  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_export_harvest_cutting_grazing);
779  }
780  else
781  {
782  LDNDC_OUTPUT_SET_COLUMN_(0.0,=,output_data_,1);
783  }
784 
785  //N fluxes from fertilization and manuring
786  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_nh4_fertilization_sl[l]);
787  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_no3_fertilization_sl[l]);
788  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_nh3_fertilization_sl[l]);
789  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_don_fertilization_sl[l]);
790  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_urea_fertilization_sl[l]);
791  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_litter_fertilization_sl[l]);
792  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_aorg_fertilization_sl[l]);
793  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_nh4_fertilization_sbl[l]);
794  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_no3_fertilization_sbl[l]);
795  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_nh3_fertilization_sbl[l]);
796  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_urea_fertilization_sbl[l]);
797 
798  //N redistribution during tilling
799  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_surface_litter_incorporation_via_tilling_sl[l]);
800  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_litter_tilling_sl[l]);
801  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_aorg_tilling_sl[l]);
802  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_humus_1_tilling_sl[l]);
803  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_humus_2_tilling_sl[l]);
804  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_humus_3_tilling_sl[l]);
805  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_no3_tilling_sl[l]);
806  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_no2_tilling_sl[l]);
807  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_no_tilling_sl[l]);
808  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_n2o_tilling_sl[l]);
809  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_urea_tilling_sl[l]);
810  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_don_tilling_sl[l]);
811  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_nh4_tilling_sl[l]);
812  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_nh3_tilling_sl[l]);
813  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_microbes_tilling_sl[l]);
814 
815  //N redistribution during spin up
816  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_humus_1_spinup_sl[l]);
817  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_humus_2_spinup_sl[l]);
818  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_humus_3_spinup_sl[l]);
819  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_surface_litter_spinup_sl[l]);
820  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_litter_spinup_sl[l]);
821 
822  //N fluxes due to water movement
823  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_micro_leaching_sl[l]);
824  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_aorg_leaching_sl[l]);
825  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_litter_leaching_sl[l]);
826  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_humus_1_leaching_sl[l]);
827  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_humus_2_leaching_sl[l]);
828  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_humus_3_leaching_sl[l]);
829  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_nh4_leaching_sl[l]);
830  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH_2( sc_.accumulated_n_no3_leaching_sl[l], accumulated_n_no3_leaching_sl[l]);
831  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_nh3_leaching_sl[l]);
832  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_don_leaching_sl[l]);
833  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_urea_leaching_sl[l]);
834  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_no_leaching_sl[l]);
835  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_n2o_leaching_sl[l]);
836 
837  //N fluxes via liquid diffusion
838  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_urea_liq_diffusion_sl[l]);
839  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_nh3_liq_diffusion_sl[l]);
840  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_nh4_liq_diffusion_sl[l]);
841  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_no3_liq_diffusion_sl[l]);
842 
843  // incoming N from leaching from surface water
844  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_nh4_infiltration_phys_sl[l]);
845  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_nh3_infiltration_phys_sl[l]);
846  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_urea_infiltration_phys_sl[l]);
847  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_no3_infiltration_phys_sl[l]);
848  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_don_infiltration_phys_sl[l]);
849  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_aorg_infiltration_phys_sl[l]);
850 
851  //incoming N fluxes from disappearing water table
852  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_nh4_infiltration_leach_sl[l]);
853  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_nh3_infiltration_leach_sl[l]);
854  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_urea_infiltration_leach_sl[l]);
855  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_no3_infiltration_leach_sl[l]);
856  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_don_infiltration_leach_sl[l]);
857  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_no_infiltration_leach_sl[l]);
858  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_n2o_infiltration_leach_sl[l]);
859 
860  //incoming N flux via liquid diffusion from surface water
861  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_nh4_infiltration_liqdif_sl[l]);
862  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_nh3_infiltration_liqdif_sl[l]);
863  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_urea_infiltration_liqdif_sl[l]);
864  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_no3_infiltration_liqdif_sl[l]);
865 
866  //ebullition fluxes
867  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_nh3_bubbling_sl[l]);
868  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_no_bubbling_sl[l]);
869  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_n2o_bubbling_sl[l]);
870  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_nh3_bubbling_sbl[l]);
871  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_no_bubbling_sbl[l]);
872  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_n2o_bubbling_sbl[l]);
873 
874  //N fluxes due to dissolution between atmosphere and surface water
875  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_nh3_dissolution_sbl[l]);
876  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_no_dissolution_sbl[l]);
877  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_n2o_dissolution_sbl[l]);
878 
879  //N fluxes from urea to nh4
880  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_urea_nh4_hydrolysis_sl[l]);
881  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_urea_nh4_hydrolysis_sbl[l]);
882 
883  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_nh4_assimilation_sl[l]);
884  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_no3_assimilation_sl[l]);
885  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_don_assimilation_sl[l]);
886 
887  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_nh4_nh3_conversion_sl[l]);
888  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_nh3_nh4_conversion_sl[l]);
889  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_nh4_nh3_conversion_sbl[l]);
890  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_nh3_nh4_conversion_sbl[l]);
891 
892  //gaseous diffusion
893  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_nh3_phys_diffusion_sl[l]);
894  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_no_phys_diffusion_sl[l]);
895  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_n2o_phys_diffusion_sl[l]);
896  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_nh3_gas_diffusion_sl[l]);
897  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_no_gas_diffusion_sl[l]);
898  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_n2o_gas_diffusion_sl[l]);
899 
900  //perturbation
901  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_micro_perturbation_sl[l]);
902  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_aorg_perturbation_sl[l]);
903  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_litter_perturbation_sl[l]);
904  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_humus_1_perturbation_sl[l]);
905  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_humus_2_perturbation_sl[l]);
906  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_humus_3_perturbation_sl[l]);
907 
908  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_nh4_no2_nitrification_sl[l]);
909  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_nh4_no_nitrification_sl[l]);
910  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_nh4_n2o_nitrification_sl[l]);
911  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_no2_no3_nitrification_sl[l]);
912 
913  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_no3_no2_denitrification_sl[l]);
914  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_no3_no_denitrification_sl[l]);
915  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_no3_n2o_denitrification_sl[l]);
916  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_no3_n2_denitrification_sl[l]);
917  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_no2_no_denitrification_sl[l]);
918  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_no2_n2o_denitrification_sl[l]);
919  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_no2_n2_denitrification_sl[l]);
920  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_no_n2o_denitrification_sl[l]);
921  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_no_n2_denitrification_sl[l]);
922  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_n2o_n2_denitrification_sl[l]);
923 
924  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_no2_chemodenitrification_sl[l]);
925 
926  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_mic_naorg_decay_sl[l]);
927  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_mic_nh4_mineral_sl[l]);
928  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_mic_don_dissolve_sl[l]);
929 
930  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_aorg_nh4_mineral_sl[l]);
931  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_aorg_don_dissolve_sl[l]);
932 
933  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_humus_1_don_dissolve_sl[l]);
934  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_humus_1_nh4_mineral_sl[l]);
935  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_humus_2_don_dissolve_sl[l]);
936  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_humus_2_nh4_mineral_sl[l]);
937  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_humus_3_don_dissolve_sl[l]);
938  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_humus_3_nh4_mineral_sl[l]);
939 
940  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_litter_don_dissolve_sl[l]);
941  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_litter_nh4_mineral_sl[l]);
942 
943  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_don_humus_1_humify_sl[l]);
944  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_don_humus_2_humify_sl[l]);
945  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_don_humus_3_humify_sl[l]);
946  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT_AND_SWITCH( accumulated_n_litter_humus_1_humify_sl[l]);
947 
948  lerr_t rc_write = output_writer_.write_fluxes( l, output_data_);
949  if ( rc_write)
950  {
951  return LDNDC_ERR_FAIL;
952  }
953  }
954 
955  return LDNDC_ERR_OK;
956 }
Here is the caller graph for this function:

◆ MeTrX_write_output_layer_daily()

lerr_t ldndc::SoilChemistryMeTrX::MeTrX_write_output_layer_daily ( )
private
Parameters
[in]None
[out]None
Returns
error code

References MeTrX_get_ph_wl().

Referenced by MeTrX_write_output().

446 {
447  size_t fl_cnt( m_veg->canopy_layers_used());
448  size_t sbl_cnt( sb_.surfacebulk_layer_cnt());
449 
450  for ( size_t fl = fl_cnt; fl > 0; --fl)
451  {
452  size_t l( fl-1);
453  LDNDC_OUTPUT_SET_COLUMN_INDEX(0);
454  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //depth
455  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( ph_.h_fl[fl]); //extension
456  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //pH
457  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //pore_connectivity
458  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( D_eff_air_fl[l]); //air permeability
459  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //aerenchym_permeability
460  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //cfdd
461  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //water_content
462  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //air_content
463  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //porosity
464  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //fe2
465  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //fe3
466  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( ts_co2_concentration_fl[l]*cbm::M2_IN_HA);
467  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( ts_ch4_concentration_fl[l]*cbm::M2_IN_HA);
468  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //ch4 bubbling
469  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //ch4 production
470  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //ch4 oxidation
471  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //doc production
472  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //acetate production
473  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //mic decay
474  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //doc
475  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //doc
476  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //acetate
477  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //no3
478  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //no3
479  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //nh4
480  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //urea
481  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nh3_fl[l]*cbm::M2_IN_HA);
482  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //o2
483  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( ts_no_concentration_fl[l]*cbm::M2_IN_HA);
484  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //n2o
485  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //c_humus_0
486  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //c_humus_1
487  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //c_humus_2
488  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //no3_cons_denit
489  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //denit_factor_c
490  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //denit_factor_n
491  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //no3_prod_nit
492  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //no3_leaching
493 
494  lerr_t rc_write = output_writer_.write_layer_daily( -static_cast< int >( fl+sbl_cnt+1), output_data_);
495  if ( rc_write)
496  {
497  return LDNDC_ERR_FAIL;
498  }
499  }
500 
501  for (size_t sbl = sbl_cnt; sbl > 0; --sbl)
502  {
503  double depth_sbl( sbl_cnt * 0.01 - 0.5 * 0.01 - (sbl-1) * 0.01);
504  size_t l( sbl-1);
505  LDNDC_OUTPUT_SET_COLUMN_INDEX(0);
506  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( depth_sbl); //depth
507  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //extension
508  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( MeTrX_get_ph_wl()); //pH
509  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //pore_connectivity
510  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //air permeability
511  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //aerenchym_permeability
512  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //cfdd
513  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //water_content
514  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //air_content
515  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //porosity
516  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //fe2
517  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //fe3
518  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sb_.co2_sbl[l]*cbm::M2_IN_HA);
519  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sb_.ch4_sbl[l]*cbm::M2_IN_HA);
520 
521  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( (accumulated_c_ch4_bubbling_sbl[l]-
522  output_writer_.output_writer_layer_daily.accumulated_c_ch4_bubbling_sbl[l])*cbm::M2_IN_HA);
523  output_writer_.output_writer_layer_daily.accumulated_c_ch4_bubbling_sbl[l] = accumulated_c_ch4_bubbling_sbl[l];
524 
525  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //ch4 production
526  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //ch4 oxidation
527  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //doc production
528  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //acetate production
529  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //mic decay
530  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //doc
531  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sb_.doc_sbl[l]*cbm::M2_IN_HA);
532  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //acetate
533  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //no3 ae
534  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sb_.no3_sbl[l]*cbm::M2_IN_HA);
535  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sb_.nh4_sbl[l]*cbm::M2_IN_HA);
536  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sb_.urea_sbl[l]*cbm::M2_IN_HA);
537  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sb_.nh3_sbl[l]*cbm::M2_IN_HA);
538  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sb_.o2_sbl[l]*cbm::M2_IN_HA);
539  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //no
540  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //n2o
541  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //c_humus_0
542  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //c_humus_1
543  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //c_humus_2
544  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //no3_cons_denit
545  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //denit_factor_c
546  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //denit_factor_n
547  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //no3_prod_nit
548  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0.0); //no3_leaching
549 
550  lerr_t rc_write = output_writer_.write_layer_daily( -static_cast< int >( sbl), output_data_);
551  if ( rc_write)
552  {
553  return LDNDC_ERR_FAIL;
554  }
555  }
556 
557  for ( size_t l = 0; l < sl_.soil_layer_cnt(); ++l)
558  {
559  LDNDC_OUTPUT_SET_COLUMN_INDEX(0);
560  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( -sc_.depth_sl[l]);
561  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.h_sl[l]);
562  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.ph_sl[l]);
563  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( pore_connectivity_sl[l]);
564  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( D_eff_air_sl[l]);
565  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( D_eff_plant_sl[l]);
566  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( cumulative_freezing_degree_days_sl[l]);
567  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( wc_.wc_sl[l]);
568  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( v_air_sl[l]/sc_.h_sl[l]);
569  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.poro_sl[l]);
570  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.fe2_sl[l]*cbm::M2_IN_HA);
571  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.fe3_sl[l]*cbm::M2_IN_HA);
572  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( (co2_liq_sl[l]+co2_gas_sl[l])*cbm::M2_IN_HA);
573  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( (ch4_liq_sl[l]+ch4_gas_sl[l])*cbm::M2_IN_HA);
574  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( (accumulated_c_ch4_bubbling_sl[l]-
575  output_writer_.output_writer_layer_daily.accumulated_c_ch4_bubbling_sl[l])*cbm::M2_IN_HA);
576  output_writer_.output_writer_layer_daily.accumulated_c_ch4_bubbling_sl[l] = accumulated_c_ch4_bubbling_sl[l];
577  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( (day_ch4_production_acetate_sl[l]+day_ch4_production_hydrogen_sl[l])*cbm::M2_IN_HA);
578  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_ch4_oxidation_sl[l]*cbm::M2_IN_HA);
579  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_doc_prod_sl[l]*cbm::M2_IN_HA);
580  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_acetate_prod_sl[l]*cbm::M2_IN_HA);
581  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_decay_c_mic_sl[l]*cbm::M2_IN_HA);
582  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( (sc_.doc_sl[l])*cbm::M2_IN_HA);
583  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( (sc_.an_doc_sl[l])*cbm::M2_IN_HA);
584  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( (ae_acetate_sl[l]+an_acetate_sl[l])*cbm::M2_IN_HA);
585  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( (no3_ae_sl[l])*cbm::M2_IN_HA);
586  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( (no3_an_sl[l])*cbm::M2_IN_HA);
587  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( (nh4_ae_sl[l]+nh4_an_sl[l]+sc_.clay_nh4_sl[l])*cbm::M2_IN_HA);
588  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.urea_sl[l]*cbm::M2_IN_HA);
589  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( (sc_.nh3_gas_sl[l]+sc_.nh3_liq_sl[l])*cbm::M2_IN_HA);
590  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( (o2_gas_sl[l]+o2_liq_sl[l])*cbm::M2_IN_HA);
591  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( (no_liq_sl[l]+no_gas_sl[l]+an_no_liq_sl[l]+an_no_gas_sl[l])*cbm::M2_IN_HA);
592  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( (n2o_liq_sl[l]+n2o_gas_sl[l]+an_n2o_liq_sl[l]+an_n2o_gas_sl[l])*cbm::M2_IN_HA);
593  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_humus_1_sl[l]*cbm::M2_IN_HA);
594  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_humus_2_sl[l]*cbm::M2_IN_HA);
595  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_humus_3_sl[l]*cbm::M2_IN_HA);
596  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( (accumulated_n_no3_no2_denitrification_sl[l]
597  -output_writer_.output_writer_layer_daily.accumulated_n_no3_no2_denitrification_sl[l]) * cbm::M2_IN_HA);
598  output_writer_.output_writer_layer_daily.accumulated_n_no3_no2_denitrification_sl[l] = accumulated_n_no3_no2_denitrification_sl[l];
599  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_denit_factor_c_sl[l]*FTS_TOT_);
600  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_denit_factor_n_sl[l]*FTS_TOT_);
601  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_nit_no2_no3_sl[l]*cbm::M2_IN_HA);
602  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( (sc_.accumulated_n_no3_leaching_sl[l]
603  -output_writer_.output_writer_layer_daily.accumulated_n_no3_leaching_sl[l]) * cbm::M2_IN_HA);
604  output_writer_.output_writer_layer_daily.accumulated_n_no3_leaching_sl[l] = sc_.accumulated_n_no3_leaching_sl[l];
605 
606  lerr_t rc_write = output_writer_.write_layer_daily( l, output_data_);
607  if ( rc_write)
608  {
609  return LDNDC_ERR_FAIL;
610  }
611  }
612 
613  return LDNDC_ERR_OK;
614 }
double MeTrX_get_ph_wl()
Definition: soilchemistry-metrx-physics-chemistry.cpp:528
Here is the call graph for this function:
Here is the caller graph for this function:

◆ MeTrX_write_output_layer_yearly()

lerr_t ldndc::SoilChemistryMeTrX::MeTrX_write_output_layer_yearly ( )
private
Parameters
[in]None
[out]None
Returns
error code

Referenced by MeTrX_write_output().

619 {
620  for ( size_t l = 0; l < sl_.soil_layer_cnt(); ++l)
621  {
622  LDNDC_OUTPUT_SET_COLUMN_INDEX(0);
623  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( -sc_.depth_sl[l]);
624  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_humus_1_sl[l]);
625  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_humus_2_sl[l]);
626  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_humus_3_sl[l]);
627  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.C_aorg_sl[l]);
628  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.C_micro1_sl[l]+sc_.C_micro2_sl[l]+sc_.C_micro3_sl[l]);
629 
630  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( accumulated_n_no3_no2_denitrification_sl[l] - output_writer_.output_writer_layer_yearly.accumulated_n_no3_no2_denitrification_sl[l]);
631  output_writer_.output_writer_layer_yearly.accumulated_n_no3_no2_denitrification_sl[l] = accumulated_n_no3_no2_denitrification_sl[l];
632 
633  lerr_t rc_write = output_writer_.write_layer_yearly( l, output_data_);
634  if ( rc_write)
635  {
636  return LDNDC_ERR_FAIL;
637  }
638  }
639 
640  return LDNDC_ERR_OK;
641 }
Here is the caller graph for this function:

◆ MeTrX_write_output_pools()

lerr_t ldndc::SoilChemistryMeTrX::MeTrX_write_output_pools ( )
private
Parameters
[in]None
[out]None
Returns
error code

Referenced by MeTrX_write_output().

646 {
647  for ( size_t l = 0; l < sl_.soil_layer_cnt(); ++l)
648  {
649  LDNDC_OUTPUT_SET_COLUMN_INDEX(0);
650  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( -sc_.depth_sl[l]);
651 
652  //pools that exist for each soil layer
653  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.urea_sl[l]);
654  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.N_lit1_sl[l] + sc_.N_lit2_sl[l] + sc_.N_lit3_sl[l] + sc_.n_wood_sl[l] + sc_.n_raw_lit_1_sl[l] + sc_.n_raw_lit_2_sl[l] + sc_.n_raw_lit_3_sl[l]);
655  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.N_aorg_sl[l]);
656  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( n_humus_1_sl[l]);
657  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( n_humus_2_sl[l]);
658  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( n_humus_3_sl[l]);
659  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( n_micro_1_sl[l] + n_micro_2_sl[l] + n_micro_3_sl[l]);
660  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.nh3_liq_sl[l] + sc_.nh3_gas_sl[l]);
661  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nh4_ae_sl[l] + nh4_an_sl[l] + sc_.clay_nh4_sl[l]);
662  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( don_ae_sl[l] + don_an_sl[l]);
663  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( no3_ae_sl[l] + no3_an_sl[l]);
664  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.no2_sl[l] + sc_.an_no2_sl[l]);
665  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( no_gas_sl[l] + an_no_gas_sl[l] + no_liq_sl[l] + an_no_liq_sl[l]);
666  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( n2o_gas_sl[l] + an_n2o_gas_sl[l] + n2o_liq_sl[l] + an_n2o_liq_sl[l]);
667 
668  //surface pools
669  if( l == 0 )
670  {
671  double nplant(0.0);
672  for ( PlantIterator vt = this->m_veg->begin(); vt != this->m_veg->end(); ++vt)
673  {
674  nplant += (*vt)->total_nitrogen();
675  }
676 
677  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sb_.nh4_sbl.sum() );
678  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sb_.nh3_sbl.sum() );
679  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sb_.n2o_sbl.sum() );
680  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sb_.no_sbl.sum() );
681  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sb_.urea_sbl.sum() );
682  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sb_.no3_sbl.sum() );
683  //METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sb_.don_sbl.sum() );
684  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nplant );
685  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.n_wood + sc_.n_stubble_lit1 + sc_.n_stubble_lit2 + sc_.n_stubble_lit3 +
686  sc_.n_raw_lit_1_above + sc_.n_raw_lit_2_above + sc_.n_raw_lit_3_above);
687  }
688  else
689  {
690  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0 );
691  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0 );
692  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0 );
693  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0 );
694  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0 );
695  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0 );
696  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0 );
697  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0 );
698  //METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0 );
699  //METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0 );
700  }
701 
702  lerr_t rc_write = output_writer_.write_pools( l, output_data_);
703  if ( rc_write)
704  {
705  return LDNDC_ERR_FAIL;
706  }
707  }
708 
709  return LDNDC_ERR_OK;
710 }
Here is the caller graph for this function:

◆ MeTrX_write_output_subdaily()

lerr_t ldndc::SoilChemistryMeTrX::MeTrX_write_output_subdaily ( )
private
Parameters
[in]None
[out]None
Returns
error code

References MeTrX_get_ph_wl().

Referenced by MeTrX_write_output().

961 {
962  size_t s( lclock()->subday()-1);
963  LDNDC_OUTPUT_SET_COLUMN_INDEX(0);
964  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.C_micro1_sl.sum());
965  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.C_micro2_sl.sum());
966  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.C_micro3_sl.sum());
967  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.C_aorg_sl.sum());
968  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nh4_ae_sl.sum()+nh4_an_sl.sum()+sc_.clay_nh4_sl.sum());
969  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( no3_ae_sl.sum());
970  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( no3_an_sl.sum());
971  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.doc_sl.sum());
972  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.an_doc_sl.sum());
973  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( ae_acetate_sl.sum());
974  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( an_acetate_sl.sum());
975 
976  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_ch4_bubbling[s]);
977  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_ch4_plant[s]);
978  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_ch4_soil[s]);
979  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_ch4_water[s]);
980  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_ch4_leach[s]);
981  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_ch4_prod[s]);
982  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_ch4_ox[s]);
983 
984  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_acetate_prod[s]);
985  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_doc_prod[s]);
986 
987  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( accumulated_n_no2_no3_nitrification_sl.sum() - output_writer_.output_writer_subdaily.accumulated_n_no2_no3_nitrification);
988  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( accumulated_n_no3_no2_denitrification_sl.sum() - output_writer_.output_writer_subdaily.accumulated_n_no3_no2_denitrification);
989 
990  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_n2o_bubbling[s]);
991  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_n2o_plant[s]);
992  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_n2o_soil[s]);
993  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_n2o_water[s]);
994  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_no_bubbling[s]);
995  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_no_plant[s]);
996  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_no_soil[s]);
997  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_no_water[s]);
998  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_nh3_bubbling[s]);
999  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_nh3_plant[s]);
1000  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_nh3_soil[s]);
1001  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_nh3_water[s]);
1002 
1003  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_plant_o2_cons[s]);
1004  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_o2_plant[s]);
1005  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_algae_o2_prod[s]);
1006 
1007  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( MeTrX_get_ph_wl());
1008  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.ph_sl[0]);
1009  double anvf_mean( sc_.anvf_sl.sum() / sl_.soil_layer_cnt());
1010  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( anvf_mean);
1011 
1012  lerr_t rc_write = output_writer_.write_subdaily( output_data_);
1013  if ( rc_write)
1014  {
1015  return LDNDC_ERR_FAIL;
1016  }
1017 
1018  output_writer_.output_writer_subdaily.accumulated_n_no2_no3_nitrification = accumulated_n_no2_no3_nitrification_sl.sum();
1019  output_writer_.output_writer_subdaily.accumulated_n_no3_no2_denitrification = accumulated_n_no3_no2_denitrification_sl.sum();
1020 
1021  return LDNDC_ERR_OK;
1022 }
double MeTrX_get_ph_wl()
Definition: soilchemistry-metrx-physics-chemistry.cpp:528
Here is the call graph for this function:
Here is the caller graph for this function:

◆ MeTrX_write_output_yearly()

lerr_t ldndc::SoilChemistryMeTrX::MeTrX_write_output_yearly ( )
private
Parameters
[in]None
[out]None
Returns
error code

Referenced by MeTrX_write_output().

402 {
403  double surface_litter( c_algae + c_dead_algae + sc_.c_stubble_lit1 + sc_.c_stubble_lit2 + sc_.c_stubble_lit3);
404  double soc20( 0.0);
405  double c_hum_1_20( 0.0);
406  double c_hum_2_20( 0.0);
407  double c_hum_3_20( 0.0);
408  double c_litter_20( 0.0);
409  double c_aorg_20( 0.0);
410  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
411  {
412  if ( cbm::flt_less_equal( sc_.depth_sl[sl], 0.2))
413  {
414  soc20 += sc_.C_aorg_sl[sl] + c_humus_1_sl[sl] + c_humus_2_sl[sl] + c_humus_3_sl[sl]
415  + sc_.C_micro1_sl[sl] + sc_.C_micro2_sl[sl] + sc_.C_micro3_sl[sl]
416  + sc_.C_lit1_sl[sl] + sc_.C_lit2_sl[sl] + sc_.C_lit3_sl[sl];
417  c_hum_1_20 += c_humus_1_sl[sl];
418  c_hum_2_20 += c_humus_2_sl[sl];
419  c_hum_3_20 += c_humus_3_sl[sl];
420  c_litter_20 += sc_.C_lit1_sl[sl] + sc_.C_lit2_sl[sl] + sc_.C_lit3_sl[sl];
421  c_aorg_20 += sc_.C_aorg_sl[sl];
422  }
423  else
424  {
425  break;
426  }
427  }
428 
429 #define METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT(__val__) LDNDC_OUTPUT_SET_COLUMN_((__val__),=,output_data_,1)
430  LDNDC_OUTPUT_SET_COLUMN_INDEX(0);
431 
432  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( surface_litter);
433  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( soc20);
434  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_hum_1_20);
435  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_hum_2_20);
436  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_hum_3_20);
437  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_litter_20);
438  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_aorg_20);
439 
440  return output_writer_.write_yearly( output_data_);
441 }
Here is the caller graph for this function:

◆ MeTrX_write_rates()

lerr_t ldndc::SoilChemistryMeTrX::MeTrX_write_rates ( )
private
Parameters
[in]None
[out]None
Returns
error code

References MeTrX_send_state().

Referenced by solve().

20 {
21  sc_.accumulated_n2_emis = 0.0;
22  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
23  {
24  sc_.no_sl[sl] = no_gas_sl[sl]+no_liq_sl[sl];
25  sc_.an_no_sl[sl] = an_no_gas_sl[sl]+an_no_liq_sl[sl];
26 
27  sc_.n2o_sl[sl] = n2o_gas_sl[sl]+n2o_liq_sl[sl];
28  sc_.an_n2o_sl[sl] = an_n2o_gas_sl[sl]+an_n2o_liq_sl[sl];
29 
30  sc_.C_hum_sl[sl] = c_humus_1_sl[sl] + c_humus_2_sl[sl] + c_humus_3_sl[sl];
31  sc_.N_hum_sl[sl] = n_humus_1_sl[sl] + n_humus_2_sl[sl] + n_humus_3_sl[sl];
32 
33  sc_.N_micro_sl[sl] = n_micro_1_sl[sl] + n_micro_2_sl[sl] + n_micro_3_sl[sl];
34  sc_.som_sl[sl] = (sc_.C_lit1_sl[sl] + sc_.C_lit2_sl[sl] + sc_.C_lit3_sl[sl]
35  + sc_.c_raw_lit_1_sl[sl] + sc_.c_raw_lit_2_sl[sl] + sc_.c_raw_lit_3_sl[sl]
36  + sc_.C_micro1_sl[sl] + sc_.C_micro2_sl[sl] + sc_.C_micro3_sl[sl]
37  + sc_.C_hum_sl[sl] + sc_.C_aorg_sl[sl])
38  / cbm::CCORG;
39 
40  sc_.o2_sl[sl] = o2_gas_sl[sl] * RGAS_M_O2_BAR_PA * (mc_temp_sl[sl] + cbm::D_IN_K) / v_air_sl[sl];
41 
42  sc_.accumulated_no3_denitrify_sl[sl] = accumulated_n_no3_no2_denitrification_sl[sl];
43  sc_.accumulated_n2_emis += accumulated_n_no3_n2_denitrification_sl[sl]
44  + accumulated_n_no2_n2_denitrification_sl[sl]
45  + accumulated_n_no_n2_denitrification_sl[sl]
46  + accumulated_n_n2o_n2_denitrification_sl[sl];
47  }
48 
49  size_t const ts_end( (timemode_ == TMODE_SUBDAILY) ? lclock()->subday() * INTERNAL_TIME_STEPS : INTERNAL_TIME_STEPS);
50  size_t const ts_start( ts_end - INTERNAL_TIME_STEPS);
51  for ( size_t ts = ts_start; ts < ts_end; ++ts)
52  {
53  sc_.accumulated_co2_emis += subdaily_co2_soil[ts] + subdaily_co2_plant[ts] + subdaily_co2_bubbling[ts] + subdaily_co2_water[ts];
54  sc_.accumulated_ch4_emis += subdaily_ch4_soil[ts] + subdaily_ch4_plant[ts] + subdaily_ch4_bubbling[ts] + subdaily_ch4_water[ts];
55  sc_.accumulated_n2o_emis += subdaily_n2o_soil[ts] + subdaily_n2o_plant[ts] + subdaily_n2o_bubbling[ts] + subdaily_n2o_water[ts];
56  sc_.accumulated_no_emis += subdaily_no_soil[ts] + subdaily_no_plant[ts] + subdaily_no_bubbling[ts] + subdaily_no_water[ts];
57  sc_.accumulated_nh3_emis += subdaily_nh3_soil[ts] + subdaily_nh3_plant[ts] + subdaily_nh3_bubbling[ts] + subdaily_nh3_water[ts];
58 
59  sc_.accumulated_ch4_leach += subdaily_ch4_leach[ts];
60  }
61 
62  sc_.accumulated_co2_emis_auto += co2_auto_sl.sum();
63  sc_.accumulated_co2_emis_hetero += co2_hetero_sl.sum();
64 
65  if (timemode_ == TMODE_SUBDAILY)
66  {
67  for ( PlantIterator vt = this->m_veg->begin(); vt != this->m_veg->end(); ++vt)
68  {
69  accumulated_n_to_living_plant_and_algae_from_extern_sl[0] += (*vt)->n2_fixation;
70  }
71  }
72  else
73  {
74  for ( PlantIterator vt = this->m_veg->begin(); vt != this->m_veg->end(); ++vt)
75  {
76  accumulated_n_to_living_plant_and_algae_from_extern_sl[0] += (*vt)->d_n2_fixation;
77  }
78  }
79 
80  if ( timemode_ != TMODE_SUBDAILY || lclock()->is_position( TMODE_POST_DAILY))
81  {
82  /*************************/
83  /* Yearly rate variables */
84  /*************************/
85 
86  sc_.accumulated_c_fix_algae += day_c_fix_algae;
87  sc_.accumulated_n_fix_algae += day_n_fix_algae;
88  }
89 
91 
92  return LDNDC_ERR_OK;
93 }
lerr_t MeTrX_send_state()
Definition: soilchemistry-metrx-communicate.cpp:345
Here is the call graph for this function:
Here is the caller graph for this function:

◆ solve()

lerr_t ldndc::SoilChemistryMeTrX::solve ( )

Kicks off computation for one time step.

References MeTrX_algae_dynamics(), MeTrX_anaerobic_volume(), MeTrX_ch4_oxidation(), MeTrX_ch4_production(), MeTrX_check_for_negative_value(), MeTrX_chemodenitrification(), MeTrX_clay_nh4_equilibrium(), MeTrX_denitrification(), MeTrX_dissolution(), MeTrX_ebullition(), MeTrX_fermentation(), MeTrX_fertilize(), MeTrX_fragmentation(), MeTrX_freeze_thaw(), MeTrX_gas_diffusion(), MeTrX_groundwater_access(), MeTrX_iron_oxidation(), MeTrX_iron_reduction(), MeTrX_leaching(), MeTrX_liq_diffusion(), MeTrX_manure(), MeTrX_metabolism(), MeTrX_microbial_dynamics(), MeTrX_nh3_nh4_equilibrium(), MeTrX_nitrification(), MeTrX_nitrogen_fertilizer_release(), MeTrX_pertubation(), MeTrX_pH_calculation(), MeTrX_physics(), MeTrX_plant_respiration(), MeTrX_reset(), MeTrX_soil_organic_matter_turnover(), MeTrX_spinup(), MeTrX_till(), MeTrX_update(), MeTrX_urea_hydrolysis(), MeTrX_write_output(), and MeTrX_write_rates().

20 {
21  if ( (lclock()->subday() == 1) || (timemode_ != TMODE_SUBDAILY))
22  {
23  subdaily_time_step_ = 0;
24  }
25 
26  lerr_t rc = MeTrX_check_for_negative_value( "entry");
27  if ( rc) return LDNDC_ERR_FAIL;
28 
29  MeTrX_reset();
30 
31  rc = MeTrX_update();
32  if ( rc) return LDNDC_ERR_FAIL;
33 
34  rc = MeTrX_spinup();
35  if ( rc) return LDNDC_ERR_FAIL;
36 
37  rc = MeTrX_balance_check( 1);
38  if ( rc) return LDNDC_ERR_FAIL;
39 
40  rc = MeTrX_physics();
41  if ( rc) return LDNDC_ERR_FAIL;
42 
43  rc = MeTrX_fertilize();
44  if ( rc) return LDNDC_ERR_FAIL;
45 
46  rc = MeTrX_manure();
47  if ( rc) return LDNDC_ERR_FAIL;
48 
49  rc = MeTrX_till();
50  if ( rc) return LDNDC_ERR_FAIL;
51 
53 
54  for (size_t ts = 0; ts < INTERNAL_TIME_STEPS; ++ts)
55  {
59  MeTrX_advection();
62 
64 
66 
67  lerr_t rc_meta = MeTrX_metabolism();
68  if (rc_meta) { return rc_meta; }
69 
70  lerr_t rc_pertub = MeTrX_pertubation();
71  if (rc_pertub) { return rc_pertub; }
72 
75 
80 
85 
89 
91 
94 
97 
98  subdaily_time_step_ += 1;
99  }
100 
101  rc = MeTrX_balance_check( 2);
102  if ( rc) return LDNDC_ERR_FAIL;
103 
106 
107  rc = MeTrX_check_for_negative_value( "exit");
108  if ( rc) return LDNDC_ERR_FAIL;
109 
110  return LDNDC_ERR_OK;
111 }
lerr_t MeTrX_update()
Definition: soilchemistry-metrx-communicate.cpp:63
lerr_t MeTrX_spinup()
Definition: soilchemistry-metrx-spinup.cpp:68
void MeTrX_groundwater_access()
Definition: soilchemistry-metrx-transport.cpp:542
lerr_t MeTrX_nitrogen_fertilizer_release()
Transforms nitrogen from slow release nitrogen fertilizer to nh4.
Definition: soilchemistry-metrx-management.cpp:946
lerr_t MeTrX_till()
Definition: soilchemistry-metrx-management.cpp:702
lerr_t MeTrX_freeze_thaw()
Definition: soilchemistry-metrx-physics-chemistry.cpp:394
lerr_t MeTrX_physics()
Definition: soilchemistry-metrx-physics-chemistry.cpp:157
void MeTrX_pH_calculation()
Definition: soilchemistry-metrx-physics-chemistry.cpp:542
lerr_t MeTrX_write_rates()
Definition: soilchemistry-metrx-integrate.cpp:19
lerr_t MeTrX_fertilize()
Definition: soilchemistry-metrx-management.cpp:33
void MeTrX_soil_organic_matter_turnover()
void MeTrX_nh3_nh4_equilibrium()
Definition: soilchemistry-metrx-physics-chemistry.cpp:32
void MeTrX_leaching()
Downwards transport of solutes, litter and humus with percolation water.
Definition: soilchemistry-metrx-transport.cpp:24
void MeTrX_urea_hydrolysis()
Definition: soilchemistry-metrx-management.cpp:879
lerr_t MeTrX_pertubation()
Definition: soilchemistry-metrx-transport.cpp:1366
lerr_t MeTrX_fragmentation()
Definition: soilchemistry-metrx-fragmentation.cpp:24
lerr_t MeTrX_plant_respiration(size_t)
Updates o2 and co2 concentrations in soil layers. There is no o2 mass conservation guaranteed because...
Definition: soilchemistry-metrx-management.cpp:1039
lerr_t MeTrX_manure()
Definition: soilchemistry-metrx-management.cpp:264
lerr_t MeTrX_write_output()
Definition: soilchemistry-metrx-output.cpp:16
lerr_t MeTrX_reset()
Definition: soilchemistry-metrx-reset.cpp:36
lerr_t MeTrX_check_for_negative_value(char const *)
iterates over complete soilchemistry state and checks for negative values
Definition: soilchemistry-metrx-balance-check.cpp:174
lerr_t MeTrX_metabolism()
Definition: soilchemistry-metrx-microbial-dynamics.cpp:187
void MeTrX_clay_nh4_equilibrium()
Definition: soilchemistry-metrx-physics-chemistry.cpp:94
Here is the call graph for this function:

Member Data Documentation

◆ N_MINERALISATION_FRACTION

const double ldndc::SoilChemistryMeTrX::N_MINERALISATION_FRACTION = 0.5
staticprivate

Fractionation factor determining the share of decomposed nitrogen from different sources being mineralized to NH4 [-]

◆ TNORM

const double ldndc::SoilChemistryMeTrX::TNORM = 293.2
staticprivate

Reference temperature [K]

Referenced by MeTrX_physics().