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  /* n-h4 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( (nh4_clay - sc_.clay_nh4_sl[sl]) * FTS_TOT_);
133 
134  sc_.clay_nh4_sl[sl] += delta_nh4;
135  double const nh4_sol_new( nh4_total - sc_.clay_nh4_sl[sl]);
136  if ( cbm::flt_greater_zero( nh4_sol_old))
137  {
138  nh4_ae_sl[sl] = nh4_ae_sl[sl] / nh4_sol_old * nh4_sol_new;
139  nh4_an_sl[sl] = nh4_sol_new - nh4_ae_sl[sl];
140  }
141  else
142  {
143  nh4_ae_sl[sl] = nh4_sol_new * (1.0 - sc_.anvf_sl[sl]);
144  nh4_an_sl[sl] = nh4_sol_new * sc_.anvf_sl[sl];
145  }
146  }
147 }
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().

521 {
522  double const val_tot( _val_gas + _val_liq);
523  if ( cbm::flt_greater_zero( val_tot))
524  {
525  _val_liq = _henry / (1.0 + _henry) * val_tot;
526  _val_gas = val_tot - _val_liq;
527  }
528  return LDNDC_ERR_OK;
529 }
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().

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

387 {
388  if ( have_freeze_thaw)
389  {
390  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
391  {
392  if ( cbm::flt_greater_zero( v_ice_sl[sl]) &&
393  cbm::flt_greater( mc_temp_sl[sl], -0.5))
394  {
395  freeze_thaw_fact_sl[sl] = 1.0;
396  }
397  else if (freeze_thaw_fact_sl[sl] > 0.1)
398  {
399  freeze_thaw_fact_sl[sl] -= 0.3 * FTS_TOT_ * freeze_thaw_fact_sl[sl];
400  }
401  else
402  {
403  freeze_thaw_fact_sl[sl] = 0.0;
404  }
405  }
406  }
407 
408  return LDNDC_ERR_OK;
409 }
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().

654 {
655  double const fact_t( std::exp( -sipar_.METRX_F_DECOMP_T_EXP_1() *
656  pow(1.0 - mc_temp_sl[_sl] / sipar_.METRX_F_DECOMP_T_EXP_2(), 2.0)));
657  double const fact_m( ldndc::meteo::F_weibull( MeTrX_get_wfps_eff( _sl, 0.0),
658  sipar_.METRX_F_DECOMP_M_WEIBULL_1(),
659  sipar_.METRX_F_DECOMP_M_WEIBULL_2(),
660  1.0));
661  return cbm::harmonic_mean2( fact_t, fact_m);
662 }
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().

490 {
491  if ( cbm::flt_greater_zero( wc_.surface_water))
492  {
493  return cbm::bound( PH_SURFACE_WATER, PH_SURFACE_WATER + ph_delta_pab_wl + ph_delta_urea_wl, PH_MAX);
494  }
495  else
496  {
497  return 7.0;
498  }
499 }
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().

539 {
540  if ( gw_ != NULL)
541  {
542  for ( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
543  {
544  if ( sc_.depth_sl[sl] > gw_->watertable_subday( lclock_ref()))
545  {
546  double const no3_gw( gw_->no3_day(lclock_ref()) //given in (mg no3 L-1)
547  * cbm::MN / (cbm::MN + 3.0 * cbm::MO) * cbm::KG_IN_MG //converts no3 from (mg no3) -> (kg n-no3)
548  * (wc_.wc_sl[sl] + wc_.ice_sl[sl]) * sc_.h_sl[sl] * cbm::DM3_IN_M3); //converts water (m3) -> (L)
549 
550  if ( cbm::flt_greater_zero( no3_gw))
551  {
552  double const no3_diff( GROUNDWATER_NUTRIENT_ACCESS_RATE * (no3_gw - no3_an_sl[sl]));
553  no3_an_sl[sl] += no3_diff;
554  day_no3_groundwater_access += no3_diff;
555  sc_.accumulated_no3_leach -= no3_diff;
556  sc_.accumulated_n_no3_leaching_sl[sl] -= no3_diff;
557  }
558  }
559  }
560 
561  if ( have_river_connection)
562  {
563  if ( have_water_table)
564  {
565  for (size_t sbl = 0; sbl < sb_.surfacebulk_layer_cnt(); ++sbl)
566  {
567  DISSOLUTION_ATMOSPHERE( MeTrX_get_atm_eq_liq( o2_atm_eq_liq, h_wl), sb_.o2_sbl[sbl], subdaily_o2_water[subdaily_time_step_]);
568  DISSOLUTION_ATMOSPHERE( MeTrX_get_atm_eq_liq( ch4_atm_eq_liq, h_wl), sb_.ch4_sbl[sbl], subdaily_ch4_water[subdaily_time_step_]);
569  DISSOLUTION_ATMOSPHERE( MeTrX_get_atm_eq_liq( co2_atm_eq_liq, h_wl), sb_.co2_sbl[sbl], subdaily_co2_water[subdaily_time_step_]);
570  DISSOLUTION_ATMOSPHERE( MeTrX_get_atm_eq_liq( nh3_atm_eq_liq, h_wl), sb_.nh3_sbl[sbl], subdaily_nh3_water[subdaily_time_step_]);
571  DISSOLUTION_ATMOSPHERE( MeTrX_get_atm_eq_liq( no_atm_eq_liq, h_wl), sb_.no_sbl[sbl], subdaily_no_water[subdaily_time_step_]);
572  DISSOLUTION_ATMOSPHERE( MeTrX_get_atm_eq_liq( n2o_atm_eq_liq, h_wl), sb_.n2o_sbl[sbl], subdaily_n2o_water[subdaily_time_step_]);
573  }
574  }
575  }
576  }
577 }
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 
59  accumulated_n_nh4_infiltration_leach_sl[0] += nh4_an_sl[0] + sc_.coated_nh4_sl[0];
60  accumulated_n_nh3_infiltration_leach_sl[0] += sc_.nh3_liq_sl[0];
61  accumulated_n_no_infiltration_leach_sl[0] += an_no_liq_sl[0];
62  accumulated_n_n2o_infiltration_leach_sl[0] += an_n2o_liq_sl[0];
63  accumulated_n_urea_infiltration_leach_sl[0] += sc_.urea_sl[0];
64  accumulated_n_no3_infiltration_leach_sl[0] += no3_an_sl[0];
65  accumulated_n_don_infiltration_leach_sl[0] += don_an_sl[0];
66 
67  for (size_t sbl = 1; sbl < sb_.surfacebulk_layer_cnt(); ++sbl)
68  {
69  size_t const sbl_plus( sbl - 1);
70  LEACH_DOWN( sb_.ch4_sbl[sbl], sb_.ch4_sbl[sbl_plus], leach_fact_sbl);
71  LEACH_DOWN( sb_.o2_sbl[sbl], sb_.o2_sbl[sbl_plus], leach_fact_sbl);
72  LEACH_DOWN( sb_.nh4_sbl[sbl], sb_.nh4_sbl[sbl_plus], leach_fact_sbl);
73  LEACH_DOWN( sb_.coated_nh4_sbl[sbl], sb_.coated_nh4_sbl[sbl_plus], leach_fact_sbl);
74  LEACH_DOWN( sb_.nh3_sbl[sbl], sb_.nh3_sbl[sbl_plus], leach_fact_sbl);
75  LEACH_DOWN( sb_.no_sbl[sbl], sb_.no_sbl[sbl_plus], leach_fact_sbl);
76  LEACH_DOWN( sb_.n2o_sbl[sbl], sb_.n2o_sbl[sbl_plus], leach_fact_sbl);
77  LEACH_DOWN( sb_.urea_sbl[sbl], sb_.urea_sbl[sbl_plus], leach_fact_sbl);
78  LEACH_DOWN( sb_.no3_sbl[sbl], sb_.no3_sbl[sbl_plus], leach_fact_sbl);
79  LEACH_DOWN( sb_.don_sbl[sbl], sb_.don_sbl[sbl_plus], leach_fact_sbl);
80  LEACH_DOWN( sb_.doc_sbl[sbl], sb_.doc_sbl[sbl_plus], leach_fact_sbl);
81  LEACH_DOWN( sb_.co2_sbl[sbl], sb_.co2_sbl[sbl_plus], leach_fact_sbl);
82  LEACH_DOWN( sb_.so4_sbl[sbl], sb_.so4_sbl[sbl_plus], leach_fact_sbl);
83  LEACH_DOWN( sb_.ni_sbl[sbl], sb_.ni_sbl[sbl_plus], leach_fact_sbl);
84  }
85  }
86 
87  /************************/
88  /* Soil water transport */
89  /************************/
90 
91  if ( cbm::flt_greater_zero( waterflux_sl[0]) &&
92  cbm::flt_greater_zero( v_water_sl[0]))
93  {
94  size_t const sl( 0);
95  size_t const sl_plus( 1);
96 
97  double const leach_fact( cbm::bound_min( 0.0, waterflux_sl[sl] / v_water_sl[sl]));
98 
99  double const leach_fact_nh4( cbm::bound_max( leach_fact * sipar_.RETNH4(), 0.9999));
100  double const leach_fact_no3( cbm::bound_max( leach_fact * sipar_.RETNO3(), 0.9999));
101  double const leach_fact_doc( cbm::bound_max( leach_fact * sipar_.RETDOC(), 0.9999));
102  double const leach_fact_mic( cbm::bound_max( leach_fact * sipar_.METRX_RET_MICROBES(), 0.9999));
103  double const leach_fact_lit( cbm::bound_max( leach_fact * sipar_.METRX_RET_LITTER(), 0.9999));
104  double const leach_fact_hum( cbm::bound_max( leach_fact * sipar_.METRX_RET_HUMUS(), 0.9999));
105  double const leach_fact_dissolved_gases( cbm::bound_max( leach_fact, 0.9999));
106 
107  accumulated_n_aorg_leaching_sl[sl] += sc_.N_aorg_sl[sl] * leach_fact_mic;
108  LEACH_DOWN( sc_.C_aorg_sl[sl], sc_.C_aorg_sl[sl_plus], leach_fact_mic);
109  LEACH_DOWN( sc_.N_aorg_sl[sl], sc_.N_aorg_sl[sl_plus], leach_fact_mic);
110 
111  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]));
112  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]));
113  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]));
114 
115  if( n_micro_1_sl[sl] > MeTrX_get_micro_n_decay_max( n_micro_1_sl[sl]) )
116  {
117  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;
118  }
119  if( n_micro_2_sl[sl] > MeTrX_get_micro_n_decay_max( n_micro_2_sl[sl]) )
120  {
121  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;
122  }
123  if( n_micro_3_sl[sl] > MeTrX_get_micro_n_decay_max( n_micro_3_sl[sl]) )
124  {
125  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;
126  }
127  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]));
128  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]));
129  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]));
130 
131  LEACH_DOWN( sc_.C_lit1_sl[sl], sc_.C_lit1_sl[sl_plus], leach_fact_lit);
132  LEACH_DOWN( sc_.C_lit2_sl[sl], sc_.C_lit2_sl[sl_plus], leach_fact_lit);
133  LEACH_DOWN( sc_.C_lit3_sl[sl], sc_.C_lit3_sl[sl_plus], leach_fact_lit);
134 
135  accumulated_n_litter_leaching_sl[sl] += (sc_.N_lit1_sl[sl] + sc_.N_lit2_sl[sl] + sc_.N_lit3_sl[sl]) * leach_fact_lit;
136  LEACH_DOWN( sc_.N_lit1_sl[sl], sc_.N_lit1_sl[sl_plus], leach_fact_lit);
137  LEACH_DOWN( sc_.N_lit2_sl[sl], sc_.N_lit2_sl[sl_plus], leach_fact_lit);
138  LEACH_DOWN( sc_.N_lit3_sl[sl], sc_.N_lit3_sl[sl_plus], leach_fact_lit);
139 
140  LEACH_DOWN( c_humus_1_sl[sl], c_humus_1_sl[sl_plus], leach_fact_hum);
141  LEACH_DOWN( c_humus_2_sl[sl], c_humus_2_sl[sl_plus], leach_fact_hum);
142  LEACH_DOWN( c_humus_3_sl[sl], c_humus_3_sl[sl_plus], leach_fact_hum);
143 
144  accumulated_n_humus_1_leaching_sl[sl] += n_humus_1_sl[sl] * leach_fact_hum;
145  accumulated_n_humus_2_leaching_sl[sl] += n_humus_2_sl[sl] * leach_fact_hum;
146  accumulated_n_humus_3_leaching_sl[sl] += n_humus_3_sl[sl] * leach_fact_hum;
147  LEACH_DOWN( n_humus_1_sl[sl], n_humus_1_sl[sl_plus], leach_fact_hum);
148  LEACH_DOWN( n_humus_2_sl[sl], n_humus_2_sl[sl_plus], leach_fact_hum);
149  LEACH_DOWN( n_humus_3_sl[sl], n_humus_3_sl[sl_plus], leach_fact_hum);
150 
151  accumulated_n_nh4_leaching_sl[sl] += (nh4_ae_sl[sl] + nh4_an_sl[sl] + sc_.coated_nh4_sl[sl]) * leach_fact_nh4;
152  accumulated_n_nh3_leaching_sl[sl] += sc_.nh3_liq_sl[sl] * leach_fact_doc;
153  accumulated_n_urea_leaching_sl[sl] += sc_.urea_sl[sl] * leach_fact_doc;
154  LEACH_DOWN( nh4_ae_sl[sl], nh4_ae_sl[sl_plus], leach_fact_nh4);
155  LEACH_DOWN( nh4_an_sl[sl], nh4_an_sl[sl_plus], leach_fact_nh4);
156  LEACH_DOWN( sc_.coated_nh4_sl[sl], sc_.coated_nh4_sl[sl_plus], leach_fact_nh4);
157  LEACH_DOWN( sc_.nh3_liq_sl[sl], sc_.nh3_liq_sl[sl_plus], leach_fact_doc);
158  LEACH_DOWN( sc_.urea_sl[sl], sc_.urea_sl[sl_plus], leach_fact_doc);
159 
160  sc_.accumulated_n_no3_leaching_sl[sl] += (no3_ae_sl[sl] + no3_an_sl[sl]) * leach_fact_no3;
161  LEACH_DOWN( no3_ae_sl[sl], no3_ae_sl[sl_plus], leach_fact_no3);
162  LEACH_DOWN( no3_an_sl[sl], no3_an_sl[sl_plus], leach_fact_no3);
163 
164  accumulated_n_don_leaching_sl[sl] += (don_ae_sl[sl] + don_an_sl[sl]) * leach_fact_doc;
165  LEACH_DOWN( don_ae_sl[sl], don_ae_sl[sl_plus], leach_fact_doc);
166  LEACH_DOWN( don_an_sl[sl], don_an_sl[sl_plus], leach_fact_doc);
167  LEACH_DOWN( sc_.doc_sl[sl], sc_.doc_sl[sl_plus], leach_fact_doc);
168  LEACH_DOWN( sc_.an_doc_sl[sl], sc_.an_doc_sl[sl_plus], leach_fact_doc);
169  LEACH_DOWN( ae_acetate_sl[sl], ae_acetate_sl[sl_plus], leach_fact_doc);
170  LEACH_DOWN( an_acetate_sl[sl], an_acetate_sl[sl_plus], leach_fact_doc);
171 
172  accumulated_n_no_leaching_sl[sl] += (no_liq_sl[sl]+an_no_liq_sl[sl]) * leach_fact_dissolved_gases;
173  accumulated_n_n2o_leaching_sl[sl] += (n2o_liq_sl[sl]+an_n2o_liq_sl[sl]) * leach_fact_dissolved_gases;
174  LEACH_DOWN( no_liq_sl[sl], no_liq_sl[sl_plus], leach_fact_dissolved_gases);
175  LEACH_DOWN( an_no_liq_sl[sl], an_no_liq_sl[sl_plus], leach_fact_dissolved_gases);
176  LEACH_DOWN( n2o_liq_sl[sl], n2o_liq_sl[sl_plus], leach_fact_dissolved_gases);
177  LEACH_DOWN( an_n2o_liq_sl[sl], an_n2o_liq_sl[sl_plus], leach_fact_dissolved_gases);
178 
179  LEACH_DOWN( ch4_liq_sl[sl], ch4_liq_sl[sl_plus], leach_fact_dissolved_gases);
180  LEACH_DOWN( co2_liq_sl[sl], co2_liq_sl[sl_plus], leach_fact_dissolved_gases);
181  LEACH_DOWN( o2_liq_sl[sl], o2_liq_sl[sl_plus], leach_fact_dissolved_gases);
182 
183  LEACH_DOWN( sc_.so4_sl[sl], sc_.so4_sl[sl_plus], leach_fact_no3);
184  LEACH_DOWN( sc_.ni_sl[sl], sc_.ni_sl[sl_plus], leach_fact_doc);
185  }
186 
187  for( size_t sl = 1; sl < sl_.soil_layer_cnt()-1; ++sl)
188  {
189  if ( !cbm::flt_equal_zero( waterflux_sl[sl]) &&
190  cbm::flt_greater_zero( v_water_sl[sl]))
191  {
192  size_t sl_minus( sl - 1);
193  size_t sl_plus( sl + 1);
194 
195  double const leach_fact( waterflux_sl[sl] / v_water_sl[sl]);
196 
197  double const leach_fact_nh4( cbm::bound(-0.9999, leach_fact * sipar_.RETNH4(), 0.9999));
198  double const leach_fact_no3( cbm::bound(-0.9999, leach_fact * sipar_.RETNO3(), 0.9999));
199  double const leach_fact_doc( cbm::bound(-0.9999, leach_fact * sipar_.RETDOC(), 0.9999));
200  double const leach_fact_mic( cbm::bound(-0.9999, leach_fact * sipar_.METRX_RET_MICROBES(), 0.9999));
201  double const leach_fact_lit( cbm::bound(-0.9999, leach_fact * sipar_.METRX_RET_LITTER(), 0.9999));
202  double const leach_fact_hum( cbm::bound(-0.9999, leach_fact * sipar_.METRX_RET_HUMUS(), 0.9999));
203  double const leach_fact_dissolved_gases( cbm::bound(-0.9999, leach_fact, 0.9999));
204 
205  accumulated_n_aorg_leaching_sl[sl] += sc_.N_aorg_sl[sl] * leach_fact_mic;
206  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);
207  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);
208 
209  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]));
210  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]));
211  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]));
212 
213  if( n_micro_1_sl[sl] > MeTrX_get_micro_n_decay_max( n_micro_1_sl[sl]) )
214  {
215  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;
216  }
217  if( n_micro_2_sl[sl] > MeTrX_get_micro_n_decay_max( n_micro_2_sl[sl]) )
218  {
219  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;
220  }
221  if( n_micro_3_sl[sl] > MeTrX_get_micro_n_decay_max( n_micro_3_sl[sl]) )
222  {
223  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;
224  }
225  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]));
226  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]));
227  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]));
228 
229  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);
230  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);
231  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);
232 
233  accumulated_n_litter_leaching_sl[sl] += (sc_.N_lit1_sl[sl]+sc_.N_lit2_sl[sl]+sc_.N_lit3_sl[sl]) * leach_fact_lit;
234  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);
235  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);
236  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);
237 
238  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);
239  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);
240  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);
241 
242  accumulated_n_humus_1_leaching_sl[sl] += n_humus_1_sl[sl] * leach_fact_hum;
243  accumulated_n_humus_2_leaching_sl[sl] += n_humus_2_sl[sl] * leach_fact_hum;
244  accumulated_n_humus_3_leaching_sl[sl] += n_humus_3_sl[sl] * leach_fact_hum;
245  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);
246  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);
247  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);
248 
249  accumulated_n_nh4_leaching_sl[sl] += (nh4_ae_sl[sl] + nh4_an_sl[sl] + sc_.coated_nh4_sl[sl]) * leach_fact_nh4;
250  accumulated_n_nh3_leaching_sl[sl] += sc_.nh3_liq_sl[sl] * leach_fact_doc;
251  accumulated_n_urea_leaching_sl[sl] += sc_.urea_sl[sl] * leach_fact_doc;
252  transport_.leach_up_and_down( nh4_ae_sl[sl_minus], nh4_ae_sl[sl], nh4_ae_sl[sl_plus], leach_fact_nh4);
253  transport_.leach_up_and_down( nh4_an_sl[sl_minus], nh4_an_sl[sl], nh4_an_sl[sl_plus], leach_fact_nh4);
254  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);
255  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);
256  transport_.leach_up_and_down( sc_.urea_sl[sl_minus], sc_.urea_sl[sl], sc_.urea_sl[sl_plus], leach_fact_doc);
257 
258  sc_.accumulated_n_no3_leaching_sl[sl] += (no3_ae_sl[sl]+no3_an_sl[sl]) * leach_fact_no3;
259  transport_.leach_up_and_down( no3_ae_sl[sl_minus], no3_ae_sl[sl], no3_ae_sl[sl_plus], leach_fact_no3);
260  transport_.leach_up_and_down( no3_an_sl[sl_minus], no3_an_sl[sl], no3_an_sl[sl_plus], leach_fact_no3);
261 
262  accumulated_n_don_leaching_sl[sl] += (don_ae_sl[sl] + don_an_sl[sl]) * leach_fact_doc;
263  transport_.leach_up_and_down( don_ae_sl[sl_minus], don_ae_sl[sl], don_ae_sl[sl_plus], leach_fact_doc);
264  transport_.leach_up_and_down( don_an_sl[sl_minus], don_an_sl[sl], don_an_sl[sl_plus], leach_fact_doc);
265  transport_.leach_up_and_down( sc_.doc_sl[sl_minus], sc_.doc_sl[sl], sc_.doc_sl[sl_plus], leach_fact_doc);
266  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);
267  transport_.leach_up_and_down( ae_acetate_sl[sl_minus], ae_acetate_sl[sl], ae_acetate_sl[sl_plus], leach_fact_doc);
268  transport_.leach_up_and_down( an_acetate_sl[sl_minus], an_acetate_sl[sl], an_acetate_sl[sl_plus], leach_fact_doc);
269 
270  accumulated_n_no_leaching_sl[sl] += (no_liq_sl[sl]+an_no_liq_sl[sl]) * leach_fact_dissolved_gases;
271  accumulated_n_n2o_leaching_sl[sl] += (n2o_liq_sl[sl]+an_n2o_liq_sl[sl]) * leach_fact_dissolved_gases;
272  transport_.leach_up_and_down( no_liq_sl[sl_minus], no_liq_sl[sl], no_liq_sl[sl_plus], leach_fact_dissolved_gases);
273  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);
274  transport_.leach_up_and_down( n2o_liq_sl[sl_minus], n2o_liq_sl[sl], n2o_liq_sl[sl_plus], leach_fact_dissolved_gases);
275  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);
276 
277  transport_.leach_up_and_down( ch4_liq_sl[sl_minus], ch4_liq_sl[sl], ch4_liq_sl[sl_plus], leach_fact_dissolved_gases);
278  transport_.leach_up_and_down( co2_liq_sl[sl_minus], co2_liq_sl[sl], co2_liq_sl[sl_plus], leach_fact_dissolved_gases);
279  transport_.leach_up_and_down( o2_liq_sl[sl_minus], o2_liq_sl[sl], o2_liq_sl[sl_plus], leach_fact_dissolved_gases);
280 
281  transport_.leach_up_and_down( sc_.so4_sl[sl_minus], sc_.so4_sl[sl], sc_.so4_sl[sl_plus], leach_fact_no3);
282  transport_.leach_up_and_down( sc_.ni_sl[sl_minus], sc_.ni_sl[sl], sc_.ni_sl[sl_plus], leach_fact_doc);
283  }
284  }
285 
286  size_t sl( sl_.soil_layer_cnt()-1);
287 
288  if ( !cbm::flt_equal_zero( waterflux_sl[sl]) &&
289  cbm::flt_greater_zero( v_water_sl[sl]))
290  {
291  double dummy_out( 0.0); //dummy for substances that are not balanced (no accumulated leaching variable exists)
292  size_t sl_minus( sl_.soil_layer_cnt()-2);
293 
294  double const leach_fact( waterflux_sl[sl] / v_water_sl[sl]);
295 
296  double const leach_fact_nh4( cbm::bound(-0.9999, leach_fact * sipar_.RETNH4(), 0.9999));
297  double const leach_fact_no3( cbm::bound(-0.9999, leach_fact * sipar_.RETNO3(), 0.9999));
298  double const leach_fact_doc( cbm::bound(-0.9999, leach_fact * sipar_.RETDOC(), 0.9999));
299  double const leach_fact_mic( cbm::bound(-0.9999, leach_fact * sipar_.METRX_RET_MICROBES(), 0.9999));
300  double const leach_fact_lit( cbm::bound(-0.9999, leach_fact * sipar_.METRX_RET_LITTER(), 0.9999));
301  double const leach_fact_hum( cbm::bound(-0.9999, leach_fact * sipar_.METRX_RET_HUMUS(), 0.9999));
302  double const leach_fact_dissolved_gases( cbm::bound(-0.9999, leach_fact, 0.9999));
303 
304  accumulated_n_aorg_leaching_sl[sl] += sc_.N_aorg_sl[sl] * leach_fact_mic;
305  transport_.leach_up_and_down( sc_.C_aorg_sl[sl_minus], sc_.C_aorg_sl[sl], sc_.accumulated_doc_leach, leach_fact_mic);
306  transport_.leach_up_and_down( sc_.N_aorg_sl[sl_minus], sc_.N_aorg_sl[sl], sc_.accumulated_don_leach, leach_fact_mic);
307 
308  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]));
309  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]));
310  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]));
311 
312  if( n_micro_1_sl[sl] > MeTrX_get_micro_n_decay_max( n_micro_1_sl[sl]) )
313  {
314  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;
315  }
316  if( n_micro_2_sl[sl] > MeTrX_get_micro_n_decay_max( n_micro_2_sl[sl]) )
317  {
318  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;
319  }
320  if( n_micro_3_sl[sl] > MeTrX_get_micro_n_decay_max( n_micro_3_sl[sl]) )
321  {
322  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;
323  }
324  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]));
325  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]));
326  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]));
327 
328  transport_.leach_up_and_down( sc_.C_lit1_sl[sl_minus], sc_.C_lit1_sl[sl], sc_.accumulated_doc_leach, leach_fact_lit);
329  transport_.leach_up_and_down( sc_.C_lit2_sl[sl_minus], sc_.C_lit2_sl[sl], sc_.accumulated_doc_leach, leach_fact_lit);
330  transport_.leach_up_and_down( sc_.C_lit3_sl[sl_minus], sc_.C_lit3_sl[sl], sc_.accumulated_doc_leach, leach_fact_lit);
331 
332  accumulated_n_litter_leaching_sl[sl] += (sc_.N_lit1_sl[sl]+sc_.N_lit2_sl[sl]+sc_.N_lit3_sl[sl]) * leach_fact_lit;
333  transport_.leach_up_and_down( sc_.N_lit1_sl[sl_minus], sc_.N_lit1_sl[sl], sc_.accumulated_don_leach, leach_fact_lit);
334  transport_.leach_up_and_down( sc_.N_lit2_sl[sl_minus], sc_.N_lit2_sl[sl], sc_.accumulated_don_leach, leach_fact_lit);
335  transport_.leach_up_and_down( sc_.N_lit3_sl[sl_minus], sc_.N_lit3_sl[sl], sc_.accumulated_don_leach, leach_fact_lit);
336 
337  transport_.leach_up_and_down( c_humus_1_sl[sl_minus], c_humus_1_sl[sl], sc_.accumulated_doc_leach, leach_fact_hum);
338  transport_.leach_up_and_down( c_humus_2_sl[sl_minus], c_humus_2_sl[sl], sc_.accumulated_doc_leach, leach_fact_hum);
339  transport_.leach_up_and_down( c_humus_3_sl[sl_minus], c_humus_3_sl[sl], sc_.accumulated_doc_leach, leach_fact_hum);
340 
341  accumulated_n_humus_1_leaching_sl[sl] += n_humus_1_sl[sl] * leach_fact_hum;
342  accumulated_n_humus_2_leaching_sl[sl] += n_humus_2_sl[sl] * leach_fact_hum;
343  accumulated_n_humus_3_leaching_sl[sl] += n_humus_3_sl[sl] * leach_fact_hum;
344  transport_.leach_up_and_down( n_humus_1_sl[sl_minus], n_humus_1_sl[sl], sc_.accumulated_don_leach, leach_fact_hum);
345  transport_.leach_up_and_down( n_humus_2_sl[sl_minus], n_humus_2_sl[sl], sc_.accumulated_don_leach, leach_fact_hum);
346  transport_.leach_up_and_down( n_humus_2_sl[sl_minus], n_humus_2_sl[sl], sc_.accumulated_don_leach, leach_fact_hum);
347 
348  accumulated_n_nh4_leaching_sl[sl] += (nh4_ae_sl[sl] + nh4_an_sl[sl] + sc_.coated_nh4_sl[sl]) * leach_fact_nh4;
349  accumulated_n_nh3_leaching_sl[sl] += sc_.nh3_liq_sl[sl] * leach_fact_doc;
350  accumulated_n_urea_leaching_sl[sl] += sc_.urea_sl[sl] * leach_fact_doc;
351  transport_.leach_up_and_down( nh4_ae_sl[sl_minus], nh4_ae_sl[sl], sc_.accumulated_nh4_leach, leach_fact_nh4);
352  transport_.leach_up_and_down( nh4_an_sl[sl_minus], nh4_an_sl[sl], sc_.accumulated_nh4_leach, leach_fact_nh4);
353  transport_.leach_up_and_down( sc_.coated_nh4_sl[sl_minus], sc_.coated_nh4_sl[sl], sc_.accumulated_nh4_leach, leach_fact_nh4);
354  transport_.leach_up_and_down( sc_.nh3_liq_sl[sl_minus], sc_.nh3_liq_sl[sl], day_leach_nh3, leach_fact_doc);
355  transport_.leach_up_and_down( sc_.urea_sl[sl_minus], sc_.urea_sl[sl], day_leach_urea, leach_fact_doc);
356 
357  sc_.accumulated_n_no3_leaching_sl[sl] += (no3_ae_sl[sl]+no3_an_sl[sl]) * leach_fact_no3;
358  transport_.leach_up_and_down( no3_ae_sl[sl_minus], no3_ae_sl[sl], sc_.accumulated_no3_leach, leach_fact_no3);
359  transport_.leach_up_and_down( no3_an_sl[sl_minus], no3_an_sl[sl], sc_.accumulated_no3_leach, leach_fact_no3);
360 
361  accumulated_n_don_leaching_sl[sl] += (don_ae_sl[sl] + don_an_sl[sl]) * leach_fact_doc;
362  transport_.leach_up_and_down( don_ae_sl[sl_minus], don_ae_sl[sl], sc_.accumulated_don_leach, leach_fact_doc);
363  transport_.leach_up_and_down( don_an_sl[sl_minus], don_an_sl[sl], sc_.accumulated_don_leach, leach_fact_doc);
364  transport_.leach_up_and_down( sc_.doc_sl[sl_minus], sc_.doc_sl[sl], sc_.accumulated_doc_leach, leach_fact_doc);
365  transport_.leach_up_and_down( sc_.an_doc_sl[sl_minus], sc_.an_doc_sl[sl], sc_.accumulated_doc_leach, leach_fact_doc);
366  transport_.leach_up_and_down( ae_acetate_sl[sl_minus], ae_acetate_sl[sl], sc_.accumulated_doc_leach, leach_fact_doc);
367  transport_.leach_up_and_down( an_acetate_sl[sl_minus], an_acetate_sl[sl], sc_.accumulated_doc_leach, leach_fact_doc);
368 
369  accumulated_n_no_leaching_sl[sl] += (no_liq_sl[sl]+an_no_liq_sl[sl]) * leach_fact_dissolved_gases;
370  accumulated_n_n2o_leaching_sl[sl] += (n2o_liq_sl[sl]+an_n2o_liq_sl[sl]) * leach_fact_dissolved_gases;
371  transport_.leach_up_and_down( no_liq_sl[sl_minus], no_liq_sl[sl], day_leach_no, leach_fact_dissolved_gases);
372  transport_.leach_up_and_down( an_no_liq_sl[sl_minus], an_no_liq_sl[sl], day_leach_no, leach_fact_dissolved_gases);
373  transport_.leach_up_and_down( n2o_liq_sl[sl_minus], n2o_liq_sl[sl], day_leach_n2o, leach_fact_dissolved_gases);
374  transport_.leach_up_and_down( an_n2o_liq_sl[sl_minus], an_n2o_liq_sl[sl], day_leach_n2o, leach_fact_dissolved_gases);
375  transport_.leach_up_and_down( o2_liq_sl[sl_minus], o2_liq_sl[sl], day_leach_o2, leach_fact_dissolved_gases);
376 
377  transport_.leach_up_and_down( ch4_liq_sl[sl_minus], ch4_liq_sl[sl], subdaily_ch4_leach[subdaily_time_step_], leach_fact_dissolved_gases);
378  transport_.leach_up_and_down( co2_liq_sl[sl_minus], co2_liq_sl[sl], subdaily_co2_leach[subdaily_time_step_], leach_fact_dissolved_gases);
379 
380  transport_.leach_up_and_down( sc_.so4_sl[sl_minus], sc_.so4_sl[sl], sc_.accumulated_so4_leach, leach_fact_no3);
381  transport_.leach_up_and_down( sc_.ni_sl[sl_minus], sc_.ni_sl[sl], dummy_out, leach_fact_doc);
382  }
383 }
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().

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

181 {
182  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
183  {
184  double const metabolism_rate( 0.1 * FTS_TOT_);
185 
186  double const mic_12( sc_.C_micro1_sl[sl] + sc_.C_micro2_sl[sl]);
187  double const mic_23( sc_.C_micro2_sl[sl] + sc_.C_micro3_sl[sl]);
188 
189  if ( cbm::flt_greater_zero( mic_12))
190  {
191  double const fact_mic_12( sc_.anvf_sl[sl]);
192  double trans_12( (fact_mic_12 * mic_12 - sc_.C_micro2_sl[sl]) * metabolism_rate);
193  if ( cbm::flt_greater_zero( trans_12))
194  {
195  double const trans_max( cbm::bound_min( 0.0, sc_.C_micro1_sl[sl] - MICRO_C_MIN));
196  trans_12 = cbm::bound_max( trans_12, trans_max);
197  sc_.C_micro1_sl[sl] -= trans_12;
198  sc_.C_micro2_sl[sl] += trans_12;
199  }
200  else
201  {
202  double const trans_max( cbm::bound_min( 0.0, sc_.C_micro2_sl[sl] - MICRO_C_MIN));
203  trans_12 = cbm::bound_max( -trans_12, trans_max);
204  sc_.C_micro2_sl[sl] -= trans_12;
205  sc_.C_micro1_sl[sl] += trans_12;
206  }
207  }
208 
209  if ( cbm::flt_greater_zero( mic_23))
210  {
211  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)));
212  double trans_23( (fact_mic_23 * mic_23 - sc_.C_micro3_sl[sl]) * metabolism_rate);
213  if ( cbm::flt_greater_zero( trans_23))
214  {
215  double const trans_max( cbm::bound_min( 0.0, sc_.C_micro2_sl[sl] - MICRO_C_MIN));
216  trans_23 = cbm::bound_max( trans_23, trans_max);
217  sc_.C_micro2_sl[sl] -= trans_23;
218  sc_.C_micro3_sl[sl] += trans_23;
219  }
220  else
221  {
222  double const trans_max( cbm::bound_min( 0.0, sc_.C_micro3_sl[sl] - MICRO_C_MIN));
223  trans_23 = cbm::bound_max( -trans_23, trans_max);
224  sc_.C_micro3_sl[sl] -= trans_23;
225  sc_.C_micro2_sl[sl] += trans_23;
226  }
227  }
228  }
229  return LDNDC_ERR_OK;
230 }
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:489
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().

838 {
839  double const coated_nh4_sbl_sum( sb_.coated_nh4_sbl.sum());
840  double const coated_nh4_sl_sum( sc_.coated_nh4_sl.sum());
841  double const coated_nh4_sum( coated_nh4_sbl_sum + coated_nh4_sl_sum);
842  if ( !cbm::flt_greater_zero( coated_nh4_sum))
843  { return LDNDC_ERR_OK; }
844 
845  if ( cbm::flt_greater_zero( coated_nh4_sbl_sum))
846  {
847  for (size_t sbl = 0; sbl < sb_.surfacebulk_layer_cnt(); ++sbl)
848  {
849  crnf_.update_crnf( 1.0, mc_temp_sl[0], FTS_TOT_, sb_.nh4_sbl[sbl] / coated_nh4_sum);
850  }
851  }
852 
853  if ( cbm::flt_greater_zero( coated_nh4_sl_sum))
854  {
855  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
856  {
857  crnf_.update_crnf( MeTrX_get_wfps( sl), mc_temp_sl[sl], FTS_TOT_, sc_.coated_nh4_sl[sl] / coated_nh4_sum);
858  }
859  }
860 
861  double coated_nh4_release( crnf_.get_crnf_release( coated_nh4_sum));
862  if ( !cbm::flt_greater_zero( coated_nh4_release))
863  { return LDNDC_ERR_OK; }
864 
865  double const scale( coated_nh4_release / coated_nh4_sum);
866 
867  if ( cbm::flt_greater( scale, 0.99))
868  {
869  if ( cbm::flt_greater_zero( coated_nh4_sbl_sum))
870  {
871  for (size_t sbl = 0; sbl < sb_.surfacebulk_layer_cnt(); ++sbl)
872  {
873  sb_.nh4_sbl[sbl] += sb_.coated_nh4_sbl[sbl];
874  sb_.coated_nh4_sbl[sbl] = 0.0;
875  }
876  }
877 
878  if ( cbm::flt_greater_zero( coated_nh4_sl_sum))
879  {
880  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
881  {
882  nh4_ae_sl[sl] += sc_.coated_nh4_sl[sl] * (1.0 - sc_.anvf_sl[sl]);
883  nh4_an_sl[sl] += sc_.coated_nh4_sl[sl] * sc_.anvf_sl[sl];
884  sc_.coated_nh4_sl[sl] = 0.0;
885  }
886  }
887  }
888  else
889  {
890  if ( cbm::flt_greater_zero( coated_nh4_sbl_sum))
891  {
892  for (size_t sbl = 0; sbl < sb_.surfacebulk_layer_cnt(); ++sbl)
893  {
894  if ( cbm::flt_greater_zero( sb_.coated_nh4_sbl[sbl]))
895  {
896  double const n_transform( scale * sb_.coated_nh4_sbl[sbl]);
897  sb_.coated_nh4_sbl[sbl] -= n_transform;
898  sb_.nh4_sbl[sbl] += n_transform;
899  }
900  }
901  }
902 
903  if ( cbm::flt_greater_zero( coated_nh4_sl_sum))
904  {
905  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
906  {
907  if ( cbm::flt_greater_zero( sc_.coated_nh4_sl[sl]))
908  {
909  double const n_transform( scale * sc_.coated_nh4_sl[sl]);
910  sc_.coated_nh4_sl[sl] -= n_transform;
911  nh4_ae_sl[sl] += n_transform * (1.0 - sc_.anvf_sl[sl]);
912  nh4_an_sl[sl] += n_transform * sc_.anvf_sl[sl];
913  }
914  }
915  }
916  }
917 
918  return LDNDC_ERR_OK;
919 }
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().

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

504 {
505  for ( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
506  {
507  sc_.ph_sl[sl] = MeTrX_get_ph_sl( sl);
508  }
509 }
double MeTrX_get_ph_sl(size_t)
Returns dynamic pH-value of given soil layer.
Definition: soilchemistry-metrx-physics-chemistry.cpp:481
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().

156 {
157  /*****************************/
158  /* Water-, Ice-, Air-Content */
159  /*****************************/
160 
161  for (size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
162  {
163  double const v_ice_old( v_ice_sl[sl]);
164  double const v_pores( sc_.h_sl[sl] * sc_.poro_sl[sl]);
165  v_water_sl[sl] = cbm::bound_min( 0.01 * v_pores, wc_.wc_sl[sl] * sc_.h_sl[sl]);
166  v_ice_sl[sl] = cbm::bound_min( 0.0, wc_.ice_sl[sl] * sc_.h_sl[sl]);
167  v_air_sl[sl] = cbm::bound_min( 0.05 * v_pores, v_pores - v_water_sl[sl] - v_ice_sl[sl]);
168 
169  pore_connectivity_sl[sl] = cbm::bound(
170  0.001,
171  1.0 - exp( -sipar_.METRX_F_CONNECTIVITY_2() *
172  ((v_air_sl[sl] / sc_.h_sl[sl]) - sipar_.METRX_F_CONNECTIVITY_1())),
173  0.999);
174 
175  if ( have_freeze_thaw)
176  {
177  if ( cbm::flt_greater( v_ice_sl[sl], v_ice_old))
178  {
179  double const freeze_fraction( (v_ice_sl[sl] - v_ice_old) / v_ice_sl[sl]);
180 
181  double const delta_doc( freeze_fraction * (sc_.doc_sl[sl] + sc_.an_doc_sl[sl]));
182  doc_ice_sl[sl] += delta_doc;
183  sc_.doc_sl[sl] *= (1.0 - freeze_fraction);
184  sc_.an_doc_sl[sl] *= (1.0 - freeze_fraction);
185 
186  double const delta_acetate( freeze_fraction * (ae_acetate_sl[sl] + an_acetate_sl[sl]));
187  acetate_ice_sl[sl] += delta_acetate;
188  ae_acetate_sl[sl] *= (1.0 - freeze_fraction);
189  an_acetate_sl[sl] *= (1.0 - freeze_fraction);
190 
191  double const delta_no3( freeze_fraction * (no3_ae_sl[sl] + no3_an_sl[sl]));
192  no3_ice_sl[sl] += delta_no3;
193  no3_ae_sl[sl] *= (1.0 - freeze_fraction);
194  no3_an_sl[sl] *= (1.0 - freeze_fraction);
195 
196  double const delta_nh4( freeze_fraction * (nh4_ae_sl[sl] + nh4_an_sl[sl]));
197  nh4_ice_sl[sl] += delta_nh4;
198  nh4_ae_sl[sl] *= (1.0 - freeze_fraction);
199  nh4_an_sl[sl] *= (1.0 - freeze_fraction);
200 
201  double const delta_don( freeze_fraction * (don_ae_sl[sl] + don_an_sl[sl]));
202  don_ice_sl[sl] += delta_don;
203  don_ae_sl[sl] *= (1.0 - freeze_fraction);
204  don_an_sl[sl] *= (1.0 - freeze_fraction);
205  }
206  else if ( cbm::flt_less( v_ice_sl[sl], v_ice_old))
207  {
208  double const melt_fraction( (v_ice_old > 0.0)? (v_ice_old - v_ice_sl[sl]) / v_ice_old : 1.0);
209 
210  double const delta_doc( melt_fraction * doc_ice_sl[sl]);
211  sc_.doc_sl[sl] += delta_doc * (1.0 - sc_.anvf_sl[sl]);
212  sc_.an_doc_sl[sl] += delta_doc * sc_.anvf_sl[sl];
213  doc_ice_sl[sl] *= (1.0 - melt_fraction);
214 
215  double const delta_acetate( melt_fraction * acetate_ice_sl[sl]);
216  ae_acetate_sl[sl] += delta_acetate * (1.0 - sc_.anvf_sl[sl]);
217  an_acetate_sl[sl] += delta_acetate * sc_.anvf_sl[sl];
218  acetate_ice_sl[sl] *= (1.0 - melt_fraction);
219 
220  double const delta_no3( melt_fraction * no3_ice_sl[sl]);
221  no3_ae_sl[sl] += delta_no3 * (1.0 - sc_.anvf_sl[sl]);
222  no3_an_sl[sl] += delta_no3 * sc_.anvf_sl[sl];
223  no3_ice_sl[sl] *= (1.0 - melt_fraction);
224 
225  double const delta_nh4( melt_fraction * nh4_ice_sl[sl]);
226  nh4_ae_sl[sl] += delta_nh4 * (1.0 - sc_.anvf_sl[sl]);
227  nh4_an_sl[sl] += delta_nh4 * sc_.anvf_sl[sl];
228  nh4_ice_sl[sl] *= (1.0 - melt_fraction);
229 
230  double const delta_don( melt_fraction * don_ice_sl[sl]);
231  don_ae_sl[sl] += delta_don * (1.0 - sc_.anvf_sl[sl]);
232  don_an_sl[sl] += delta_don * sc_.anvf_sl[sl];
233  don_ice_sl[sl] *= (1.0 - melt_fraction);
234  }
235  }
236  }
237 
238  size_t sl_max( sl_.soil_layer_cnt()-1);
239  for (size_t sl = 0; sl < sl_max; ++sl)
240  {
241  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]);
242  interface_delta_x_air_sl[sl] = interface_air_sl[sl] / delta_x[sl];
243  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];
244  interface_delta_x_soil_sl[sl] = 1.0;
245  }
246  interface_air_sl[sl_max] = v_air_sl[sl_max]/sc_.h_sl[sl_max];
247  interface_delta_x_air_sl[sl_max] = interface_air_sl[sl_max] / delta_x[sl_max];
248  interface_delta_x_water_sl[sl_max] = v_water_sl[sl_max]/sc_.h_sl[sl_max] / delta_x[sl_max];
249  interface_delta_x_soil_sl[sl_max] = 1.0;
250 
251 
252  double interface_delta_x_atm_soil( 0.0);
253  double interface_delta_x_fl_soil( 0.0);
254  double interface_delta_x_sbl_soil( 0.0);
255 
256  if ( have_water_table)
257  {
258  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]));
259  }
260  else
261  {
262  /* Set atmospheric Dirichlet boundary condition at ground level */
263  interface_delta_x_atm_soil = (cbm::harmonic_mean2( 1.0, v_air_sl[0]/sc_.h_sl[0]) / (0.5 * sc_.h_sl[0]));
264  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]));
265  }
266 
267 
268 
269  /************************************/
270  /* Effective Diffusion Coefficients */
271  /************************************/
272 
273  /* Plant mediated diffusion */
274 
275  for ( PlantIterator vt = this->m_veg->begin(); vt != this->m_veg->end(); ++vt)
276  {
277  MoBiLE_Plant *p = *vt;
278  if ( cbm::flt_greater_zero( p->root_tc))
279  {
280  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
281  {
282  D_eff_plant_sl[sl] = (p->root_tc * p->fFrt_sl[sl]);
283  }
284  have_plant_diffusion = true;
285  }
286  else
287  {
288  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
289  {
290  D_eff_plant_sl[sl] = 0.0;
291  }
292  have_plant_diffusion = false;
293  }
294  }
295 
296 
297  /* Soil diffusion */
298 
299  /* Effective diffusion coefficients relates to the tortuosity of the soil matrix.
300  * Formular is taken from Lai, S.H., J.M. Tiedje, and A.E. Erickson. 1976.
301  * In situ measurement of gas diffusion coefficient in soils, Soil Sci. Soc. Am. J., 40:3–6
302  * tortuosity = theta^(7/3)
303  * theta refers to soil gas content: volume_gas / volume_soil
304  *
305  * Stone content is considered in order to derive characteristic gas content for soil matrix
306  * only, i.e., excluding the stone fraction of the soil. Stone fractions are implicitly incorporated into
307  * the gaseous diffusion by the reduction of the diffusive interface area between soil layers
308  */
309  if ( d_eff_method == "parameter")
310  {
311  for (size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
312  {
313  double const air_content( v_air_sl[sl] / (sc_.h_sl[sl] * (1.0 - sc_.stone_frac_sl[sl])));
314  double const d_eff( d_eff_air_a( 7.0/3.0, air_content)
315  * pow((mc_temp_sl[sl] + cbm::D_IN_K) / TNORM, sipar_.TEXP())) ;
316 
317  /* Empirical reduction of gaseous diffsuion */
318  D_eff_air_sl[sl] = cbm::bound_max( sipar_.METRX_D_EFF_REDUCTION() * d_eff * sc_.till_effect_sl[sl], 1.0);
319  }
320  }
321  else if ( d_eff_method == "millington_and_quirk_1961")
322  {
323  for (size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
324  {
325  double const air_content( v_air_sl[sl] / (sc_.h_sl[sl] * (1.0 - sc_.stone_frac_sl[sl])));
326  double const d_eff( d_eff_air_millington_and_quirk_1961( air_content, sc_.poro_sl[sl])
327  * pow((mc_temp_sl[sl] + cbm::D_IN_K) / TNORM, sipar_.TEXP())) ;
328 
329  /* Empirical reduction of gaseous diffsuion */
330  D_eff_air_sl[sl] = cbm::bound_max( sipar_.METRX_D_EFF_REDUCTION() * d_eff * sc_.till_effect_sl[sl], 1.0);
331  }
332  }
333  else
334  {
335  KLOGERROR("invalid effective diffusion approach: [", d_eff_method,"]");
336  return LDNDC_ERR_FAIL;
337  }
338 
339  for (size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
340  {
341  /* Preliminary set to any value */
342  D_eff_water_sl[sl] = pow( MeTrX_get_wfps( sl), 2.0);
343 
344  //pertubation / earthworms activity decreases with depth and soil water saturation
345  D_eff_dailyturbation_sl[sl] = std::exp( - sc_.depth_sl[sl] / sipar_.METRX_F_PERTUBATION_EXP())
346  * sipar_.METRX_F_PERTUBATION_MIX() * (1.0 - MeTrX_get_wfps( sl));
347  }
348 
349  /*******************************/
350  /* Update transport properties */
351  /*******************************/
352 
353  transport_.update_diffusion( D_eff_plant_sl, D_eff_air_sl,
354  v_air_sl,
355  soil_gas_advection_sl,
356  interface_delta_x_air_sl,
357  interface_delta_x_atm_soil,
358  interface_delta_x_fl_soil,
359  interface_delta_x_sbl_soil,
360  h_wl,
361  have_water_table);
362  transport_.update_advection( interface_air_sl);
363 
364  double const d_wind_scale( 1.0 + (*mc_wind) / ((*mc_wind) + 5.0) * 2.0);
365  transport_.wind_stimulation = d_wind_scale;
366 
367  for ( std::map< std::string , double>::iterator it = sc_.n_subdivision.begin();
368  it != sc_.n_subdivision.end(); )
369  {
370  it->second -= 0.02 * FTS_TOT_;
371  if ( !cbm::flt_greater_zero( it->second))
372  {
373  sc_.n_subdivision.erase( it++);
374  }
375  else{ ++it; }
376  }
377 
378  return LDNDC_ERR_OK;
379 }
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  /* Water layer variables */
116  for (size_t wl = 0; wl < sb_.surfacebulk_layer_cnt(); wl++)
117  {
118  day_ch4_bubbling_wl[wl] = 0.0;
119  }
120 
121  /* Soil layer variables */
122  for (size_t sl = 0; sl < sl_.soil_layer_cnt(); sl++)
123  {
124  plant_o2_consumption_sl[sl] = 0.0;
125 
126  day_nitrify_n2o_sl[sl] = 0.0;
127  day_nit_no2_no3_sl[sl] = 0.0;
128 
129  day_acetate_cons_fe3_sl[sl] = 0.0;
130  day_h2_c_eq_cons_fe3_sl[sl] = 0.0;
131  day_fe2_oxidation_sl[sl] = 0.0;
132 
133  day_acetate_prod_sl[sl] = 0.0;
134 
135  day_ch4_oxidation_sl[sl] = 0.0;
136  day_ch4_bubbling_sl[sl] = 0.0;
137 
138  day_h2_c_eq_prod_sl[sl] = 0.0;
139  day_ch4_production_acetate_sl[sl] = 0.0;
140  day_ch4_production_hydrogen_sl[sl] = 0.0;
141 
142  day_doc_prod_sl[sl] = 0.0;
143  day_denit_factor_c_sl[sl] = 0.0;
144  day_denit_factor_n_sl[sl] = 0.0;
145  }
146 
147  // Groundwater access
148  day_no3_groundwater_access = 0.0;
149 
150  // Mineralisation
151  day_min_n_decomp = 0.0;
152  day_min_n_aorg = 0.0;
153  day_min_n_mic_1 = 0.0;
154  day_min_n_mic_2 = 0.0;
155  day_min_n_mic_3 = 0.0;
156 
157  // Assimilation
158  day_assi_n_mic_1 = 0.0;
159  day_assi_n_mic_2 = 0.0;
160  day_assi_n_mic_3 = 0.0;
161  day_assi_c_mic_1 = 0.0;
162  day_assi_c_mic_2 = 0.0;
163  day_assi_c_mic_3 = 0.0;
164 
165  // Nitrification
166  day_nit_nh4_no2 = 0.0;
167  day_nit_no2_no = 0.0;
168  day_nit_no2_n2o = 0.0;
169  day_nit_no2_no3_sl = 0.0;
170 
171  // Denitrification
172  day_denit_no3_no2 = 0.0;
173  day_denit_no2_no = 0.0;
174  day_denit_no2_n2o = 0.0;
175  day_denit_no2_n2 = 0.0;
176  day_denit_no_n2o = 0.0;
177  day_denit_no_n2 = 0.0;
178  day_denit_n2o_n2 = 0.0;
179  day_chemodenit_no2_no = 0.0;
180 
181  // Respiration / Fermentation / Methanogenesis
182  day_co2_prod_mic_1_growth = 0.0;
183  day_co2_prod_mic_1_maintenance = 0.0;
184  day_co2_prod_mic_2 = 0.0;
185  day_co2_prod_mic_3_acetate_prod = 0.0;
186  day_co2_prod_mic_3_acetate_cons = 0.0;
187  day_co2_prod_ch4_prod = 0.0;
188  day_co2_prod_ch4_cons = 0.0;
189 
190  // Leaching
191  day_leach_o2 = 0.0;
192  day_leach_n2o = 0.0;
193  day_leach_n2 = 0.0;
194  day_leach_no = 0.0;
195  day_leach_nh3 = 0.0;
196  day_leach_urea = 0.0;
197 
198  // litter
199  dC_root_exsudates = 0.0;
200  dC_litter_algae = 0.0;
201 
202  // Decomposition
203  day_decomp_c_lit_1 = 0.0;
204  day_decomp_c_lit_2 = 0.0;
205  day_decomp_c_lit_3 = 0.0;
206  day_decomp_n_lit_1 = 0.0;
207  day_decomp_n_lit_2 = 0.0;
208  day_decomp_n_lit_3 = 0.0;
209  day_decomp_c_hum_1_sl = 0.0;
210  day_decomp_c_hum_2_sl = 0.0;
211  day_decomp_c_hum_3_sl = 0.0;
212  day_decay_c_mic_sl = 0.0;
213  day_decomp_n_hum_1 = 0.0;
214  day_decomp_n_hum_2 = 0.0;
215  day_decomp_n_hum_3 = 0.0;
216 
217  // Humification
218  day_c_humify_doc_hum_1_sl = 0.0;
219  day_c_humify_sol_hum_1_sl = 0.0;
220  day_c_humify_cel_hum_1_sl = 0.0;
221  day_c_humify_lig_hum_1_sl = 0.0;
222  day_c_humify_lig_hum_2_sl = 0.0;
223  day_c_humify_mic_hum_1_sl = 0.0;
224  day_c_humify_mic_hum_2_sl = 0.0;
225  day_c_humify_hum_1_hum_2_sl = 0.0;
226  day_c_humify_hum_2_hum_3_sl = 0.0;
227 
228  // Algae
229  day_n_fix_algae = 0.0;
230  day_c_fix_algae = 0.0;
231 
232  // DOC production
233  day_doc_prod_decomp_litter = 0.0;
234  day_doc_prod_decomp_humus = 0.0;
235  day_doc_prod_decomp_aorg = 0.0;
236 
237  return LDNDC_ERR_OK;
238 }
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  for ( int i = 0; i < 10; ++i)
116  {
117  double c_hum_1( c_humus_1_sl[sl]);
118  double n_hum_1( n_humus_1_sl[sl]);
119  double c_hum_2( c_humus_2_sl[sl]);
120  double n_hum_2( n_humus_2_sl[sl]);
121  double c_hum_3( c_humus_3_sl[sl]);
122  double n_hum_3( n_humus_3_sl[sl]);
123 
124  double const c_tot( c_hum_1 + c_hum_2 + c_hum_3);
125  double const n_tot( n_hum_1 + n_hum_2 + n_hum_3);
126 
127  int spinup_steps_per_year( 12);
128  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()
129  * spinup_delta_c / spinup_steps_per_year);
130  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()
131  * spinup_delta_c / spinup_steps_per_year);
132 
133  double const c_humus_1_tmp( cbm::bound_min( -1.0e-9, spinup_.humify_c_to_humus_1_sl[sl] - delta_c_hum_1)
134  / (spinup_.decompose_hum_1[sl] + spinup_.humify_humus_1_to_humus_2_sl[sl]));
135 
136  double const c_humus_2_tmp( cbm::bound_min( -1.0e-9, spinup_.humify_c_to_humus_2_sl[sl]
137  + spinup_.humify_humus_1_to_humus_2_sl[sl] * c_humus_1_sl[sl]
138  - delta_c_hum_2)
139  / (spinup_.decompose_hum_2[sl] + spinup_.humify_humus_2_to_humus_3_sl[sl]));
140 
141  //change less with time
142  double const fraction( 0.1);
143 
144  //use upper limit for humus pool 1
145  c_humus_1_sl[sl] = cbm::bound_max( c_humus_1_tmp * fraction + c_hum_1 * (1.0 - fraction), 0.2 * c_tot);
146  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]));
147  c_humus_3_sl[sl] = c_tot - c_humus_1_sl[sl] -c_humus_2_sl[sl];
148 
149  double const n_demand_humus_1( c_humus_1_sl[sl] / cn_hum_1_sl[sl]);
150  double const n_demand_humus_2( c_humus_2_sl[sl] / cn_hum_2_sl[sl]);
151  double const n_demand_humus_3( c_humus_3_sl[sl] / cn_hum_3_sl[sl]);
152  double const n_demand_tot( n_demand_humus_1 + n_demand_humus_2 + n_demand_humus_3);
153 
154  accumulated_n_humus_1_spinup_sl[sl] -= n_humus_1_sl[sl];
155  accumulated_n_humus_2_spinup_sl[sl] -= n_humus_2_sl[sl];
156  accumulated_n_humus_3_spinup_sl[sl] -= n_humus_3_sl[sl];
157 
158  n_humus_1_sl[sl] = n_demand_humus_1 / n_demand_tot * n_tot;
159  n_humus_2_sl[sl] = n_demand_humus_2 / n_demand_tot * n_tot;
160  n_humus_3_sl[sl] = n_demand_humus_3 / n_demand_tot * n_tot;
161 
162  accumulated_n_humus_1_spinup_sl[sl] += n_humus_1_sl[sl];
163  accumulated_n_humus_2_spinup_sl[sl] += n_humus_2_sl[sl];
164  accumulated_n_humus_3_spinup_sl[sl] += n_humus_3_sl[sl];
165 
166  //adapt only target cn of recalcitrant pools
167  cn_hum_2_sl[sl] = c_humus_2_sl[sl] / n_humus_2_sl[sl];
168  cn_hum_3_sl[sl] = c_humus_3_sl[sl] / n_humus_3_sl[sl];
169  }
170 
171  spinup_.cn_humus_2_temp_sl[sl] += cn_hum_2_sl[sl];
172  spinup_.cn_humus_3_temp_sl[sl] += cn_hum_3_sl[sl];
173 
174  spinup_.c_humus_1_temp_sl[sl] += c_humus_1_sl[sl];
175  spinup_.c_humus_2_temp_sl[sl] += c_humus_2_sl[sl];
176  spinup_.c_humus_3_temp_sl[sl] += c_humus_3_sl[sl];
177  }
178 
179  spinup_.executed_months_ += 1;
180 
181  if ( spinup_.executed_months_ == spinup_.spinup_months())
182  {
183  double const c_hum_tot( c_humus_1_sl.sum() + c_humus_2_sl.sum() + c_humus_3_sl.sum());
184  double const c_hum_1_acc_tot( spinup_.c_humus_1_temp_sl.sum());
185  double const c_hum_2_acc_tot( spinup_.c_humus_2_temp_sl.sum());
186  double const c_hum_3_acc_tot( spinup_.c_humus_3_temp_sl.sum());
187  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
188  {
189  double const c_hum_acc_tot( c_hum_1_acc_tot + c_hum_2_acc_tot + c_hum_3_acc_tot);
190 
191  double const c_hum_1_tot( c_hum_1_acc_tot / c_hum_acc_tot * c_hum_tot);
192  double const c_hum_2_tot( c_hum_2_acc_tot / c_hum_acc_tot * c_hum_tot);
193  double const c_hum_3_tot( c_hum_3_acc_tot / c_hum_acc_tot * c_hum_tot);
194 
195  c_humus_1_sl[sl] = spinup_.c_humus_1_temp_sl[sl] / c_hum_1_acc_tot * c_hum_1_tot;
196  c_humus_2_sl[sl] = spinup_.c_humus_2_temp_sl[sl] / c_hum_2_acc_tot * c_hum_2_tot;
197  c_humus_3_sl[sl] = spinup_.c_humus_3_temp_sl[sl] / c_hum_3_acc_tot * c_hum_3_tot;
198  }
199 
200  double const c_difference( c_hum_tot - (c_humus_1_sl.sum() + c_humus_2_sl.sum() + c_humus_3_sl.sum()));
201  if ( cbm::flt_greater( c_difference, 1.0e-10))
202  {
203  KLOGERROR( name(),": C-leakage during spinup: ", c_difference*cbm::M2_IN_HA, "[kg C ha-1]");
204  }
205 
206  double const n_old_total( n_humus_1_sl.sum() + n_humus_2_sl.sum() + n_humus_3_sl.sum());
207  double n_new_total( 0.0);
208  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
209  {
210  cn_hum_2_sl[sl] = spinup_.cn_humus_2_temp_sl[sl] / spinup_.executed_months_;
211  cn_hum_3_sl[sl] = spinup_.cn_humus_3_temp_sl[sl] / spinup_.executed_months_;
212 
213  n_new_total += c_humus_1_sl[sl] / cn_hum_1_sl[sl];
214  n_new_total += c_humus_2_sl[sl] / cn_hum_2_sl[sl];
215  n_new_total += c_humus_3_sl[sl] / cn_hum_3_sl[sl];
216  }
217 
218  double const scale( n_old_total / n_new_total);
219  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
220  {
221  accumulated_n_humus_1_spinup_sl[sl] -= n_humus_1_sl[sl];
222  accumulated_n_humus_2_spinup_sl[sl] -= n_humus_2_sl[sl];
223  accumulated_n_humus_3_spinup_sl[sl] -= n_humus_3_sl[sl];
224 
225  n_humus_1_sl[sl] = c_humus_1_sl[sl] / cn_hum_1_sl[sl] * scale;
226  n_humus_2_sl[sl] = c_humus_2_sl[sl] / cn_hum_2_sl[sl] * scale;
227  n_humus_3_sl[sl] = c_humus_3_sl[sl] / cn_hum_3_sl[sl] * scale;
228 
229  accumulated_n_humus_1_spinup_sl[sl] += n_humus_1_sl[sl];
230  accumulated_n_humus_2_spinup_sl[sl] += n_humus_2_sl[sl];
231  accumulated_n_humus_3_spinup_sl[sl] += n_humus_3_sl[sl];
232  }
233 
234  double const n_difference( n_old_total - (n_humus_1_sl.sum() + n_humus_2_sl.sum() + n_humus_3_sl.sum()));
235  if ( cbm::flt_greater( c_difference, 1.0e-10))
236  {
237  KLOGERROR( name(),": N-leakage during spinup: ", n_difference*cbm::M2_IN_HA, "[kg N ha-1]");
238  }
239 
240  spinup_.stop_spinup();
241  }
242 
243  spinup_.reset();
244  }
245 
246  return LDNDC_ERR_OK;
247 }
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().

630 {
631  if ( cbm::flt_greater( sc_.till_effect_sl[0], 1.01))
632  {
633  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
634  {
635  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())));
636  }
637  }
638  else if ( cbm::flt_greater( sc_.till_effect_sl[0], 1.0))
639  {
640  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
641  {
642  sc_.till_effect_sl[sl] = 1.0;
643  }
644  }
645 
646  EventAttributes const * ev_till = NULL;
647  while (( ev_till = this->m_TillEvents.pop()) != NULL)
648  {
649  /***************************/
650  /* tilling depth and layer */
651  /***************************/
652 
653  double till_depth( ev_till->get( "/depth", 0.0));
654  if ( till_depth > 0.5)
655  {
656  KLOGINFO( "tilling depth greater than 0.5m, reset to 0.5m [depth=",till_depth, "m,time=",lclock_ref().to_string(),"]");
657  till_depth = 0.5;
658  }
659 
660  unsigned int till_layer( SL_SURFACE_DISTRIBUTION);
661  if ( cbm::flt_greater_zero( till_depth))
662  {
663  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
664  {
665  if ( sc_.depth_sl[sl] <= till_depth)
666  {
667  sc_.till_effect_sl[sl] = sipar_.METRX_TILL_STIMULATION_1();
668  till_layer = std::max( SL_SURFACE_DISTRIBUTION, sl);
669  }
670  else { break; }
671  }
672  }
673 
674  /**************************************************/
675  /* stubble, root and surface litter incorporation */
676  /**************************************************/
677 
678  sc_.C_lit1_sl[0] += sc_.c_stubble_lit1 + sc_.c_raw_lit_1_sl.sum();
679  sc_.C_lit2_sl[0] += sc_.c_stubble_lit2 + sc_.c_raw_lit_2_sl.sum();
680  sc_.C_lit3_sl[0] += sc_.c_stubble_lit3 + sc_.c_raw_lit_3_sl.sum();
681 
682  sc_.N_lit1_sl[0] += sc_.n_stubble_lit1 + sc_.n_raw_lit_1_sl.sum();
683  sc_.N_lit2_sl[0] += sc_.n_stubble_lit2 + sc_.n_raw_lit_2_sl.sum();
684  sc_.N_lit3_sl[0] += sc_.n_stubble_lit3 + sc_.n_raw_lit_3_sl.sum();
685 
686  accumulated_n_surface_litter_incorporation_via_tilling_sl[0] += sc_.n_stubble_lit1 + sc_.n_stubble_lit2 + sc_.n_stubble_lit3 ;
687  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();
688 
689  sc_.c_stubble_lit1 = sc_.c_stubble_lit2 = sc_.c_stubble_lit3 = 0.0;
690  sc_.n_stubble_lit1 = sc_.n_stubble_lit2 = sc_.n_stubble_lit3 = 0.0;
691 
692  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
693  {
694  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];
695  accumulated_n_aorg_tilling_sl[sl] -= sc_.N_aorg_sl[sl];
696  accumulated_n_humus_1_tilling_sl[sl] -= n_humus_1_sl[sl];
697  accumulated_n_humus_2_tilling_sl[sl] -= n_humus_2_sl[sl];
698  accumulated_n_humus_3_tilling_sl[sl] -= n_humus_3_sl[sl];
699  accumulated_n_no3_tilling_sl[sl] -= no3_ae_sl[sl] + no3_an_sl[sl];
700  accumulated_n_no2_tilling_sl[sl] -= sc_.no2_sl[sl] + sc_.an_no2_sl[sl];
701  accumulated_n_no_tilling_sl[sl] -= no_gas_sl[sl] + no_liq_sl[sl] + an_no_gas_sl[sl] + an_no_liq_sl[sl];
702  accumulated_n_n2o_tilling_sl[sl] -= n2o_gas_sl[sl] + n2o_liq_sl[sl] + an_n2o_gas_sl[sl] + an_n2o_liq_sl[sl];
703  accumulated_n_urea_tilling_sl[sl] -= sc_.urea_sl[sl];
704  accumulated_n_don_tilling_sl[sl] -= don_ae_sl[sl] + don_an_sl[sl];
705  accumulated_n_nh4_tilling_sl[sl] -= nh4_ae_sl[sl] + nh4_an_sl[sl] + sc_.clay_nh4_sl[sl];
706  accumulated_n_nh3_tilling_sl[sl] -= sc_.nh3_gas_sl[sl] + sc_.nh3_liq_sl[sl];
707  accumulated_n_microbes_tilling_sl[sl] -= n_micro_1_sl[sl] + n_micro_2_sl[sl] + n_micro_3_sl[sl];
708  }
709 
710  sc_.c_raw_lit_1_sl = sc_.c_raw_lit_2_sl = sc_.c_raw_lit_3_sl = 0.0;
711  sc_.n_raw_lit_1_sl = sc_.n_raw_lit_2_sl = sc_.n_raw_lit_3_sl = 0.0;
712 
713  /****************************************/
714  /* rearranging soil pools after tilling */
715  /****************************************/
716 
717  lvector_t< double > pool_buf[] =
718  {
719  sc_.fe2_sl, sc_.fe3_sl,
720  sc_.C_lit1_sl, sc_.C_lit2_sl, sc_.C_lit3_sl,
721  sc_.N_lit1_sl, sc_.N_lit2_sl, sc_.N_lit3_sl,
722  sc_.C_aorg_sl, sc_.N_aorg_sl,
723  sc_.C_micro1_sl, sc_.C_micro2_sl, sc_.C_micro3_sl,
724  n_micro_1_sl, n_micro_2_sl, n_micro_3_sl,
725  c_humus_1_sl, c_humus_2_sl, c_humus_3_sl,
726  n_humus_1_sl, n_humus_2_sl, n_humus_3_sl,
727  sc_.doc_sl, sc_.an_doc_sl,
728  ae_acetate_sl, an_acetate_sl,
729  no3_ae_sl, no3_an_sl,
730  sc_.no2_sl, sc_.an_no2_sl,
731  don_ae_sl, don_an_sl,
732  nh4_ae_sl, nh4_an_sl, sc_.clay_nh4_sl,
733  sc_.urea_sl, sc_.nh3_gas_sl, sc_.nh3_liq_sl,
734  no_gas_sl, no_liq_sl, an_no_gas_sl, an_no_liq_sl,
735  n2o_gas_sl, n2o_liq_sl, an_n2o_gas_sl, an_n2o_liq_sl
736  };
737 
738  size_t const pools_cnt( sizeof( pool_buf) / sizeof(lvector_t< double >));
739  for ( size_t k = 0; k < pools_cnt; ++k)
740  {
741  // summing up pool down to tilling depth
742  double pool_sum( pool_buf[k].sum( till_layer) / sc_.depth_sl[till_layer-1]);
743  for ( size_t l = 0; l < till_layer; l++)
744  {
745  pool_buf[k][l] = pool_sum * sc_.h_sl[l];
746  }
747  }
748 
749  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
750  {
751  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];
752  accumulated_n_aorg_tilling_sl[sl] += sc_.N_aorg_sl[sl];
753  accumulated_n_humus_1_tilling_sl[sl] += n_humus_1_sl[sl];
754  accumulated_n_humus_2_tilling_sl[sl] += n_humus_2_sl[sl];
755  accumulated_n_humus_3_tilling_sl[sl] += n_humus_3_sl[sl];
756  accumulated_n_no3_tilling_sl[sl] += no3_ae_sl[sl] + no3_an_sl[sl];
757  accumulated_n_no2_tilling_sl[sl] += sc_.no2_sl[sl] + sc_.an_no2_sl[sl];
758  accumulated_n_no_tilling_sl[sl] += no_gas_sl[sl] + no_liq_sl[sl] + an_no_gas_sl[sl] + an_no_liq_sl[sl];
759  accumulated_n_n2o_tilling_sl[sl] += n2o_gas_sl[sl] + n2o_liq_sl[sl] + an_n2o_gas_sl[sl] + an_n2o_liq_sl[sl];
760  accumulated_n_urea_tilling_sl[sl] += sc_.urea_sl[sl];
761  accumulated_n_don_tilling_sl[sl] += don_ae_sl[sl] + don_an_sl[sl];
762  accumulated_n_nh4_tilling_sl[sl] += nh4_ae_sl[sl] + nh4_an_sl[sl] + sc_.clay_nh4_sl[sl];
763  accumulated_n_nh3_tilling_sl[sl] += sc_.nh3_gas_sl[sl] + sc_.nh3_liq_sl[sl];
764  accumulated_n_microbes_tilling_sl[sl] += n_micro_1_sl[sl] + n_micro_2_sl[sl] + n_micro_3_sl[sl];
765  }
766  }
767 
768  return LDNDC_ERR_OK;
769 }
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().

788 {
789  if ( have_water_table)
790  {
791  double nh4_prod_sum( 0.0);
792  for (size_t wl = 0; wl < sb_.surfacebulk_layer_cnt(); wl++)
793  {
794  double const fact_t( 0.25 * exp(0.0693 * mc_temp_sl[0]));
795  double const nh4_prod( sb_.urea_sbl[wl]
796  * cbm::bound( 0.0,
797  1.0 - exp( -fact_t * 0.02),
798  0.9));
799  sb_.urea_sbl[wl] -= nh4_prod;
800  sb_.nh4_sbl[wl] += nh4_prod;
801  accumulated_n_urea_nh4_hydrolysis_sbl[0] += nh4_prod;
802  nh4_prod_sum += nh4_prod;
803  }
804  ph_delta_urea_wl = cbm::bound( 0.0, nh4_prod_sum / (sipar_.METRX_KMM_PH_INCREASE_FROM_UREA() * wc_.surface_water), PH_MAX-PH_SURFACE_WATER);
805  }
806 
807  for ( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
808  {
809  if ( cbm::flt_greater_zero( sc_.urea_sl[sl]))
810  {
811  double const fact_t( 0.25 * exp(0.0693 * mc_temp_sl[sl]));
812  double const nh4_prod( sc_.urea_sl[sl]
813  * cbm::bound( 0.0,
814  1.0 - exp( -fact_t * 0.02),
815  0.9));
816 
817  sc_.urea_sl[sl] -= nh4_prod;
818  nh4_ae_sl[sl] += nh4_prod * (1.0 - sc_.anvf_sl[sl]);
819  nh4_an_sl[sl] += nh4_prod * sc_.anvf_sl[sl];
820  accumulated_n_urea_nh4_hydrolysis_sl[sl] += nh4_prod;
821  ph_delta_urea_sl[sl] = cbm::bound( 0.0, nh4_prod / (sipar_.METRX_KMM_PH_INCREASE_FROM_UREA() * sc_.h_sl[sl]), PH_MAX-sc_.phi_sl[sl]);
822  }
823  else
824  {
825  sc_.urea_sl[sl] = 0.0;
826  ph_delta_urea_sl[sl] = 0.0;
827  }
828  }
829 }
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:593
lerr_t MeTrX_write_output_subdaily()
Definition: soilchemistry-metrx-output.cpp:935
lerr_t MeTrX_write_output_pools()
Definition: soilchemistry-metrx-output.cpp:620
lerr_t MeTrX_write_output_daily()
Definition: soilchemistry-metrx-output.cpp:76
lerr_t MeTrX_write_output_fluxes()
Definition: soilchemistry-metrx-output.cpp:689
lerr_t MeTrX_write_output_layer_daily()
Definition: soilchemistry-metrx-output.cpp:436
lerr_t MeTrX_write_output_yearly()
Definition: soilchemistry-metrx-output.cpp:392
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 sl_counter( 0);
212  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
213  {
214  double const ni_inhibition( crnf_.get_nitrification_inhibition( sc_.ni_sl[sl]));
215  if ( cbm::flt_greater_zero( ni_inhibition))
216  {
217  sl_counter += 1;
218  nitrification_inhibition += ni_inhibition;
219  }
220  }
221 
222  if ( sl_counter > 0)
223  {
224  nitrification_inhibition /= sl_counter;
225  urease_inhibition /= sl_counter;
226  }
227 
228  double const litter_height( (sl_.soil_layers_in_litter_cnt() > 0) ? sc_.depth_sl[sl_.soil_layers_in_litter_cnt()-1] : 0.0);
229  anvf_avg /= depth_sum;
230 #ifdef METRX_ANVF_TYPES
231  anvf_avg_pnet /= depth_sum;
232  anvf_avg_dndc_can /= depth_sum;
233  anvf_avg_nloss /= depth_sum;
234 #endif
235  pore_connect_avg /= depth_sum;
236  d_eff_avg /= depth_sum;
237  wfps_avg /= depth_sum;
238  air_avg /= depth_sum;
239  root_conduct_avg /= depth_sum;
240 
241  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( anvf_avg);
242 #ifdef METRX_ANVF_TYPES
243  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( anvf_avg_pnet);
244  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( anvf_avg_dndc_can);
245  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( anvf_avg_nloss);
246 #endif
247  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( pore_connect_avg);
248  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( d_eff_avg);
249  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( wfps_avg);
250  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( air_avg);
251  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( root_conduct_avg);
252  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( o2_sum * cbm::M2_IN_HA);
253  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( crnf_.get_crnf_teff_mean());
254  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( crnf_.get_crnf_release_fraction_mean());
255  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nitrification_inhibition);
256  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( urease_inhibition);
257  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( mineral_efficiency / (mineral_efficiency_scale_sum * sl_.soil_layer_cnt()));
258  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( don_sum * cbm::M2_IN_HA);
259  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nh4_sum * cbm::M2_IN_HA);
260  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nh4_clay_sum * cbm::M2_IN_HA);
261  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( coated_nh4_sum * cbm::M2_IN_HA);
262  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( urea_sum * cbm::M2_IN_HA);
263  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( no2_sum * cbm::M2_IN_HA);
264  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( an_no2_sum * cbm::M2_IN_HA);
265  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( no3_sum * cbm::M2_IN_HA);
266  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( an_no3_sum * cbm::M2_IN_HA);
267  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( n2o_sum * cbm::M2_IN_HA);
268  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( an_n2o_sum * cbm::M2_IN_HA);
269  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( no_sum * cbm::M2_IN_HA);
270  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( an_no_sum * cbm::M2_IN_HA);
271  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nh3_gas_sum * cbm::M2_IN_HA);
272  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nh3_liq_sum * cbm::M2_IN_HA);
273  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( doc_sum * cbm::M2_IN_HA);
274  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( an_doc_sum * cbm::M2_IN_HA);
275  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( acetate_sum * cbm::M2_IN_HA);
276  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( ch4_gas_sum * cbm::M2_IN_HA);
277  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( ch4_liq_sum * cbm::M2_IN_HA);
278  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( caorg * cbm::M2_IN_HA);
279  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( naorg * cbm::M2_IN_HA);
280  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( cmic1 * cbm::M2_IN_HA);
281  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( cmic2 * cbm::M2_IN_HA);
282  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( cmic3 * cbm::M2_IN_HA);
283  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nmic1 * cbm::M2_IN_HA);
284  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nmic2 * cbm::M2_IN_HA);
285  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nmic3 * cbm::M2_IN_HA);
286  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( chum1 * cbm::M2_IN_HA);
287  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( chum2 * cbm::M2_IN_HA);
288  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( chum3 * cbm::M2_IN_HA);
289  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nhum1 * cbm::M2_IN_HA);
290  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nhum2 * cbm::M2_IN_HA);
291  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nhum3 * cbm::M2_IN_HA);
292  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( clit1 * cbm::M2_IN_HA);
293  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( clit2 * cbm::M2_IN_HA);
294  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( clit3 * cbm::M2_IN_HA);
295  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nlit1 * cbm::M2_IN_HA);
296  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nlit2 * cbm::M2_IN_HA);
297  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nlit3 * cbm::M2_IN_HA);
298  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_algae_tot * cbm::M2_IN_HA);
299  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( n_algae_tot * cbm::M2_IN_HA);
300  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( cstub * cbm::M2_IN_HA);
301  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nstub * cbm::M2_IN_HA);
302  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);
303  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);
304 
305  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( n_sbl * cbm::M2_IN_HA);
306 
307  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( soc20 / soilmass20);
308  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( soc40 / soilmass40);
309  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( totn20 / soilmass20);
310  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( totn40 / soilmass40);
311  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.fe2_sl.sum() * cbm::M2_IN_HA);
312  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.fe3_sl.sum() * cbm::M2_IN_HA);
313  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.till_effect_sl.sum() / sl_.soil_layer_cnt());
314  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( freeze_thaw_fact_sl.sum());
315  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( litter_height);
316  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( MeTrX_get_ph_wl());
317  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.ph_sl[0]);
318  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_no3_groundwater_access * cbm::M2_IN_HA);
319  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);
320  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_nit_nh4_no2 * cbm::M2_IN_HA);
321  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_nit_no2_no3_sl.sum() * cbm::M2_IN_HA);
322  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_nit_no2_no * cbm::M2_IN_HA);
323  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_nit_no2_n2o * cbm::M2_IN_HA);
324  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_denit_no3_no2 * cbm::M2_IN_HA);
325  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_denit_no2_no * cbm::M2_IN_HA);
326  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_denit_no2_n2o * cbm::M2_IN_HA);
327  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_denit_no2_n2 * cbm::M2_IN_HA);
328  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_denit_no_n2o * cbm::M2_IN_HA);
329  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_denit_no_n2 * cbm::M2_IN_HA);
330  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_denit_n2o_n2 * cbm::M2_IN_HA);
331  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_chemodenit_no2_no * cbm::M2_IN_HA);
332  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_ch4_oxidation_sl.sum() * cbm::M2_IN_HA);
333  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_ch4_production_hydrogen_sl.sum() * cbm::M2_IN_HA);
334  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_ch4_production_acetate_sl.sum() * cbm::M2_IN_HA);
335  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_ch4_plant.sum() * cbm::M2_IN_HA);
336  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_ch4_soil.sum() * cbm::M2_IN_HA);
337  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_ch4_water.sum() * cbm::M2_IN_HA);
338  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_ch4_bubbling.sum() * cbm::M2_IN_HA);
339  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_ch4_leach.sum() * cbm::M2_IN_HA);
340  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_o2_plant.sum() * cbm::M2_IN_HA);
341 
342  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);
343  accumulated_c_litter_above_old = sc_.accumulated_c_litter_stubble + sc_.accumulated_c_litter_wood_above;
344 
345  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);
346  accumulated_c_litter_below_old = sc_.accumulated_c_litter_below_sl.sum() + sc_.accumulated_c_litter_wood_below_sl.sum();
347 
348  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_c_fix_algae * cbm::M2_IN_HA);
349  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_n_fix_algae * cbm::M2_IN_HA);
350  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);
351  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_decay_c_mic_sl.sum()*cbm::M2_IN_HA);
352  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_co2_prod_mic_1_growth * cbm::M2_IN_HA);
353  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_co2_prod_mic_1_maintenance * cbm::M2_IN_HA);
354  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_co2_prod_mic_2 * cbm::M2_IN_HA);
355  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_co2_prod_mic_3_acetate_prod * cbm::M2_IN_HA);
356  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_co2_prod_mic_3_acetate_cons * cbm::M2_IN_HA);
357  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_co2_prod_ch4_prod * cbm::M2_IN_HA);
358  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_co2_prod_ch4_cons * cbm::M2_IN_HA);
359  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_h2_c_eq_prod_sl.sum() * cbm::M2_IN_HA);
360  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_acetate_prod_sl.sum() * cbm::M2_IN_HA);
361  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_acetate_cons_fe3_sl.sum() * cbm::M2_IN_HA/FE3_ACETATE_REDUCTION_RATIO);
362  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_h2_c_eq_cons_fe3_sl.sum() * cbm::M2_IN_HA/FE3_ACETATE_REDUCTION_RATIO);
363  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_doc_prod_decomp_litter * cbm::M2_IN_HA);
364  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_doc_prod_decomp_humus * cbm::M2_IN_HA);
365  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_doc_prod_decomp_aorg * cbm::M2_IN_HA);
366  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( dC_root_exsudates * cbm::M2_IN_HA);
367  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_doc_prod_sl.sum() * cbm::M2_IN_HA);
368  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_c_humify_doc_hum_1_sl.sum() * cbm::M2_IN_HA);
369  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_c_humify_sol_hum_1_sl.sum() * cbm::M2_IN_HA);
370  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_c_humify_cel_hum_1_sl.sum() * cbm::M2_IN_HA);
371  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_c_humify_lig_hum_1_sl.sum() * cbm::M2_IN_HA);
372  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_c_humify_lig_hum_2_sl.sum() * cbm::M2_IN_HA);
373  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_c_humify_mic_hum_1_sl.sum() * cbm::M2_IN_HA);
374  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_c_humify_mic_hum_2_sl.sum() * cbm::M2_IN_HA);
375  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_c_humify_hum_1_hum_2_sl.sum() * cbm::M2_IN_HA);
376  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_c_humify_hum_2_hum_3_sl.sum() * cbm::M2_IN_HA);
377  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( (subdaily_ch4_leach.sum()) * cbm::M2_IN_HA);
378  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_min_n_decomp * cbm::M2_IN_HA);
379  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_min_n_aorg * cbm::M2_IN_HA);
380  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_min_n_mic_1 * cbm::M2_IN_HA);
381  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_min_n_mic_2 * cbm::M2_IN_HA);
382  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_min_n_mic_3 * cbm::M2_IN_HA);
383  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_assi_c_mic_1 * cbm::M2_IN_HA);
384  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_assi_c_mic_2 * cbm::M2_IN_HA);
385  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_assi_c_mic_3 * cbm::M2_IN_HA);
386 
387  return output_writer_.write_daily( output_data_);
388 }
double MeTrX_get_ph_wl()
Definition: soilchemistry-metrx-physics-chemistry.cpp:489
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().

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

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

594 {
595  for ( size_t l = 0; l < sl_.soil_layer_cnt(); ++l)
596  {
597  LDNDC_OUTPUT_SET_COLUMN_INDEX(0);
598  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( -sc_.depth_sl[l]);
599  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_humus_1_sl[l]);
600  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_humus_2_sl[l]);
601  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_humus_3_sl[l]);
602  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.C_aorg_sl[l]);
603  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.C_micro1_sl[l]+sc_.C_micro2_sl[l]+sc_.C_micro3_sl[l]);
604 
605  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]);
606  output_writer_.output_writer_layer_yearly.accumulated_n_no3_no2_denitrification_sl[l] = accumulated_n_no3_no2_denitrification_sl[l];
607 
608  lerr_t rc_write = output_writer_.write_layer_yearly( l, output_data_);
609  if ( rc_write)
610  {
611  return LDNDC_ERR_FAIL;
612  }
613  }
614 
615  return LDNDC_ERR_OK;
616 }
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().

621 {
622  for ( size_t l = 0; l < sl_.soil_layer_cnt(); ++l)
623  {
624  LDNDC_OUTPUT_SET_COLUMN_INDEX(0);
625  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( -sc_.depth_sl[l]);
626 
627  //pools that exist for each soil layer
628  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.urea_sl[l]);
629  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]);
630  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.N_aorg_sl[l]);
631  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( n_humus_1_sl[l]);
632  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( n_humus_2_sl[l]);
633  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( n_humus_3_sl[l]);
634  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( n_micro_1_sl[l] + n_micro_2_sl[l] + n_micro_3_sl[l]);
635  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.nh3_liq_sl[l] + sc_.nh3_gas_sl[l]);
636  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nh4_ae_sl[l] + nh4_an_sl[l] + sc_.clay_nh4_sl[l]);
637  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( don_ae_sl[l] + don_an_sl[l]);
638  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( no3_ae_sl[l] + no3_an_sl[l]);
639  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.no2_sl[l] + sc_.an_no2_sl[l]);
640  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]);
641  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]);
642 
643  //surface pools
644  if( l == 0 )
645  {
646  double nplant(0.0);
647  for ( PlantIterator vt = this->m_veg->begin(); vt != this->m_veg->end(); ++vt)
648  {
649  nplant += (*vt)->total_nitrogen();
650  }
651 
652  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sb_.nh4_sbl.sum() );
653  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sb_.nh3_sbl.sum() );
654  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sb_.n2o_sbl.sum() );
655  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sb_.no_sbl.sum() );
656  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sb_.urea_sbl.sum() );
657  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sb_.no3_sbl.sum() );
658  //METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sb_.don_sbl.sum() );
659  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nplant );
660  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.n_wood + sc_.n_stubble_lit1 + sc_.n_stubble_lit2 + sc_.n_stubble_lit3 +
661  sc_.n_raw_lit_1_above + sc_.n_raw_lit_2_above + sc_.n_raw_lit_3_above);
662  }
663  else
664  {
665  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0 );
666  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0 );
667  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0 );
668  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0 );
669  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0 );
670  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0 );
671  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0 );
672  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0 );
673  //METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0 );
674  //METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0 );
675  }
676 
677  lerr_t rc_write = output_writer_.write_pools( l, output_data_);
678  if ( rc_write)
679  {
680  return LDNDC_ERR_FAIL;
681  }
682  }
683 
684  return LDNDC_ERR_OK;
685 }
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().

936 {
937  size_t s( lclock()->subday()-1);
938  LDNDC_OUTPUT_SET_COLUMN_INDEX(0);
939  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.C_micro1_sl.sum());
940  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.C_micro2_sl.sum());
941  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.C_micro3_sl.sum());
942  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.C_aorg_sl.sum());
943  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nh4_ae_sl.sum()+nh4_an_sl.sum()+sc_.clay_nh4_sl.sum());
944  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( no3_ae_sl.sum());
945  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( no3_an_sl.sum());
946  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.doc_sl.sum());
947  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.an_doc_sl.sum());
948  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( ae_acetate_sl.sum());
949  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( an_acetate_sl.sum());
950 
951  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_ch4_bubbling[s]);
952  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_ch4_plant[s]);
953  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_ch4_soil[s]);
954  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_ch4_water[s]);
955  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_ch4_leach[s]);
956  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_ch4_prod[s]);
957  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_ch4_ox[s]);
958 
959  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_acetate_prod[s]);
960  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_doc_prod[s]);
961 
962  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( accumulated_n_no2_no3_nitrification_sl.sum() - output_writer_.output_writer_subdaily.accumulated_n_no2_no3_nitrification);
963  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( accumulated_n_no3_no2_denitrification_sl.sum() - output_writer_.output_writer_subdaily.accumulated_n_no3_no2_denitrification);
964 
965  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_n2o_bubbling[s]);
966  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_n2o_plant[s]);
967  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_n2o_soil[s]);
968  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_n2o_water[s]);
969  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_no_bubbling[s]);
970  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_no_plant[s]);
971  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_no_soil[s]);
972  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_no_water[s]);
973  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_nh3_bubbling[s]);
974  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_nh3_plant[s]);
975  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_nh3_soil[s]);
976  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_nh3_water[s]);
977 
978  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_plant_o2_cons[s]);
979  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_o2_plant[s]);
980  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_algae_o2_prod[s]);
981 
982  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( MeTrX_get_ph_wl());
983  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.ph_sl[0]);
984  double anvf_mean( sc_.anvf_sl.sum() / sl_.soil_layer_cnt());
985  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( anvf_mean);
986 
987  lerr_t rc_write = output_writer_.write_subdaily( output_data_);
988  if ( rc_write)
989  {
990  return LDNDC_ERR_FAIL;
991  }
992 
993  output_writer_.output_writer_subdaily.accumulated_n_no2_no3_nitrification = accumulated_n_no2_no3_nitrification_sl.sum();
994  output_writer_.output_writer_subdaily.accumulated_n_no3_no2_denitrification = accumulated_n_no3_no2_denitrification_sl.sum();
995 
996  return LDNDC_ERR_OK;
997 }
double MeTrX_get_ph_wl()
Definition: soilchemistry-metrx-physics-chemistry.cpp:489
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().

393 {
394  double surface_litter( c_algae + c_dead_algae + sc_.c_stubble_lit1 + sc_.c_stubble_lit2 + sc_.c_stubble_lit3);
395  double soc20( 0.0);
396  double c_hum_1_20( 0.0);
397  double c_hum_2_20( 0.0);
398  double c_hum_3_20( 0.0);
399  double c_litter_20( 0.0);
400  double c_aorg_20( 0.0);
401  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
402  {
403  if ( cbm::flt_less_equal( sc_.depth_sl[sl], 0.2))
404  {
405  soc20 += sc_.C_aorg_sl[sl] + c_humus_1_sl[sl] + c_humus_2_sl[sl] + c_humus_3_sl[sl]
406  + sc_.C_micro1_sl[sl] + sc_.C_micro2_sl[sl] + sc_.C_micro3_sl[sl]
407  + sc_.C_lit1_sl[sl] + sc_.C_lit2_sl[sl] + sc_.C_lit3_sl[sl];
408  c_hum_1_20 += c_humus_1_sl[sl];
409  c_hum_2_20 += c_humus_2_sl[sl];
410  c_hum_3_20 += c_humus_3_sl[sl];
411  c_litter_20 += sc_.C_lit1_sl[sl] + sc_.C_lit2_sl[sl] + sc_.C_lit3_sl[sl];
412  c_aorg_20 += sc_.C_aorg_sl[sl];
413  }
414  else
415  {
416  break;
417  }
418  }
419 
420 #define METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT(__val__) LDNDC_OUTPUT_SET_COLUMN_((__val__),=,output_data_,1)
421  LDNDC_OUTPUT_SET_COLUMN_INDEX(0);
422 
423  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( surface_litter);
424  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( soc20);
425  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_hum_1_20);
426  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_hum_2_20);
427  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_hum_3_20);
428  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_litter_20);
429  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_aorg_20);
430 
431  return output_writer_.write_yearly( output_data_);
432 }
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:538
lerr_t MeTrX_nitrogen_fertilizer_release()
Transforms nitrogen from slow release nitrogen fertilizer to nh4.
Definition: soilchemistry-metrx-management.cpp:837
lerr_t MeTrX_till()
Definition: soilchemistry-metrx-management.cpp:629
lerr_t MeTrX_freeze_thaw()
Definition: soilchemistry-metrx-physics-chemistry.cpp:386
lerr_t MeTrX_physics()
Definition: soilchemistry-metrx-physics-chemistry.cpp:155
void MeTrX_pH_calculation()
Definition: soilchemistry-metrx-physics-chemistry.cpp:503
lerr_t MeTrX_write_rates()
Definition: soilchemistry-metrx-integrate.cpp:19
lerr_t MeTrX_fertilize()
Definition: soilchemistry-metrx-management.cpp:32
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:787
lerr_t MeTrX_pertubation()
Definition: soilchemistry-metrx-transport.cpp:1350
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:930
lerr_t MeTrX_manure()
Definition: soilchemistry-metrx-management.cpp:261
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:180
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().