LandscapeDNDC  1.37.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_radon_source_sink ()
 
lerr_t MeTrX_fragmentation ()
 
void MeTrX_litter_distribution (double const &, double const &, double const &, double const &, double const &, double const &, lvector< 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_t_denit (size_t const &)
 The soil temperature response \( \phi_{T}\) of denitrification is given by the same temperature dependency as for general microbial activity:

\[ \phi_{T} = e^{-\Omega_{MFMTE1} \cdot \left( 1 - \frac{T}{\Omega_{MFMTE2}} \right)^2} \]

. More...

 
double MeTrX_get_fact_m_denit (size_t const &)
 The soil moisture response \( \phi_{wfps}\) of denitrificstion is given by: More...
 
double MeTrX_get_fact_tm_denit (size_t const &)
 The temperature and moisture dependency of denitrifying microbes is given by the harmonic mean of a soil temperature ( \( \phi_{T}\)) and a soil moisture ( \( \phi_{wfps}\)) response coefficient. More...
 
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 (bool)
 

Static Private Attributes

static const double TNORM = 293.2
 

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(), ldndc::d_eff_air_a(), ldndc::d_eff_air_millington_and_quirk_1961(), MeTrX_physics(), and TNORM.

Referenced by solve().

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

751 {
752  double const val_tot( _val_gas + _val_liq);
753  if ( cbm::flt_greater_zero( val_tot))
754  {
755  _val_liq = _henry / (1.0 + _henry) * val_tot;
756  _val_gas = val_tot - _val_liq;
757  }
758  return LDNDC_ERR_OK;
759 }
Here is the caller graph for this function:

◆ MeTrX_ebullition()

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

Referenced by MeTrX_groundwater_access(), and solve().

Here is the caller graph for this function:

◆ MeTrX_fermentation()

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

Referenced by solve().

Here is the caller graph for this function:

◆ MeTrX_fertilize()

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

Referenced by solve().

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

◆ MeTrX_fragmentation()

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

References MeTrX_get_fact_tm_decomp(), and MeTrX_litter_distribution().

Referenced by solve().

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

413 {
414  if ( freeze_thaw_method == "ft_processes")
415  {
416  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
417  {
418 
419  if ( cbm::flt_greater_zero( v_ice_sl[sl]) &&
420  cbm::flt_less_equal( mc_temp_sl[sl], 0.0))
421  {
422  cumulative_freezing_degree_days_sl[sl] += std::abs( mc_temp_sl[sl]) * FTS_TOT_;
423  if ( cbm::flt_less_equal( mc_temp_sl[sl], -sipar_.METRX_CFDD_THRESHOLD()))
424  {
425  cfdd_turnover_sl[sl] += std::abs( mc_temp_sl[sl]) * FTS_TOT_;
426  }
427  }
428  else if ( cbm::flt_greater_equal( mc_temp_sl[sl],0.0))
429  // else if (cbm::flt_equal_zero( v_ice_sl[sl]) &&
430  // cbm::flt_greater_zero( mc_temp_sl[sl]))
431  {
432  if ( cfdd_turnover_sl[sl] > sipar_.METRX_CFDD_MIN())
433  {
434  // linear function
435  // double c_decomp_aorg(cbm::bound(0.0, cfdd_turnover_sl[sl] / sipar_.METRX_CFDD_MAX(), 0.99) * sc_.C_aorg_sl[sl] * sipar_.METRX_CFDD_TURN_MAX());
436  // double n_decomp_aorg(cbm::bound(0.0, cfdd_turnover_sl[sl] / sipar_.METRX_CFDD_MAX(), 0.99) * sc_.N_aorg_sl[sl] * sipar_.METRX_CFDD_TURN_MAX());
437  // saturation function
438  double c_decomp_aorg( cbm::bound( 0.0, 1.0 /(1.0+ std::exp(-0.05 * (cfdd_turnover_sl[sl] - (sipar_.METRX_CFDD_MAX()/2.0)))), 0.99) * sc_.C_aorg_sl[sl] * sipar_.METRX_CFDD_TURN_MAX());
439  double n_decomp_aorg( cbm::bound( 0.0, 1.0 /(1.0+ std::exp(-0.05 * (cfdd_turnover_sl[sl] - (sipar_.METRX_CFDD_MAX()/2.0)))), 0.99) * sc_.N_aorg_sl[sl] * sipar_.METRX_CFDD_TURN_MAX());
440 
441  sc_.C_aorg_sl[sl] -= c_decomp_aorg;
442  sc_.N_aorg_sl[sl] -= n_decomp_aorg;
443 
444  sc_.an_doc_sl[sl] += c_decomp_aorg * sc_.anvf_sl[sl];
445  sc_.doc_sl[sl] += c_decomp_aorg * (1.0 - sc_.anvf_sl[sl]);
446 
447  don_ae_sl[sl] += (1.0 - sipar_.METRX_FRAC_MINERAL()) * n_decomp_aorg * (1.0 - sc_.anvf_sl[sl]);
448  don_an_sl[sl] += (1.0 - sipar_.METRX_FRAC_MINERAL()) * n_decomp_aorg * sc_.anvf_sl[sl];
449 
450  nh4_ae_sl[sl] += sipar_.METRX_FRAC_MINERAL() * n_decomp_aorg * (1.0 - sc_.anvf_sl[sl]);
451  nh4_an_sl[sl] += sipar_.METRX_FRAC_MINERAL() * n_decomp_aorg * sc_.anvf_sl[sl];
452  }
453 
454  cumulative_freezing_degree_days_sl[sl] = 0.0;
455  cfdd_turnover_sl[sl] = 0.0;
456  }
457  }
458  }
459 
460  return LDNDC_ERR_OK;
461 }
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_m_denit()

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

The soil moisture response \( \phi_{wfps}\) of denitrificstion is given by:

\[ \phi_{wfps} = 1 - \frac{1}{1 + e^{(wfps - \Omega_{MFDMW1}) \cdot \Omega_{MFDMW2}}} \]

  • \( \Omega_{MFDMW1} \): METRX_F_DENIT_M_WEIBULL_1
  • \( \Omega_{MFDMW2} \): METRX_F_DENIT_M_WEIBULL_2
metrx_denitrification_on_soilwater.png
Response function depending on soilwater

Referenced by MeTrX_get_fact_tm_denit().

579 {
580  return ldndc::meteo::F_weibull( MeTrX_get_wfps_eff( _sl, 0.0),
581  sipar_.METRX_F_DENIT_M_WEIBULL_1(),
582  sipar_.METRX_F_DENIT_M_WEIBULL_2(),
583  1.0);
584 }
Here is the caller graph for this function:

◆ MeTrX_get_fact_t_denit()

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

The soil temperature response \( \phi_{T}\) of denitrification is given by the same temperature dependency as for general microbial activity:

\[ \phi_{T} = e^{-\Omega_{MFMTE1} \cdot \left( 1 - \frac{T}{\Omega_{MFMTE2}} \right)^2} \]

.

  • \( \Omega_{MFMTE1} \): METRX_F_MIC_T_EXP_1
  • \( \Omega_{MFMTE2} \): METRX_F_MIC_T_EXP_2
metrx_microbial_activity_on_temperature.png
Response function depending on temperature

Referenced by MeTrX_get_fact_tm_denit().

548 {
549  double const help( std::pow(1.0 - mc_temp_sl[_sl] / sipar_.METRX_F_MIC_T_EXP_2(), 2.0));
550  if ( freeze_thaw_method == "ft_processes")
551  {
552  return std::exp( -(sipar_.METRX_F_MIC_T_EXP_COLD() +
553  (sipar_.METRX_F_MIC_T_EXP_1() - sipar_.METRX_F_MIC_T_EXP_COLD()) /
554  (1.0 + std::exp(-sipar_.METRX_F_MIC_T_EXP_1() *
555  (mc_temp_sl[_sl] - sipar_.METRX_F_MIC_T_EXP_2())))) * help);
556  }
557  else
558  {
559  return std::exp( -sipar_.METRX_F_MIC_T_EXP_1() * help);
560  }
561 }
Here is the caller 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().

686 {
687  double const fact_t( std::exp( -sipar_.METRX_F_DECOMP_T_EXP_1() *
688  pow(1.0 - mc_temp_sl[_sl] / sipar_.METRX_F_DECOMP_T_EXP_2(), 2.0)));
689  double const fact_m( ldndc::meteo::F_weibull( MeTrX_get_wfps_eff( _sl, 0.0),
690  sipar_.METRX_F_DECOMP_M_WEIBULL_1(),
691  sipar_.METRX_F_DECOMP_M_WEIBULL_2(),
692  1.0));
693  return cbm::harmonic_mean2( fact_t, fact_m);
694 }
Here is the caller graph for this function:

◆ MeTrX_get_fact_tm_denit()

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

The temperature and moisture dependency of denitrifying microbes is given by the harmonic mean of a soil temperature ( \( \phi_{T}\)) and a soil moisture ( \( \phi_{wfps}\)) response coefficient.

\[ \frac{2}{\frac{1}{\phi_{T}} + \frac{1}{\phi_{wfps}}} \]

The soil temperature response \( \phi_{T}\) of denitrification is given by the same temperature dependency as for general microbial activity:

\[ \phi_{T} = e^{-\Omega_{MFMTE1} \cdot \left( 1 - \frac{T}{\Omega_{MFMTE2}} \right)^2} \]

.

  • \( \Omega_{MFMTE1} \): METRX_F_MIC_T_EXP_1
  • \( \Omega_{MFMTE2} \): METRX_F_MIC_T_EXP_2
metrx_microbial_activity_on_temperature.png
Response function depending on temperature
The soil moisture response \( \phi_{wfps}\) of denitrificstion is given by:

\[ \phi_{wfps} = 1 - \frac{1}{1 + e^{(wfps - \Omega_{MFDMW1}) \cdot \Omega_{MFDMW2}}} \]

  • \( \Omega_{MFDMW1} \): METRX_F_DENIT_M_WEIBULL_1
  • \( \Omega_{MFDMW2} \): METRX_F_DENIT_M_WEIBULL_2
metrx_denitrification_on_soilwater.png
Response function depending on soilwater

References MeTrX_chemodenitrification(), MeTrX_get_fact_m_denit(), and MeTrX_get_fact_t_denit().

602 {
603  return cbm::harmonic_mean2( MeTrX_get_fact_t_denit( _sl),
604  MeTrX_get_fact_m_denit( _sl));
605 }
double MeTrX_get_fact_m_denit(size_t const &)
The soil moisture response of denitrificstion is given by:
Definition: soilchemistry-metrx-denitrification.cpp:578
double MeTrX_get_fact_t_denit(size_t const &)
The soil temperature response of denitrification is given by the same temperature dependency as for ...
Definition: soilchemistry-metrx-denitrification.cpp:547
Here is the call 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().

602 {
603  if ( cbm::flt_greater_zero( wc_.surface_water))
604  {
605  return cbm::bound( PH_SURFACE_WATER, PH_SURFACE_WATER + ph_delta_pab_wl + ph_delta_urea_wl, PH_MAX);
606  }
607  else
608  {
609  return 7.0;
610  }
611 }
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().

769 {
770  if ( gw_ != NULL)
771  {
772  for ( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
773  {
774  if ( sc_.depth_sl[sl] > gw_->watertable_subday( lclock_ref()))
775  {
776  double const no3_gw( gw_->no3_day(lclock_ref()) //given in (mg no3 L-1)
777  * cbm::MN / (cbm::MN + 3.0 * cbm::MO) * cbm::KG_IN_MG //converts no3 from (mg no3) -> (kg n-no3)
778  * (wc_.wc_sl[sl] + wc_.ice_sl[sl]) * sc_.h_sl[sl] * cbm::DM3_IN_M3); //converts water (m3) -> (L)
779 
780  if ( cbm::flt_greater_zero( no3_gw))
781  {
782  double const no3_diff( GROUNDWATER_NUTRIENT_ACCESS_RATE * (no3_gw - no3_an_sl[sl]));
783  no3_an_sl[sl] += no3_diff;
784  day_no3_groundwater_access += no3_diff;
785  sc_.accumulated_no3_leach -= no3_diff;
786  sc_.accumulated_n_no3_leaching_sl[sl] -= no3_diff;
787  }
788  }
789  }
790 
791  if ( have_river_connection)
792  {
793  if ( have_water_table)
794  {
795  for (size_t sbl = 0; sbl < sb_.surfacebulk_layer_cnt(); ++sbl)
796  {
797  DISSOLUTION_ATMOSPHERE( MeTrX_get_atm_eq_liq( o2_atm_eq_liq, h_wl), sb_.o2_sbl[sbl], subdaily_o2_water[subdaily_time_step_]);
798  DISSOLUTION_ATMOSPHERE( MeTrX_get_atm_eq_liq( ch4_atm_eq_liq, h_wl), sb_.ch4_sbl[sbl], subdaily_ch4_water[subdaily_time_step_]);
799  DISSOLUTION_ATMOSPHERE( MeTrX_get_atm_eq_liq( co2_atm_eq_liq, h_wl), sb_.co2_sbl[sbl], subdaily_co2_water[subdaily_time_step_]);
800  DISSOLUTION_ATMOSPHERE( MeTrX_get_atm_eq_liq( nh3_atm_eq_liq, h_wl), sb_.nh3_sbl[sbl], subdaily_nh3_water[subdaily_time_step_]);
801  DISSOLUTION_ATMOSPHERE( MeTrX_get_atm_eq_liq( no_atm_eq_liq, h_wl), sb_.no_sbl[sbl], subdaily_no_water[subdaily_time_step_]);
802  DISSOLUTION_ATMOSPHERE( MeTrX_get_atm_eq_liq( n2o_atm_eq_liq, h_wl), sb_.n2o_sbl[sbl], subdaily_n2o_water[subdaily_time_step_]);
803  if ( have_radon_diffusion)
804  {
805  DISSOLUTION_ATMOSPHERE( MeTrX_get_atm_eq_liq( radon_atm_eq_liq, h_wl) * cbm::RGAS * mc_.ts_airtemperature, sb_.radon_sbl[sbl], subdaily_radon_water[subdaily_time_step_]);
806  }
807  }
808  }
809  }
810  }
811 }
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().

26 {
27  /*************************/
28  /* Water table transport */
29  /*************************/
30 
31  if ( have_water_table &&
32  cbm::flt_greater_zero( infiltration))
33  {
34  ldndc_kassert( h_wl > 0.0);
35 
36  accumulated_n_nh4_infiltration_leach_sl[0] -= nh4_an_sl[0] + sc_.coated_nh4_sl[0];
37  accumulated_n_nh3_infiltration_leach_sl[0] -= sc_.nh3_liq_sl[0];
38  accumulated_n_no_infiltration_leach_sl[0] -= an_no_liq_sl[0];
39  accumulated_n_n2o_infiltration_leach_sl[0] -= an_n2o_liq_sl[0];
40  accumulated_n_urea_infiltration_leach_sl[0] -= sc_.urea_sl[0];
41  accumulated_n_no3_infiltration_leach_sl[0] -= no3_an_sl[0];
42  accumulated_n_don_infiltration_leach_sl[0] -= don_an_sl[0];
43 
44  double const leach_fact_sbl( cbm::bound_max( infiltration / h_wl, 0.99));
45  LEACH_DOWN( sb_.ch4_sbl[0], ch4_liq_sl[0], leach_fact_sbl);
46  LEACH_DOWN( sb_.o2_sbl[0], o2_liq_sl[0], leach_fact_sbl);
47  LEACH_DOWN( sb_.nh4_sbl[0], nh4_an_sl[0], leach_fact_sbl);
48  LEACH_DOWN( sb_.coated_nh4_sbl[0], sc_.coated_nh4_sl[0], leach_fact_sbl);
49  LEACH_DOWN( sb_.nh3_sbl[0], sc_.nh3_liq_sl[0], leach_fact_sbl);
50  LEACH_DOWN( sb_.no_sbl[0], an_no_liq_sl[0], leach_fact_sbl);
51  LEACH_DOWN( sb_.n2o_sbl[0], an_n2o_liq_sl[0], leach_fact_sbl);
52  LEACH_DOWN( sb_.urea_sbl[0], sc_.urea_sl[0], leach_fact_sbl);
53  LEACH_DOWN( sb_.no3_sbl[0], no3_an_sl[0], leach_fact_sbl);
54  LEACH_DOWN( sb_.don_sbl[0], don_an_sl[0], leach_fact_sbl);
55  LEACH_DOWN( sb_.doc_sbl[0], sc_.doc_sl[0], leach_fact_sbl);
56  LEACH_DOWN( sb_.co2_sbl[0], co2_liq_sl[0], leach_fact_sbl);
57  LEACH_DOWN( sb_.so4_sbl[0], sc_.so4_sl[0], leach_fact_sbl);
58  LEACH_DOWN( sb_.ni_sbl[0], sc_.ni_sl[0], leach_fact_sbl);
59  LEACH_DOWN( sb_.ui_sbl[0], sc_.ui_sl[0], leach_fact_sbl);
60  if ( have_radon_diffusion)
61  {
62  LEACH_DOWN( sb_.radon_sbl[0], radon_liq_sl[0], leach_fact_sbl);
63  }
64 
65  accumulated_n_nh4_infiltration_leach_sl[0] += nh4_an_sl[0] + sc_.coated_nh4_sl[0];
66  accumulated_n_nh3_infiltration_leach_sl[0] += sc_.nh3_liq_sl[0];
67  accumulated_n_no_infiltration_leach_sl[0] += an_no_liq_sl[0];
68  accumulated_n_n2o_infiltration_leach_sl[0] += an_n2o_liq_sl[0];
69  accumulated_n_urea_infiltration_leach_sl[0] += sc_.urea_sl[0];
70  accumulated_n_no3_infiltration_leach_sl[0] += no3_an_sl[0];
71  accumulated_n_don_infiltration_leach_sl[0] += don_an_sl[0];
72 
73  for (size_t sbl = 1; sbl < sb_.surfacebulk_layer_cnt(); ++sbl)
74  {
75  size_t const sbl_plus( sbl - 1);
76  LEACH_DOWN( sb_.ch4_sbl[sbl], sb_.ch4_sbl[sbl_plus], leach_fact_sbl);
77  LEACH_DOWN( sb_.o2_sbl[sbl], sb_.o2_sbl[sbl_plus], leach_fact_sbl);
78  LEACH_DOWN( sb_.nh4_sbl[sbl], sb_.nh4_sbl[sbl_plus], leach_fact_sbl);
79  LEACH_DOWN( sb_.coated_nh4_sbl[sbl], sb_.coated_nh4_sbl[sbl_plus], leach_fact_sbl);
80  LEACH_DOWN( sb_.nh3_sbl[sbl], sb_.nh3_sbl[sbl_plus], leach_fact_sbl);
81  LEACH_DOWN( sb_.no_sbl[sbl], sb_.no_sbl[sbl_plus], leach_fact_sbl);
82  LEACH_DOWN( sb_.n2o_sbl[sbl], sb_.n2o_sbl[sbl_plus], leach_fact_sbl);
83  LEACH_DOWN( sb_.urea_sbl[sbl], sb_.urea_sbl[sbl_plus], leach_fact_sbl);
84  LEACH_DOWN( sb_.no3_sbl[sbl], sb_.no3_sbl[sbl_plus], leach_fact_sbl);
85  LEACH_DOWN( sb_.don_sbl[sbl], sb_.don_sbl[sbl_plus], leach_fact_sbl);
86  LEACH_DOWN( sb_.doc_sbl[sbl], sb_.doc_sbl[sbl_plus], leach_fact_sbl);
87  LEACH_DOWN( sb_.co2_sbl[sbl], sb_.co2_sbl[sbl_plus], leach_fact_sbl);
88  LEACH_DOWN( sb_.so4_sbl[sbl], sb_.so4_sbl[sbl_plus], leach_fact_sbl);
89  LEACH_DOWN( sb_.ni_sbl[sbl], sb_.ni_sbl[sbl_plus], leach_fact_sbl);
90  if ( have_radon_diffusion)
91  {
92  LEACH_DOWN( sb_.radon_sbl[sbl], sb_.radon_sbl[sbl_plus], leach_fact_sbl);
93  }
94  }
95  }
96 
97  /************************/
98  /* Soil water transport */
99  /************************/
100 
101  if ( cbm::flt_greater_zero( waterflux_sl[0]) &&
102  cbm::flt_greater_zero( v_water_sl[0]))
103  {
104  size_t const sl( 0);
105  size_t const sl_plus( 1);
106 
107  double const leach_fact( cbm::bound_min( 0.0, waterflux_sl[sl] / v_water_sl[sl]));
108 
109  double const leach_fact_nh4( cbm::bound_max( leach_fact * sipar_.RETNH4(), 0.9999));
110  double const leach_fact_no3( cbm::bound_max( leach_fact * sipar_.RETNO3(), 0.9999));
111  double const leach_fact_doc( cbm::bound_max( leach_fact * sipar_.RETDOC(), 0.9999));
112  double const leach_fact_mic( cbm::bound_max( leach_fact * sipar_.METRX_RET_MICROBES(), 0.9999));
113  double const leach_fact_lit( cbm::bound_max( leach_fact * sipar_.METRX_RET_LITTER(), 0.9999));
114  double const leach_fact_hum( cbm::bound_max( leach_fact * sipar_.METRX_RET_HUMUS(), 0.9999));
115  double const leach_fact_dissolved_gases( cbm::bound_max( leach_fact, 0.9999));
116 
117  if ( spinup_.spinup_stage( this->lclock()))
118  {
119  spinup_.loose_lit_1[sl] += leach_fact_lit;
120  spinup_.loose_lit_2[sl] += leach_fact_lit;
121  spinup_.loose_lit_3[sl] += leach_fact_lit;
122 
123  spinup_.loose_aorg[sl] += leach_fact_mic;
124 
125  spinup_.decompose_hum_1[sl] += leach_fact_hum;
126  spinup_.decompose_hum_2[sl] += leach_fact_hum;
127  spinup_.decompose_hum_3[sl] += leach_fact_hum;
128 
129  spinup_.c_to_lit_1[sl_plus] += sc_.C_lit1_sl[sl] * leach_fact_lit;
130  spinup_.c_to_lit_2[sl_plus] += sc_.C_lit2_sl[sl] * leach_fact_lit;
131  spinup_.c_to_lit_3[sl_plus] += sc_.C_lit3_sl[sl] * leach_fact_lit;
132 
133  spinup_.c_to_aorg[sl_plus] += sc_.C_aorg_sl[sl] * leach_fact_mic;
134 
135  spinup_.c_to_humus_1_sl[sl_plus] += c_humus_1_sl[sl] * leach_fact_hum;
136  spinup_.c_to_humus_2_sl[sl_plus] += c_humus_2_sl[sl] * leach_fact_hum;
137  spinup_.c_to_humus_3_sl[sl_plus] += c_humus_3_sl[sl] * leach_fact_hum;
138  }
139 
140  accumulated_n_aorg_leaching_sl[sl] += sc_.N_aorg_sl[sl] * leach_fact_mic;
141  LEACH_DOWN( sc_.C_aorg_sl[sl], sc_.C_aorg_sl[sl_plus], leach_fact_mic);
142  LEACH_DOWN( sc_.N_aorg_sl[sl], sc_.N_aorg_sl[sl_plus], leach_fact_mic);
143 
144  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]));
145  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]));
146  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]));
147 
148  if( n_micro_1_sl[sl] > MeTrX_get_micro_n_decay_max( n_micro_1_sl[sl]) )
149  {
150  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;
151  }
152  if( n_micro_2_sl[sl] > MeTrX_get_micro_n_decay_max( n_micro_2_sl[sl]) )
153  {
154  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;
155  }
156  if( n_micro_3_sl[sl] > MeTrX_get_micro_n_decay_max( n_micro_3_sl[sl]) )
157  {
158  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;
159  }
160  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]));
161  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]));
162  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]));
163 
164  LEACH_DOWN( sc_.C_lit1_sl[sl], sc_.C_lit1_sl[sl_plus], leach_fact_lit);
165  LEACH_DOWN( sc_.C_lit2_sl[sl], sc_.C_lit2_sl[sl_plus], leach_fact_lit);
166  LEACH_DOWN( sc_.C_lit3_sl[sl], sc_.C_lit3_sl[sl_plus], leach_fact_lit);
167 
168  accumulated_n_litter_leaching_sl[sl] += (sc_.N_lit1_sl[sl] + sc_.N_lit2_sl[sl] + sc_.N_lit3_sl[sl]) * leach_fact_lit;
169  LEACH_DOWN( sc_.N_lit1_sl[sl], sc_.N_lit1_sl[sl_plus], leach_fact_lit);
170  LEACH_DOWN( sc_.N_lit2_sl[sl], sc_.N_lit2_sl[sl_plus], leach_fact_lit);
171  LEACH_DOWN( sc_.N_lit3_sl[sl], sc_.N_lit3_sl[sl_plus], leach_fact_lit);
172 
173  LEACH_DOWN( c_humus_1_sl[sl], c_humus_1_sl[sl_plus], leach_fact_hum);
174  LEACH_DOWN( c_humus_2_sl[sl], c_humus_2_sl[sl_plus], leach_fact_hum);
175  LEACH_DOWN( c_humus_3_sl[sl], c_humus_3_sl[sl_plus], leach_fact_hum);
176 
177  accumulated_n_humus_1_leaching_sl[sl] += n_humus_1_sl[sl] * leach_fact_hum;
178  accumulated_n_humus_2_leaching_sl[sl] += n_humus_2_sl[sl] * leach_fact_hum;
179  accumulated_n_humus_3_leaching_sl[sl] += n_humus_3_sl[sl] * leach_fact_hum;
180  LEACH_DOWN( n_humus_1_sl[sl], n_humus_1_sl[sl_plus], leach_fact_hum);
181  LEACH_DOWN( n_humus_2_sl[sl], n_humus_2_sl[sl_plus], leach_fact_hum);
182  LEACH_DOWN( n_humus_3_sl[sl], n_humus_3_sl[sl_plus], leach_fact_hum);
183 
184  accumulated_n_nh4_leaching_sl[sl] += (nh4_ae_sl[sl] + nh4_an_sl[sl] + sc_.coated_nh4_sl[sl]) * leach_fact_nh4;
185  accumulated_n_nh3_leaching_sl[sl] += sc_.nh3_liq_sl[sl] * leach_fact_doc;
186  accumulated_n_urea_leaching_sl[sl] += sc_.urea_sl[sl] * leach_fact_doc;
187  LEACH_DOWN( nh4_ae_sl[sl], nh4_ae_sl[sl_plus], leach_fact_nh4);
188  LEACH_DOWN( nh4_an_sl[sl], nh4_an_sl[sl_plus], leach_fact_nh4);
189  LEACH_DOWN( sc_.coated_nh4_sl[sl], sc_.coated_nh4_sl[sl_plus], leach_fact_nh4);
190  LEACH_DOWN( sc_.nh3_liq_sl[sl], sc_.nh3_liq_sl[sl_plus], leach_fact_doc);
191  LEACH_DOWN( sc_.urea_sl[sl], sc_.urea_sl[sl_plus], leach_fact_doc);
192 
193  sc_.accumulated_n_no3_leaching_sl[sl] += (no3_ae_sl[sl] + no3_an_sl[sl]) * leach_fact_no3;
194  LEACH_DOWN( no3_ae_sl[sl], no3_ae_sl[sl_plus], leach_fact_no3);
195  LEACH_DOWN( no3_an_sl[sl], no3_an_sl[sl_plus], leach_fact_no3);
196 
197  accumulated_n_don_leaching_sl[sl] += (don_ae_sl[sl] + don_an_sl[sl]) * leach_fact_doc;
198  LEACH_DOWN( don_ae_sl[sl], don_ae_sl[sl_plus], leach_fact_doc);
199  LEACH_DOWN( don_an_sl[sl], don_an_sl[sl_plus], leach_fact_doc);
200  LEACH_DOWN( sc_.doc_sl[sl], sc_.doc_sl[sl_plus], leach_fact_doc);
201  LEACH_DOWN( sc_.an_doc_sl[sl], sc_.an_doc_sl[sl_plus], leach_fact_doc);
202  LEACH_DOWN( ae_acetate_sl[sl], ae_acetate_sl[sl_plus], leach_fact_doc);
203  LEACH_DOWN( an_acetate_sl[sl], an_acetate_sl[sl_plus], leach_fact_doc);
204 
205  accumulated_n_no_leaching_sl[sl] += (no_liq_sl[sl]+an_no_liq_sl[sl]) * leach_fact_dissolved_gases;
206  accumulated_n_n2o_leaching_sl[sl] += (n2o_liq_sl[sl]+an_n2o_liq_sl[sl]) * leach_fact_dissolved_gases;
207  LEACH_DOWN( no_liq_sl[sl], no_liq_sl[sl_plus], leach_fact_dissolved_gases);
208  LEACH_DOWN( an_no_liq_sl[sl], an_no_liq_sl[sl_plus], leach_fact_dissolved_gases);
209  LEACH_DOWN( n2o_liq_sl[sl], n2o_liq_sl[sl_plus], leach_fact_dissolved_gases);
210  LEACH_DOWN( an_n2o_liq_sl[sl], an_n2o_liq_sl[sl_plus], leach_fact_dissolved_gases);
211 
212  LEACH_DOWN( ch4_liq_sl[sl], ch4_liq_sl[sl_plus], leach_fact_dissolved_gases);
213  LEACH_DOWN( co2_liq_sl[sl], co2_liq_sl[sl_plus], leach_fact_dissolved_gases);
214  LEACH_DOWN( o2_liq_sl[sl], o2_liq_sl[sl_plus], leach_fact_dissolved_gases);
215 
216  LEACH_DOWN( sc_.so4_sl[sl], sc_.so4_sl[sl_plus], leach_fact_no3);
217  LEACH_DOWN( sc_.ni_sl[sl], sc_.ni_sl[sl_plus], leach_fact_doc);
218  LEACH_DOWN( sc_.ui_sl[sl], sc_.ui_sl[sl_plus], leach_fact_doc);
219 
220  if ( have_radon_diffusion)
221  {
222  LEACH_DOWN( radon_liq_sl[sl], radon_liq_sl[sl_plus], leach_fact_dissolved_gases);
223  }
224  }
225 
226  for( size_t sl = 1; sl < sl_.soil_layer_cnt()-1; ++sl)
227  {
228  if ( cbm::flt_equal_zero( v_water_sl[sl]) ||
229  cbm::flt_equal_zero( waterflux_sl[sl]))
230  {
231  continue;
232  }
233 
234  size_t sl_plus( sl + 1);
235  if ( cbm::flt_less( waterflux_sl[sl], 0.0))
236  {
237  sl_plus = sl - 1;
238  }
239 
240  //take absolute value (negative fluxes are handled by sl_plus
241  double const leach_fact( std::abs( waterflux_sl[sl] / v_water_sl[sl]));
242 
243  double const leach_fact_nh4( cbm::bound_max( leach_fact * sipar_.RETNH4(), 0.9999));
244  double const leach_fact_no3( cbm::bound_max( leach_fact * sipar_.RETNO3(), 0.9999));
245  double const leach_fact_doc( cbm::bound_max( leach_fact * sipar_.RETDOC(), 0.9999));
246  double const leach_fact_mic( cbm::bound_max( leach_fact * sipar_.METRX_RET_MICROBES(), 0.9999));
247  double const leach_fact_lit( cbm::bound_max( leach_fact * sipar_.METRX_RET_LITTER(), 0.9999));
248  double const leach_fact_hum( cbm::bound_max( leach_fact * sipar_.METRX_RET_HUMUS(), 0.9999));
249  double const leach_fact_dissolved_gases( cbm::bound_max( leach_fact, 0.9999));
250 
251  if ( spinup_.spinup_stage( this->lclock()))
252  {
253  spinup_.loose_lit_1[sl] += leach_fact_lit;
254  spinup_.loose_lit_2[sl] += leach_fact_lit;
255  spinup_.loose_lit_3[sl] += leach_fact_lit;
256 
257  spinup_.loose_aorg[sl] += leach_fact_mic;
258 
259  spinup_.decompose_hum_1[sl] += leach_fact_hum;
260  spinup_.decompose_hum_2[sl] += leach_fact_hum;
261  spinup_.decompose_hum_3[sl] += leach_fact_hum;
262 
263  spinup_.c_to_lit_1[sl_plus] += sc_.C_lit1_sl[sl] * leach_fact_lit;
264  spinup_.c_to_lit_2[sl_plus] += sc_.C_lit2_sl[sl] * leach_fact_lit;
265  spinup_.c_to_lit_3[sl_plus] += sc_.C_lit3_sl[sl] * leach_fact_lit;
266 
267  spinup_.c_to_aorg[sl_plus] += sc_.C_aorg_sl[sl] * leach_fact_mic;
268 
269  spinup_.c_to_humus_1_sl[sl_plus] += c_humus_1_sl[sl] * leach_fact_hum;
270  spinup_.c_to_humus_2_sl[sl_plus] += c_humus_2_sl[sl] * leach_fact_hum;
271  spinup_.c_to_humus_3_sl[sl_plus] += c_humus_3_sl[sl] * leach_fact_hum;
272  }
273 
274  accumulated_n_aorg_leaching_sl[sl] += sc_.N_aorg_sl[sl] * leach_fact_mic;
275  LEACH_DOWN( sc_.C_aorg_sl[sl], sc_.C_aorg_sl[sl_plus], leach_fact_mic);
276  LEACH_DOWN( sc_.N_aorg_sl[sl], sc_.N_aorg_sl[sl_plus], leach_fact_mic);
277 
278  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]));
279  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]));
280  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]));
281 
282  if( n_micro_1_sl[sl] > MeTrX_get_micro_n_decay_max( n_micro_1_sl[sl]) )
283  {
284  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;
285  }
286  if( n_micro_2_sl[sl] > MeTrX_get_micro_n_decay_max( n_micro_2_sl[sl]) )
287  {
288  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;
289  }
290  if( n_micro_3_sl[sl] > MeTrX_get_micro_n_decay_max( n_micro_3_sl[sl]) )
291  {
292  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;
293  }
294  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]));
295  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]));
296  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]));
297 
298  LEACH_DOWN( sc_.C_lit1_sl[sl], sc_.C_lit1_sl[sl_plus], leach_fact_lit);
299  LEACH_DOWN( sc_.C_lit2_sl[sl], sc_.C_lit2_sl[sl_plus], leach_fact_lit);
300  LEACH_DOWN( sc_.C_lit3_sl[sl], sc_.C_lit3_sl[sl_plus], leach_fact_lit);
301 
302  accumulated_n_litter_leaching_sl[sl] += (sc_.N_lit1_sl[sl]+sc_.N_lit2_sl[sl]+sc_.N_lit3_sl[sl]) * leach_fact_lit;
303  LEACH_DOWN( sc_.N_lit1_sl[sl], sc_.N_lit1_sl[sl_plus], leach_fact_lit);
304  LEACH_DOWN( sc_.N_lit2_sl[sl], sc_.N_lit2_sl[sl_plus], leach_fact_lit);
305  LEACH_DOWN( sc_.N_lit3_sl[sl], sc_.N_lit3_sl[sl_plus], leach_fact_lit);
306 
307  LEACH_DOWN( c_humus_1_sl[sl], c_humus_1_sl[sl_plus], leach_fact_hum);
308  LEACH_DOWN( c_humus_2_sl[sl], c_humus_2_sl[sl_plus], leach_fact_hum);
309  LEACH_DOWN( c_humus_3_sl[sl], c_humus_3_sl[sl_plus], leach_fact_hum);
310 
311  accumulated_n_humus_1_leaching_sl[sl] += n_humus_1_sl[sl] * leach_fact_hum;
312  accumulated_n_humus_2_leaching_sl[sl] += n_humus_2_sl[sl] * leach_fact_hum;
313  accumulated_n_humus_3_leaching_sl[sl] += n_humus_3_sl[sl] * leach_fact_hum;
314  LEACH_DOWN( n_humus_1_sl[sl], n_humus_1_sl[sl_plus], leach_fact_hum);
315  LEACH_DOWN( n_humus_2_sl[sl], n_humus_2_sl[sl_plus], leach_fact_hum);
316  LEACH_DOWN( n_humus_3_sl[sl], n_humus_3_sl[sl_plus], leach_fact_hum);
317 
318  accumulated_n_nh4_leaching_sl[sl] += (nh4_ae_sl[sl] + nh4_an_sl[sl] + sc_.coated_nh4_sl[sl]) * leach_fact_nh4;
319  accumulated_n_nh3_leaching_sl[sl] += sc_.nh3_liq_sl[sl] * leach_fact_doc;
320  accumulated_n_urea_leaching_sl[sl] += sc_.urea_sl[sl] * leach_fact_doc;
321  LEACH_DOWN( nh4_ae_sl[sl], nh4_ae_sl[sl_plus], leach_fact_nh4);
322  LEACH_DOWN( nh4_an_sl[sl], nh4_an_sl[sl_plus], leach_fact_nh4);
323  LEACH_DOWN( sc_.coated_nh4_sl[sl], sc_.coated_nh4_sl[sl_plus], leach_fact_nh4);
324  LEACH_DOWN( sc_.nh3_liq_sl[sl], sc_.nh3_liq_sl[sl_plus], leach_fact_doc);
325  LEACH_DOWN( sc_.urea_sl[sl], sc_.urea_sl[sl_plus], leach_fact_doc);
326 
327  sc_.accumulated_n_no3_leaching_sl[sl] += (no3_ae_sl[sl]+no3_an_sl[sl]) * leach_fact_no3;
328  LEACH_DOWN( no3_ae_sl[sl], no3_ae_sl[sl_plus], leach_fact_no3);
329  LEACH_DOWN( no3_an_sl[sl], no3_an_sl[sl_plus], leach_fact_no3);
330 
331  accumulated_n_don_leaching_sl[sl] += (don_ae_sl[sl] + don_an_sl[sl]) * leach_fact_doc;
332  LEACH_DOWN( don_ae_sl[sl], don_ae_sl[sl_plus], leach_fact_doc);
333  LEACH_DOWN( don_an_sl[sl], don_an_sl[sl_plus], leach_fact_doc);
334  LEACH_DOWN( sc_.doc_sl[sl], sc_.doc_sl[sl_plus], leach_fact_doc);
335  LEACH_DOWN( sc_.an_doc_sl[sl], sc_.an_doc_sl[sl_plus], leach_fact_doc);
336  LEACH_DOWN( ae_acetate_sl[sl], ae_acetate_sl[sl_plus], leach_fact_doc);
337  LEACH_DOWN( an_acetate_sl[sl], an_acetate_sl[sl_plus], leach_fact_doc);
338 
339  accumulated_n_no_leaching_sl[sl] += (no_liq_sl[sl]+an_no_liq_sl[sl]) * leach_fact_dissolved_gases;
340  accumulated_n_n2o_leaching_sl[sl] += (n2o_liq_sl[sl]+an_n2o_liq_sl[sl]) * leach_fact_dissolved_gases;
341  LEACH_DOWN( no_liq_sl[sl], no_liq_sl[sl_plus], leach_fact_dissolved_gases);
342  LEACH_DOWN( an_no_liq_sl[sl], an_no_liq_sl[sl_plus], leach_fact_dissolved_gases);
343  LEACH_DOWN( n2o_liq_sl[sl], n2o_liq_sl[sl_plus], leach_fact_dissolved_gases);
344  LEACH_DOWN( an_n2o_liq_sl[sl], an_n2o_liq_sl[sl_plus], leach_fact_dissolved_gases);
345 
346  LEACH_DOWN( ch4_liq_sl[sl], ch4_liq_sl[sl_plus], leach_fact_dissolved_gases);
347  LEACH_DOWN( co2_liq_sl[sl], co2_liq_sl[sl_plus], leach_fact_dissolved_gases);
348  LEACH_DOWN( o2_liq_sl[sl], o2_liq_sl[sl_plus], leach_fact_dissolved_gases);
349 
350  LEACH_DOWN( sc_.so4_sl[sl], sc_.so4_sl[sl_plus], leach_fact_no3);
351  LEACH_DOWN( sc_.ni_sl[sl], sc_.ni_sl[sl_plus], leach_fact_doc);
352  LEACH_DOWN( sc_.ui_sl[sl], sc_.ui_sl[sl_plus], leach_fact_doc);
353 
354  if ( have_radon_diffusion)
355  {
356  LEACH_DOWN( radon_liq_sl[sl], radon_liq_sl[sl_plus], leach_fact_dissolved_gases);
357  }
358  }
359 
360  size_t sl( sl_.soil_layer_cnt()-1);
361 
362  if ( cbm::flt_greater_zero( v_water_sl[sl]))
363  {
364  if ( cbm::flt_greater_zero( waterflux_sl[sl]))
365  {
366  double dummy_out( 0.0); //dummy for substances that are not balanced (no accumulated leaching variable exists)
367 
368  double const leach_fact( waterflux_sl[sl] / v_water_sl[sl]);
369 
370  double const leach_fact_nh4( cbm::bound_max( leach_fact * sipar_.RETNH4(), 0.9999));
371  double const leach_fact_no3( cbm::bound_max( leach_fact * sipar_.RETNO3(), 0.9999));
372  double const leach_fact_doc( cbm::bound_max( leach_fact * sipar_.RETDOC(), 0.9999));
373  double const leach_fact_mic( cbm::bound_max( leach_fact * sipar_.METRX_RET_MICROBES(), 0.9999));
374  double const leach_fact_lit( cbm::bound_max( leach_fact * sipar_.METRX_RET_LITTER(), 0.9999));
375  double const leach_fact_hum( cbm::bound_max( leach_fact * sipar_.METRX_RET_HUMUS(), 0.9999));
376  double const leach_fact_dissolved_gases( cbm::bound_max( leach_fact, 0.9999));
377 
378  if ( spinup_.spinup_stage( this->lclock()))
379  {
380  spinup_.loose_lit_1[sl] += leach_fact_lit;
381  spinup_.loose_lit_2[sl] += leach_fact_lit;
382  spinup_.loose_lit_3[sl] += leach_fact_lit;
383 
384  spinup_.loose_aorg[sl] += leach_fact_mic;
385 
386  spinup_.decompose_hum_1[sl] += leach_fact_hum;
387  spinup_.decompose_hum_2[sl] += leach_fact_hum;
388  spinup_.decompose_hum_3[sl] += leach_fact_hum;
389  }
390 
391  accumulated_n_aorg_leaching_sl[sl] += sc_.N_aorg_sl[sl] * leach_fact_mic;
392  LEACH_DOWN( sc_.C_aorg_sl[sl], sc_.accumulated_doc_leach, leach_fact_mic);
393  LEACH_DOWN( sc_.N_aorg_sl[sl], sc_.accumulated_don_leach, leach_fact_mic);
394 
395  LEACH_DOWN_EPSILON( sc_.C_micro1_sl[sl], sc_.accumulated_doc_leach, leach_fact_mic, MeTrX_get_micro_c_decay_max( sc_.C_micro1_sl[sl]));
396  LEACH_DOWN_EPSILON( sc_.C_micro2_sl[sl], sc_.accumulated_doc_leach, leach_fact_mic, MeTrX_get_micro_c_decay_max( sc_.C_micro2_sl[sl]));
397  LEACH_DOWN_EPSILON( sc_.C_micro3_sl[sl], sc_.accumulated_doc_leach, leach_fact_mic, MeTrX_get_micro_c_decay_max( sc_.C_micro3_sl[sl]));
398 
399  if( n_micro_1_sl[sl] > MeTrX_get_micro_n_decay_max( n_micro_1_sl[sl]) )
400  {
401  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;
402  }
403  if( n_micro_2_sl[sl] > MeTrX_get_micro_n_decay_max( n_micro_2_sl[sl]) )
404  {
405  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;
406  }
407  if( n_micro_3_sl[sl] > MeTrX_get_micro_n_decay_max( n_micro_3_sl[sl]) )
408  {
409  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;
410  }
411  LEACH_DOWN_EPSILON( n_micro_1_sl[sl], sc_.accumulated_don_leach, leach_fact_mic, MeTrX_get_micro_n_decay_max( n_micro_1_sl[sl]));
412  LEACH_DOWN_EPSILON( n_micro_2_sl[sl], sc_.accumulated_don_leach, leach_fact_mic, MeTrX_get_micro_n_decay_max( n_micro_2_sl[sl]));
413  LEACH_DOWN_EPSILON( n_micro_3_sl[sl], sc_.accumulated_don_leach, leach_fact_mic, MeTrX_get_micro_n_decay_max( n_micro_3_sl[sl]));
414 
415  LEACH_DOWN( sc_.C_lit1_sl[sl], sc_.accumulated_doc_leach, leach_fact_lit);
416  LEACH_DOWN( sc_.C_lit2_sl[sl], sc_.accumulated_doc_leach, leach_fact_lit);
417  LEACH_DOWN( sc_.C_lit3_sl[sl], sc_.accumulated_doc_leach, leach_fact_lit);
418 
419  accumulated_n_litter_leaching_sl[sl] += (sc_.N_lit1_sl[sl]+sc_.N_lit2_sl[sl]+sc_.N_lit3_sl[sl]) * leach_fact_lit;
420  LEACH_DOWN( sc_.N_lit1_sl[sl], sc_.accumulated_don_leach, leach_fact_lit);
421  LEACH_DOWN( sc_.N_lit2_sl[sl], sc_.accumulated_don_leach, leach_fact_lit);
422  LEACH_DOWN( sc_.N_lit3_sl[sl], sc_.accumulated_don_leach, leach_fact_lit);
423 
424  LEACH_DOWN( c_humus_1_sl[sl], sc_.accumulated_doc_leach, leach_fact_hum);
425  LEACH_DOWN( c_humus_2_sl[sl], sc_.accumulated_doc_leach, leach_fact_hum);
426  LEACH_DOWN( c_humus_3_sl[sl], sc_.accumulated_doc_leach, leach_fact_hum);
427 
428  accumulated_n_humus_1_leaching_sl[sl] += n_humus_1_sl[sl] * leach_fact_hum;
429  accumulated_n_humus_2_leaching_sl[sl] += n_humus_2_sl[sl] * leach_fact_hum;
430  accumulated_n_humus_3_leaching_sl[sl] += n_humus_3_sl[sl] * leach_fact_hum;
431  LEACH_DOWN( n_humus_1_sl[sl], sc_.accumulated_don_leach, leach_fact_hum);
432  LEACH_DOWN( n_humus_2_sl[sl], sc_.accumulated_don_leach, leach_fact_hum);
433  LEACH_DOWN( n_humus_2_sl[sl], sc_.accumulated_don_leach, leach_fact_hum);
434 
435  accumulated_n_nh4_leaching_sl[sl] += (nh4_ae_sl[sl] + nh4_an_sl[sl] + sc_.coated_nh4_sl[sl]) * leach_fact_nh4;
436  accumulated_n_nh3_leaching_sl[sl] += sc_.nh3_liq_sl[sl] * leach_fact_doc;
437  accumulated_n_urea_leaching_sl[sl] += sc_.urea_sl[sl] * leach_fact_doc;
438  LEACH_DOWN( nh4_ae_sl[sl], sc_.accumulated_nh4_leach, leach_fact_nh4);
439  LEACH_DOWN( nh4_an_sl[sl], sc_.accumulated_nh4_leach, leach_fact_nh4);
440  LEACH_DOWN( sc_.coated_nh4_sl[sl], sc_.accumulated_nh4_leach, leach_fact_nh4);
441  LEACH_DOWN( sc_.nh3_liq_sl[sl], day_leach_nh3, leach_fact_doc);
442  LEACH_DOWN( sc_.urea_sl[sl], day_leach_urea, leach_fact_doc);
443 
444  sc_.accumulated_n_no3_leaching_sl[sl] += (no3_ae_sl[sl]+no3_an_sl[sl]) * leach_fact_no3;
445  LEACH_DOWN( no3_ae_sl[sl], sc_.accumulated_no3_leach, leach_fact_no3);
446  LEACH_DOWN( no3_an_sl[sl], sc_.accumulated_no3_leach, leach_fact_no3);
447 
448  accumulated_n_don_leaching_sl[sl] += (don_ae_sl[sl] + don_an_sl[sl]) * leach_fact_doc;
449  LEACH_DOWN( don_ae_sl[sl], sc_.accumulated_don_leach, leach_fact_doc);
450  LEACH_DOWN( don_an_sl[sl], sc_.accumulated_don_leach, leach_fact_doc);
451  LEACH_DOWN( sc_.doc_sl[sl], sc_.accumulated_doc_leach, leach_fact_doc);
452  LEACH_DOWN( sc_.an_doc_sl[sl], sc_.accumulated_doc_leach, leach_fact_doc);
453  LEACH_DOWN( ae_acetate_sl[sl], sc_.accumulated_doc_leach, leach_fact_doc);
454  LEACH_DOWN( an_acetate_sl[sl], sc_.accumulated_doc_leach, leach_fact_doc);
455 
456  accumulated_n_no_leaching_sl[sl] += (no_liq_sl[sl]+an_no_liq_sl[sl]) * leach_fact_dissolved_gases;
457  accumulated_n_n2o_leaching_sl[sl] += (n2o_liq_sl[sl]+an_n2o_liq_sl[sl]) * leach_fact_dissolved_gases;
458  LEACH_DOWN( no_liq_sl[sl], day_leach_no, leach_fact_dissolved_gases);
459  LEACH_DOWN( an_no_liq_sl[sl], day_leach_no, leach_fact_dissolved_gases);
460  LEACH_DOWN( n2o_liq_sl[sl], day_leach_n2o, leach_fact_dissolved_gases);
461  LEACH_DOWN( an_n2o_liq_sl[sl], day_leach_n2o, leach_fact_dissolved_gases);
462  LEACH_DOWN( o2_liq_sl[sl], day_leach_o2, leach_fact_dissolved_gases);
463 
464  LEACH_DOWN( ch4_liq_sl[sl], subdaily_ch4_leach[subdaily_time_step_], leach_fact_dissolved_gases);
465  LEACH_DOWN( co2_liq_sl[sl], subdaily_co2_leach[subdaily_time_step_], leach_fact_dissolved_gases);
466 
467  LEACH_DOWN( sc_.so4_sl[sl], sc_.accumulated_so4_leach, leach_fact_no3);
468  LEACH_DOWN( sc_.ni_sl[sl], dummy_out, leach_fact_doc);
469  LEACH_DOWN( sc_.ui_sl[sl], dummy_out, leach_fact_doc);
470 
471  if ( have_radon_diffusion)
472  {
473  LEACH_DOWN( radon_liq_sl[sl], day_leach_radon, leach_fact_dissolved_gases);
474  }
475  }
476  else if ( cbm::flt_less( waterflux_sl[sl], 0.0))
477  {
478  size_t sl_plus( sl - 1);
479 
480  double const leach_fact( -1.0 * waterflux_sl[sl] / v_water_sl[sl]);
481 
482  double const leach_fact_nh4( cbm::bound_max( leach_fact * sipar_.RETNH4(), 0.9999));
483  double const leach_fact_no3( cbm::bound_max( leach_fact * sipar_.RETNO3(), 0.9999));
484  double const leach_fact_doc( cbm::bound_max( leach_fact * sipar_.RETDOC(), 0.9999));
485  double const leach_fact_mic( cbm::bound_max( leach_fact * sipar_.METRX_RET_MICROBES(), 0.9999));
486  double const leach_fact_lit( cbm::bound_max( leach_fact * sipar_.METRX_RET_LITTER(), 0.9999));
487  double const leach_fact_hum( cbm::bound_max( leach_fact * sipar_.METRX_RET_HUMUS(), 0.9999));
488  double const leach_fact_dissolved_gases( cbm::bound_max( leach_fact, 0.9999));
489 
490  if ( spinup_.spinup_stage( this->lclock()))
491  {
492  spinup_.loose_lit_1[sl] += leach_fact_lit;
493  spinup_.loose_lit_2[sl] += leach_fact_lit;
494  spinup_.loose_lit_3[sl] += leach_fact_lit;
495 
496  spinup_.loose_aorg[sl] += leach_fact_mic;
497 
498  spinup_.decompose_hum_1[sl] += leach_fact_hum;
499  spinup_.decompose_hum_2[sl] += leach_fact_hum;
500  spinup_.decompose_hum_3[sl] += leach_fact_hum;
501 
502  spinup_.c_to_lit_1[sl_plus] += sc_.C_lit1_sl[sl] * leach_fact_lit;
503  spinup_.c_to_lit_2[sl_plus] += sc_.C_lit2_sl[sl] * leach_fact_lit;
504  spinup_.c_to_lit_3[sl_plus] += sc_.C_lit3_sl[sl] * leach_fact_lit;
505 
506  spinup_.c_to_aorg[sl_plus] += sc_.C_aorg_sl[sl] * leach_fact_mic;
507 
508  spinup_.c_to_humus_1_sl[sl_plus] += c_humus_1_sl[sl] * leach_fact_hum;
509  spinup_.c_to_humus_2_sl[sl_plus] += c_humus_2_sl[sl] * leach_fact_hum;
510  spinup_.c_to_humus_3_sl[sl_plus] += c_humus_3_sl[sl] * leach_fact_hum;
511  }
512 
513  accumulated_n_aorg_leaching_sl[sl] += sc_.N_aorg_sl[sl] * leach_fact_mic;
514  LEACH_DOWN( sc_.C_aorg_sl[sl], sc_.C_aorg_sl[sl_plus], leach_fact_mic);
515  LEACH_DOWN( sc_.N_aorg_sl[sl], sc_.N_aorg_sl[sl_plus], leach_fact_mic);
516 
517  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]));
518  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]));
519  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]));
520 
521  if( n_micro_1_sl[sl] > MeTrX_get_micro_n_decay_max( n_micro_1_sl[sl]) )
522  {
523  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;
524  }
525  if( n_micro_2_sl[sl] > MeTrX_get_micro_n_decay_max( n_micro_2_sl[sl]) )
526  {
527  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;
528  }
529  if( n_micro_3_sl[sl] > MeTrX_get_micro_n_decay_max( n_micro_3_sl[sl]) )
530  {
531  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;
532  }
533  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]));
534  LEACH_DOWN_EPSILON( n_micro_2_sl[sl], n_micro_1_sl[sl_plus], leach_fact_mic, MeTrX_get_micro_n_decay_max( n_micro_2_sl[sl]));
535  LEACH_DOWN_EPSILON( n_micro_3_sl[sl], n_micro_1_sl[sl_plus], leach_fact_mic, MeTrX_get_micro_n_decay_max( n_micro_3_sl[sl]));
536 
537  LEACH_DOWN( sc_.C_lit1_sl[sl], sc_.C_lit1_sl[sl_plus], leach_fact_lit);
538  LEACH_DOWN( sc_.C_lit2_sl[sl], sc_.C_lit2_sl[sl_plus], leach_fact_lit);
539  LEACH_DOWN( sc_.C_lit3_sl[sl], sc_.C_lit3_sl[sl_plus], leach_fact_lit);
540 
541  accumulated_n_litter_leaching_sl[sl] += (sc_.N_lit1_sl[sl]+sc_.N_lit2_sl[sl]+sc_.N_lit3_sl[sl]) * leach_fact_lit;
542  LEACH_DOWN( sc_.N_lit1_sl[sl], sc_.N_lit1_sl[sl_plus], leach_fact_lit);
543  LEACH_DOWN( sc_.N_lit2_sl[sl], sc_.N_lit2_sl[sl_plus], leach_fact_lit);
544  LEACH_DOWN( sc_.N_lit3_sl[sl], sc_.N_lit3_sl[sl_plus], leach_fact_lit);
545 
546  LEACH_DOWN( c_humus_1_sl[sl], c_humus_1_sl[sl_plus], leach_fact_hum);
547  LEACH_DOWN( c_humus_2_sl[sl], c_humus_2_sl[sl_plus], leach_fact_hum);
548  LEACH_DOWN( c_humus_3_sl[sl], c_humus_3_sl[sl_plus], leach_fact_hum);
549 
550  accumulated_n_humus_1_leaching_sl[sl] += n_humus_1_sl[sl] * leach_fact_hum;
551  accumulated_n_humus_2_leaching_sl[sl] += n_humus_2_sl[sl] * leach_fact_hum;
552  accumulated_n_humus_3_leaching_sl[sl] += n_humus_3_sl[sl] * leach_fact_hum;
553  LEACH_DOWN( n_humus_1_sl[sl], n_humus_1_sl[sl_plus], leach_fact_hum);
554  LEACH_DOWN( n_humus_2_sl[sl], n_humus_2_sl[sl_plus], leach_fact_hum);
555  LEACH_DOWN( n_humus_2_sl[sl], n_humus_3_sl[sl_plus], leach_fact_hum);
556 
557  accumulated_n_nh4_leaching_sl[sl] += (nh4_ae_sl[sl] + nh4_an_sl[sl] + sc_.coated_nh4_sl[sl]) * leach_fact_nh4;
558  accumulated_n_nh3_leaching_sl[sl] += sc_.nh3_liq_sl[sl] * leach_fact_doc;
559  accumulated_n_urea_leaching_sl[sl] += sc_.urea_sl[sl] * leach_fact_doc;
560  LEACH_DOWN( nh4_ae_sl[sl], nh4_ae_sl[sl_plus], leach_fact_nh4);
561  LEACH_DOWN( nh4_an_sl[sl], nh4_an_sl[sl_plus], leach_fact_nh4);
562  LEACH_DOWN( sc_.coated_nh4_sl[sl], sc_.coated_nh4_sl[sl_plus], leach_fact_nh4);
563  LEACH_DOWN( sc_.nh3_liq_sl[sl], sc_.nh3_liq_sl[sl_plus], leach_fact_doc);
564  LEACH_DOWN( sc_.urea_sl[sl], sc_.urea_sl[sl_plus], leach_fact_doc);
565 
566  sc_.accumulated_n_no3_leaching_sl[sl] += (no3_ae_sl[sl]+no3_an_sl[sl]) * leach_fact_no3;
567  LEACH_DOWN( no3_ae_sl[sl], no3_ae_sl[sl_plus], leach_fact_no3);
568  LEACH_DOWN( no3_an_sl[sl], no3_an_sl[sl_plus], leach_fact_no3);
569 
570  accumulated_n_don_leaching_sl[sl] += (don_ae_sl[sl] + don_an_sl[sl]) * leach_fact_doc;
571  LEACH_DOWN( don_ae_sl[sl], don_ae_sl[sl_plus], leach_fact_doc);
572  LEACH_DOWN( don_an_sl[sl], don_an_sl[sl_plus], leach_fact_doc);
573  LEACH_DOWN( sc_.doc_sl[sl], sc_.doc_sl[sl_plus], leach_fact_doc);
574  LEACH_DOWN( sc_.an_doc_sl[sl], sc_.an_doc_sl[sl_plus], leach_fact_doc);
575  LEACH_DOWN( ae_acetate_sl[sl], ae_acetate_sl[sl_plus], leach_fact_doc);
576  LEACH_DOWN( an_acetate_sl[sl], an_acetate_sl[sl_plus], leach_fact_doc);
577 
578  accumulated_n_no_leaching_sl[sl] += (no_liq_sl[sl]+an_no_liq_sl[sl]) * leach_fact_dissolved_gases;
579  accumulated_n_n2o_leaching_sl[sl] += (n2o_liq_sl[sl]+an_n2o_liq_sl[sl]) * leach_fact_dissolved_gases;
580  LEACH_DOWN( no_liq_sl[sl], no_liq_sl[sl_plus], leach_fact_dissolved_gases);
581  LEACH_DOWN( an_no_liq_sl[sl], an_no_liq_sl[sl_plus], leach_fact_dissolved_gases);
582  LEACH_DOWN( n2o_liq_sl[sl], n2o_liq_sl[sl_plus], leach_fact_dissolved_gases);
583  LEACH_DOWN( an_n2o_liq_sl[sl], an_n2o_liq_sl[sl_plus], leach_fact_dissolved_gases);
584  LEACH_DOWN( o2_liq_sl[sl], o2_liq_sl[sl_plus], leach_fact_dissolved_gases);
585 
586  LEACH_DOWN( ch4_liq_sl[sl], ch4_liq_sl[sl_plus], leach_fact_dissolved_gases);
587  LEACH_DOWN( co2_liq_sl[sl], co2_liq_sl[sl_plus], leach_fact_dissolved_gases);
588 
589  LEACH_DOWN( sc_.so4_sl[sl], sc_.so4_sl[sl_plus], leach_fact_no3);
590  LEACH_DOWN( sc_.ni_sl[sl], sc_.ni_sl[sl_plus], leach_fact_doc);
591  LEACH_DOWN( sc_.ui_sl[sl], sc_.ui_sl[sl_plus], leach_fact_doc);
592 
593  if ( have_radon_diffusion)
594  {
595  LEACH_DOWN( radon_liq_sl[sl], radon_liq_sl[sl_plus], leach_fact_dissolved_gases);
596  }
597  }
598  }
599 }
Here is the caller graph for this function:

◆ MeTrX_liq_diffusion()

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

Referenced by MeTrX_groundwater_access(), and solve().

Here is the caller graph for this function:

◆ MeTrX_manure()

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

Referenced by solve().

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

◆ MeTrX_metabolism()

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

Referenced by solve().

216 {
217  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
218  {
219  double const metabolism_rate( 0.1 * FTS_TOT_);
220 
221  double const mic_12( sc_.C_micro1_sl[sl] + sc_.C_micro2_sl[sl]);
222  double const mic_23( sc_.C_micro2_sl[sl] + sc_.C_micro3_sl[sl]);
223 
224  if ( cbm::flt_greater_zero( mic_12))
225  {
226  double const fact_mic_12( sc_.anvf_sl[sl]);
227  double trans_12( (fact_mic_12 * mic_12 - sc_.C_micro2_sl[sl]) * metabolism_rate);
228  if ( cbm::flt_greater_zero( trans_12))
229  {
230  double const trans_max( cbm::bound_min( 0.0, sc_.C_micro1_sl[sl] - MICRO_C_MIN));
231  trans_12 = cbm::bound_max( trans_12, trans_max);
232  sc_.C_micro1_sl[sl] -= trans_12;
233  sc_.C_micro2_sl[sl] += trans_12;
234  }
235  else
236  {
237  double const trans_max( cbm::bound_min( 0.0, sc_.C_micro2_sl[sl] - MICRO_C_MIN));
238  trans_12 = cbm::bound_max( -trans_12, trans_max);
239  sc_.C_micro2_sl[sl] -= trans_12;
240  sc_.C_micro1_sl[sl] += trans_12;
241  }
242  }
243 
244  if ( cbm::flt_greater_zero( mic_23))
245  {
246  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)));
247  double trans_23( (fact_mic_23 * mic_23 - sc_.C_micro3_sl[sl]) * metabolism_rate);
248  if ( cbm::flt_greater_zero( trans_23))
249  {
250  double const trans_max( cbm::bound_min( 0.0, sc_.C_micro2_sl[sl] - MICRO_C_MIN));
251  trans_23 = cbm::bound_max( trans_23, trans_max);
252  sc_.C_micro2_sl[sl] -= trans_23;
253  sc_.C_micro3_sl[sl] += trans_23;
254  }
255  else
256  {
257  double const trans_max( cbm::bound_min( 0.0, sc_.C_micro3_sl[sl] - MICRO_C_MIN));
258  trans_23 = cbm::bound_max( -trans_23, trans_max);
259  sc_.C_micro3_sl[sl] -= trans_23;
260  sc_.C_micro2_sl[sl] += trans_23;
261  }
262  }
263  }
264  return LDNDC_ERR_OK;
265 }
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  }
86 }
double MeTrX_get_ph_wl()
Definition: soilchemistry-metrx-physics-chemistry.cpp:601
Here is the call graph for this function:
Here is the caller graph for this function:

◆ MeTrX_nitrification()

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

Referenced by solve().

Here is the caller graph for this function:

◆ MeTrX_nitrogen_fertilizer_release()

lerr_t ldndc::SoilChemistryMeTrX::MeTrX_nitrogen_fertilizer_release ( )
private

Transforms nitrogen from slow release nitrogen fertilizer to nh4.

Parameters
[in]None
[out]None
Returns
void

Referenced by solve().

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

◆ MeTrX_pertubation()

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

References MeTrX_anaerobic_volume().

Referenced by solve().

1639 {
1640  //Pertubation is only calculated once per day since it is a very slow process
1641  if ( lclock()->subday() == 1)
1642  {
1643  size_t sl_max_1( sl_.soil_layer_cnt()-1);
1644  double nmicro1_lowest_sl(n_micro_1_sl[sl_max_1]);
1645  double nmicro2_lowest_sl(n_micro_2_sl[sl_max_1]);
1646  double nmicro3_lowest_sl(n_micro_3_sl[sl_max_1]);
1647  double naorg_lowest_sl(sc_.N_aorg_sl[sl_max_1]);
1648  double nlit1_lowest_sl(sc_.N_lit1_sl[sl_max_1]);
1649  double nlit2_lowest_sl(sc_.N_lit2_sl[sl_max_1]);
1650  double nlit3_lowest_sl(sc_.N_lit3_sl[sl_max_1]);
1651  double nhum1_lowest_sl(n_humus_1_sl[sl_max_1]);
1652  double nhum2_lowest_sl(n_humus_2_sl[sl_max_1]);
1653  double nhum3_lowest_sl(n_humus_3_sl[sl_max_1]);
1654 
1655  lerr_t rc = transport_.pertubation(1.0, D_eff_dailyturbation_sl, sc_.C_micro1_sl, sc_.h_sl, interface_delta_x_soil_sl);
1656  if ( rc){ return rc; }
1657  rc = transport_.pertubation(1.0, D_eff_dailyturbation_sl, n_micro_1_sl, sc_.h_sl, interface_delta_x_soil_sl);
1658  if ( rc){ return rc; }
1659 
1660  rc = transport_.pertubation(1.0, D_eff_dailyturbation_sl, sc_.C_micro2_sl, sc_.h_sl, interface_delta_x_soil_sl);
1661  if ( rc){ return rc; }
1662  rc = transport_.pertubation(1.0, D_eff_dailyturbation_sl, n_micro_2_sl, sc_.h_sl, interface_delta_x_soil_sl);
1663  if ( rc){ return rc; }
1664 
1665  rc = transport_.pertubation(1.0, D_eff_dailyturbation_sl, sc_.C_micro3_sl, sc_.h_sl, interface_delta_x_soil_sl);
1666  if ( rc){ return rc; }
1667  rc = transport_.pertubation(1.0, D_eff_dailyturbation_sl, n_micro_3_sl, sc_.h_sl, interface_delta_x_soil_sl);
1668  if ( rc){ return rc; }
1669 
1670  rc = transport_.pertubation(1.0, D_eff_dailyturbation_sl, sc_.C_aorg_sl, sc_.h_sl, interface_delta_x_soil_sl);
1671  if ( rc){ return rc; }
1672  rc = transport_.pertubation(1.0, D_eff_dailyturbation_sl, sc_.N_aorg_sl, sc_.h_sl, interface_delta_x_soil_sl);
1673  if ( rc){ return rc; }
1674 
1675  rc = transport_.pertubation(1.0, D_eff_dailyturbation_sl, sc_.C_lit1_sl, sc_.h_sl, interface_delta_x_soil_sl);
1676  if ( rc){ return rc; }
1677  rc = transport_.pertubation(1.0, D_eff_dailyturbation_sl, sc_.N_lit1_sl, sc_.h_sl, interface_delta_x_soil_sl);
1678  if ( rc){ return rc; }
1679 
1680  rc = transport_.pertubation(1.0, D_eff_dailyturbation_sl, sc_.C_lit2_sl, sc_.h_sl, interface_delta_x_soil_sl);
1681  if ( rc){ return rc; }
1682  rc = transport_.pertubation(1.0, D_eff_dailyturbation_sl, sc_.N_lit2_sl, sc_.h_sl, interface_delta_x_soil_sl);
1683  if ( rc){ return rc; }
1684 
1685  rc = transport_.pertubation(1.0, D_eff_dailyturbation_sl, sc_.C_lit3_sl, sc_.h_sl, interface_delta_x_soil_sl);
1686  if ( rc){ return rc; }
1687  rc = transport_.pertubation(1.0, D_eff_dailyturbation_sl, sc_.N_lit3_sl, sc_.h_sl, interface_delta_x_soil_sl);
1688  if ( rc){ return rc; }
1689 
1690  rc = transport_.pertubation(1.0, D_eff_dailyturbation_sl, c_humus_1_sl, sc_.h_sl, interface_delta_x_soil_sl);
1691  if ( rc){ return rc; }
1692  rc = transport_.pertubation(1.0, D_eff_dailyturbation_sl, n_humus_1_sl, sc_.h_sl, interface_delta_x_soil_sl);
1693  if ( rc){ return rc; }
1694 
1695  rc = transport_.pertubation(1.0, D_eff_dailyturbation_sl, c_humus_2_sl, sc_.h_sl, interface_delta_x_soil_sl);
1696  if ( rc){ return rc; }
1697  rc = transport_.pertubation(1.0, D_eff_dailyturbation_sl, n_humus_2_sl, sc_.h_sl, interface_delta_x_soil_sl);
1698  if ( rc){ return rc; }
1699 
1700  rc = transport_.pertubation(1.0, D_eff_dailyturbation_sl, c_humus_3_sl, sc_.h_sl, interface_delta_x_soil_sl);
1701  if ( rc){ return rc; }
1702  rc = transport_.pertubation(1.0, D_eff_dailyturbation_sl, n_humus_3_sl, sc_.h_sl, interface_delta_x_soil_sl);
1703  if ( rc){ return rc; }
1704 
1705  if ( output_writer_.write_fluxes())
1706  {
1707  /* nmicro */
1708  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);
1709  for (size_t sl = 0; sl < sl_.soil_layer_cnt(); sl++)
1710  {
1711  accumulated_n_micro_perturbation_sl[sl] += communicate_sl[sl];
1712  }
1713  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);
1714  for (size_t sl = 0; sl < sl_.soil_layer_cnt(); sl++)
1715  {
1716  accumulated_n_micro_perturbation_sl[sl] += communicate_sl[sl];
1717  }
1718  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);
1719  for (size_t sl = 0; sl < sl_.soil_layer_cnt(); sl++)
1720  {
1721  accumulated_n_micro_perturbation_sl[sl] += communicate_sl[sl];
1722  }
1723 
1724  /* naorg */
1725  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);
1726  for (size_t sl = 0; sl < sl_.soil_layer_cnt(); sl++)
1727  {
1728  accumulated_n_aorg_perturbation_sl[sl] += communicate_sl[sl];
1729  }
1730 
1731  /*litter*/
1732  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);
1733  for (size_t sl = 0; sl < sl_.soil_layer_cnt(); sl++)
1734  {
1735  accumulated_n_litter_perturbation_sl[sl] += communicate_sl[sl];
1736  }
1737  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);
1738  for (size_t sl = 0; sl < sl_.soil_layer_cnt(); sl++)
1739  {
1740  accumulated_n_litter_perturbation_sl[sl] += communicate_sl[sl];
1741  }
1742  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);
1743  for (size_t sl = 0; sl < sl_.soil_layer_cnt(); sl++)
1744  {
1745  accumulated_n_litter_perturbation_sl[sl] += communicate_sl[sl];
1746  }
1747 
1748  /*humus*/
1749  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);
1750  for (size_t sl = 0; sl < sl_.soil_layer_cnt(); sl++)
1751  {
1752  accumulated_n_humus_1_perturbation_sl[sl] += communicate_sl[sl];
1753  }
1754  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);
1755  for (size_t sl = 0; sl < sl_.soil_layer_cnt(); sl++)
1756  {
1757  accumulated_n_humus_2_perturbation_sl[sl] += communicate_sl[sl];
1758  }
1759  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);
1760  for (size_t sl = 0; sl < sl_.soil_layer_cnt(); sl++)
1761  {
1762  accumulated_n_humus_3_perturbation_sl[sl] += communicate_sl[sl];
1763  }
1764  }
1765  }
1766  return LDNDC_ERR_OK;
1767 }
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().

616 {
617  for ( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
618  {
619  sc_.ph_sl[sl] = MeTrX_get_ph_sl( sl);
620  }
621 }
double MeTrX_get_ph_sl(size_t)
Returns dynamic pH-value of given soil layer.
Definition: soilchemistry-metrx-physics-chemistry.cpp:593
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

Referenced by MeTrX_clay_nh4_equilibrium(), and solve().

Here is the caller graph for this function:

◆ MeTrX_radon_source_sink()

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

Referenced by solve().

476 {
477  if ( have_radon_diffusion)
478  {
479  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
480  {
481  //timestep in seconds
482  double const Delta_t( 3600 * 24.0 / (double)TOTAL_TIME_STEPS );
483 
484  //emanation coefficient
485  double emanation_coeff( sc_.sand_sl[sl] * radon_emanation_coeff( sl, sipar_.METRX_RADON_EMANATION_SAND_EPS0(), sipar_.METRX_RADON_EMANATION_SAND_A(), sipar_.METRX_RADON_EMANATION_SAND_B(), sipar_.METRX_RADON_EMANATION_SAND_C())
486  + sc_.silt_sl[sl] * radon_emanation_coeff( sl, sipar_.METRX_RADON_EMANATION_SILT_EPS0(), sipar_.METRX_RADON_EMANATION_SILT_A(), sipar_.METRX_RADON_EMANATION_SILT_B(), sipar_.METRX_RADON_EMANATION_SILT_C())
487  + sc_.clay_sl[sl] * radon_emanation_coeff( sl, sipar_.METRX_RADON_EMANATION_CLAY_EPS0(), sipar_.METRX_RADON_EMANATION_CLAY_A(), sipar_.METRX_RADON_EMANATION_CLAY_B(), sipar_.METRX_RADON_EMANATION_CLAY_C()) );
488 
489  //radon source/sink term: creation of radon-222 via the decay of radium-226
490  // and its radioactive decay
491  radon_gas_sl[sl] += sipar_.METRX_RADON_DECAY_CONST() * Delta_t * sc_.radium_sl[sl] * sc_.h_sl[sl] * 1000 * sc_.dens_sl[sl] * emanation_coeff
492  - Delta_t * sipar_.METRX_RADON_DECAY_CONST() * radon_gas_sl[sl];
493 
494  //radon sink term: radioactive decay of radon
495  //radon_gas_sl[sl] -= Delta_t * sipar_.METRX_RADON_DECAY_CONST() * radon_gas_sl[sl];
496  radon_liq_sl[sl] -= Delta_t * sipar_.METRX_RADON_DECAY_CONST() * radon_liq_sl[sl];
497  }
498  }
499  return LDNDC_ERR_OK;
500 }
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().

261 {
262  for ( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
263  {
264  if ( cbm::flt_greater_zero( sc_.nh4_sl[sl]))
265  {
266  double const nh4_old( nh4_ae_sl[sl] + nh4_an_sl[sl]);
267  if ( cbm::flt_greater_zero( nh4_old))
268  {
269  nh4_ae_sl[sl] = cbm::bound_min( 0.0, nh4_ae_sl[sl] / nh4_old * sc_.nh4_sl[sl]);
270  nh4_an_sl[sl] = cbm::bound_min( 0.0, sc_.nh4_sl[sl] - nh4_ae_sl[sl]);
271  }
272  else
273  {
274  nh4_ae_sl[sl] = (1.0 - sc_.anvf_sl[sl]) * sc_.nh4_sl[sl];
275  nh4_an_sl[sl] = sc_.anvf_sl[sl] * sc_.nh4_sl[sl];
276  }
277  }
278  else
279  {
280  nh4_ae_sl[sl] = 0.0;
281  nh4_an_sl[sl] = 0.0;
282  }
283 
284  if ( cbm::flt_greater_zero( sc_.don_sl[sl]))
285  {
286  double const don_old( don_ae_sl[sl] + don_an_sl[sl]);
287  if ( cbm::flt_greater_zero( don_old))
288  {
289  don_ae_sl[sl] = cbm::bound_min( 0.0, don_ae_sl[sl] / don_old * sc_.don_sl[sl]);
290  don_an_sl[sl] = cbm::bound_min( 0.0, sc_.don_sl[sl] - don_ae_sl[sl]);
291  }
292  else
293  {
294  don_ae_sl[sl] = (1.0 - sc_.anvf_sl[sl]) * sc_.don_sl[sl];
295  don_an_sl[sl] = sc_.anvf_sl[sl] * sc_.don_sl[sl];
296  }
297  }
298  else
299  {
300  don_ae_sl[sl] = 0.0;
301  don_an_sl[sl] = 0.0;
302  }
303 
304  double no3_tot( sc_.no3_sl[sl] + sc_.an_no3_sl[sl]);
305  if ( cbm::flt_greater_zero( no3_tot))
306  {
307  double const no3_old( no3_ae_sl[sl] + no3_an_sl[sl]);
308  if ( cbm::flt_greater_zero( no3_old))
309  {
310  no3_ae_sl[sl] = cbm::bound_min( 0.0, no3_ae_sl[sl] / no3_old * no3_tot);
311  no3_an_sl[sl] = cbm::bound_min( 0.0, no3_tot - no3_ae_sl[sl]);
312  }
313  else
314  {
315  no3_ae_sl[sl] = (1.0 - sc_.anvf_sl[sl]) * no3_tot;
316  no3_an_sl[sl] = sc_.anvf_sl[sl] * no3_tot;
317  }
318  }
319  else
320  {
321  no3_ae_sl[sl] = 0.0;
322  no3_an_sl[sl] = 0.0;
323  }
324  }
325 
326  return LDNDC_ERR_OK;
327 }
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().

186 {
187  co2_auto_sl = 0.0;
188  co2_hetero_sl = 0.0;
189 
190  if ( timemode_ == TMODE_SUBDAILY)
191  {
192  if ( lclock()->is_position( TMODE_PRE_DAILY))
193  {
196  }
197  }
198  else
199  {
202  }
203 
204  return LDNDC_ERR_OK;
205 }
lerr_t MeTrX_reset_subdaily()
Definition: soilchemistry-metrx-reset.cpp:213
lerr_t MeTrX_reset_daily()
Definition: soilchemistry-metrx-reset.cpp:265
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().

266 {
267  /* Soil layer variables */
268  for (size_t sl = 0; sl < sl_.soil_layer_cnt(); sl++)
269  {
270  plant_o2_consumption_sl[sl] = 0.0;
271 
272  day_nitrify_n2o_sl[sl] = 0.0;
273  day_nit_no2_no3_sl[sl] = 0.0;
274 
275  day_acetate_cons_fe3_sl[sl] = 0.0;
276  day_h2_c_eq_cons_fe3_sl[sl] = 0.0;
277  day_fe2_oxidation_sl[sl] = 0.0;
278 
279  day_acetate_prod_sl[sl] = 0.0;
280 
281  day_ch4_oxidation_sl[sl] = 0.0;
282 
283  day_h2_c_eq_prod_sl[sl] = 0.0;
284  day_ch4_production_acetate_sl[sl] = 0.0;
285  day_ch4_production_hydrogen_sl[sl] = 0.0;
286 
287  day_doc_prod_sl[sl] = 0.0;
288  day_denit_factor_c_sl[sl] = 0.0;
289  day_denit_factor_n_sl[sl] = 0.0;
290  }
291 
292  // Groundwater access
293  day_no3_groundwater_access = 0.0;
294 
295  // Mineralisation
296  day_min_n_decomp = 0.0;
297  day_min_n_aorg = 0.0;
298  day_min_n_mic_1 = 0.0;
299  day_min_n_mic_2 = 0.0;
300  day_min_n_mic_3 = 0.0;
301 
302  // Assimilation
303  day_assi_n_mic_1 = 0.0;
304  day_assi_n_mic_2 = 0.0;
305  day_assi_n_mic_3 = 0.0;
306  day_assi_c_mic_1 = 0.0;
307  day_assi_c_mic_2 = 0.0;
308  day_assi_c_mic_3 = 0.0;
309 
310  // Nitrification
311  day_nit_nh4_no2 = 0.0;
312  day_nit_no2_no = 0.0;
313  day_nit_no2_n2o = 0.0;
314  day_nit_no2_no3_sl = 0.0;
315 
316  // Denitrification
317  day_denit_no3_no2 = 0.0;
318  day_denit_no2_no = 0.0;
319  day_denit_no2_n2o = 0.0;
320  day_denit_no2_n2 = 0.0;
321  day_denit_no_n2o = 0.0;
322  day_denit_no_n2 = 0.0;
323  day_denit_n2o_n2 = 0.0;
324  day_chemodenit_no2_no = 0.0;
325 
326  // Respiration / Fermentation / Methanogenesis
327  day_co2_prod_mic_1_growth = 0.0;
328  day_co2_prod_mic_1_maintenance = 0.0;
329  day_co2_prod_mic_2 = 0.0;
330  day_co2_prod_mic_3_acetate_prod = 0.0;
331  day_co2_prod_mic_3_acetate_cons = 0.0;
332  day_co2_prod_ch4_prod = 0.0;
333  day_co2_prod_ch4_cons = 0.0;
334 
335  // Leaching
336  day_leach_o2 = 0.0;
337  day_leach_n2o = 0.0;
338  day_leach_n2 = 0.0;
339  day_leach_no = 0.0;
340  day_leach_nh3 = 0.0;
341  day_leach_urea = 0.0;
342  day_leach_radon = 0.0;
343 
344  // litter
345  dC_root_exsudates = 0.0;
346  dC_litter_algae = 0.0;
347 
348  // Decomposition
349  day_decomp_c_lit_1 = 0.0;
350  day_decomp_c_lit_2 = 0.0;
351  day_decomp_c_lit_3 = 0.0;
352  day_decomp_n_lit_1 = 0.0;
353  day_decomp_n_lit_2 = 0.0;
354  day_decomp_n_lit_3 = 0.0;
355  day_decomp_c_hum_1_sl = 0.0;
356  day_decomp_c_hum_2_sl = 0.0;
357  day_decomp_c_hum_3_sl = 0.0;
358  day_decay_c_mic_sl = 0.0;
359  day_decomp_n_hum_1 = 0.0;
360  day_decomp_n_hum_2 = 0.0;
361  day_decomp_n_hum_3 = 0.0;
362 
363  // Humification
364  day_c_humify_doc_hum_1_sl = 0.0;
365  day_c_humify_sol_hum_1_sl = 0.0;
366  day_c_humify_cel_hum_1_sl = 0.0;
367  day_c_humify_lig_hum_1_sl = 0.0;
368  day_c_humify_lig_hum_2_sl = 0.0;
369  day_c_humify_mic_hum_1_sl = 0.0;
370  day_c_humify_mic_hum_2_sl = 0.0;
371  day_c_humify_hum_1_hum_2_sl = 0.0;
372  day_c_humify_hum_2_hum_3_sl = 0.0;
373 
374  // Algae
375  day_n_fix_algae = 0.0;
376  day_c_fix_algae = 0.0;
377 
378  // DOC production
379  day_doc_prod_decomp_litter = 0.0;
380  day_doc_prod_decomp_humus = 0.0;
381  day_doc_prod_decomp_aorg = 0.0;
382 
383  return LDNDC_ERR_OK;
384 }
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().

214 {
215  for (size_t ts = 0; ts < TOTAL_TIME_STEPS; ts++)
216  {
217  subdaily_co2_bubbling[ts] = 0.0;
218  subdaily_co2_plant[ts] = 0.0;
219  subdaily_co2_soil[ts] = 0.0;
220  subdaily_co2_water[ts] = 0.0;
221  subdaily_co2_leach[ts] = 0.0;
222 
223  subdaily_ch4_bubbling[ts] = 0.0;
224  subdaily_ch4_plant[ts] = 0.0;
225  subdaily_ch4_soil[ts] = 0.0;
226  subdaily_ch4_water[ts] = 0.0;
227  subdaily_ch4_leach[ts] = 0.0;
228  subdaily_ch4_prod[ts] = 0.0;
229  subdaily_ch4_ox[ts] = 0.0;
230  subdaily_acetate_prod[ts] = 0.0;
231  subdaily_doc_prod[ts] = 0.0;
232  subdaily_plant_o2_cons[ts] = 0.0;
233  subdaily_flood_o2_conc[ts] = 0.0;
234  subdaily_algae_o2_prod[ts] = 0.0;
235  subdaily_o2_bubbling[ts] = 0.0;
236  subdaily_o2_plant[ts] = 0.0;
237  subdaily_o2_soil[ts] = 0.0;
238  subdaily_o2_water[ts] = 0.0;
239  subdaily_n2o_bubbling[ts] = 0.0;
240  subdaily_n2o_plant[ts] = 0.0;
241  subdaily_n2o_soil[ts] = 0.0;
242  subdaily_n2o_water[ts] = 0.0;
243  subdaily_no_bubbling[ts] = 0.0;
244  subdaily_no_plant[ts] = 0.0;
245  subdaily_no_soil[ts] = 0.0;
246  subdaily_no_water[ts] = 0.0;
247  subdaily_nh3_bubbling[ts] = 0.0;
248  subdaily_nh3_plant[ts] = 0.0;
249  subdaily_nh3_soil[ts] = 0.0;
250  subdaily_nh3_water[ts] = 0.0;
251  subdaily_radon_soil[ts] = 0.0;
252  subdaily_radon_plant[ts] = 0.0;
253  subdaily_radon_water[ts] = 0.0;
254  }
255 
256  return LDNDC_ERR_OK;
257 }
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().

336 {
337  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
338  {
339  sc_.nh4_sl[sl] = nh4_ae_sl[sl] + nh4_an_sl[sl];
340  sc_.don_sl[sl] = don_ae_sl[sl] + don_an_sl[sl];
341  sc_.no3_sl[sl] = no3_ae_sl[sl] + no3_an_sl[sl];
342  sc_.an_no3_sl[sl] = 0.0;
343  }
344 
345  return LDNDC_ERR_OK;
346 }
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 / AORG / LITTER */
113  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
114  {
115  int const steps( 10);
116  for ( int i = 0; i < steps; ++i)
117  {
118  double const c_hum_1( c_humus_1_sl[sl]);
119  double const n_hum_1( n_humus_1_sl[sl]);
120  double const c_hum_2( c_humus_2_sl[sl]);
121  double const n_hum_2( n_humus_2_sl[sl]);
122  double const c_hum_3( c_humus_3_sl[sl]);
123  double const n_hum_3( n_humus_3_sl[sl]);
124 
125  double const c_lit_1( sc_.C_lit1_sl[sl]);
126  double const n_lit_1( sc_.N_lit1_sl[sl]);
127  double const c_lit_2( sc_.C_lit2_sl[sl]);
128  double const n_lit_2( sc_.N_lit2_sl[sl]);
129  double const c_lit_3( sc_.C_lit3_sl[sl]);
130  double const n_lit_3( sc_.N_lit3_sl[sl]);
131 
132  double const c_aorg( sc_.C_aorg_sl[sl]);
133  double const n_aorg( sc_.N_aorg_sl[sl]);
134 
135  double const c_tot( c_hum_1 + c_hum_2 + c_hum_3 + c_lit_1 + c_lit_2 + c_lit_3 + c_aorg);
136  double const n_tot( n_hum_1 + n_hum_2 + n_hum_3 + n_lit_1 + n_lit_2 + n_lit_3 + n_aorg);
137 
138  int spinup_steps_per_year( 12);
139  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()
140  * spinup_delta_c / spinup_steps_per_year);
141  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()
142  * spinup_delta_c / spinup_steps_per_year);
143  double const delta_c_hum_3( 0.0);
144 
145  double const c_humus_1_tmp( cbm::bound_min( 1.0e-9,
146  spinup_.c_to_humus_1_sl[sl]
147  - delta_c_hum_1)
148  / cbm::bound_min( 1.0e-9, spinup_.decompose_hum_1[sl] + spinup_.humify_humus_1_to_humus_2_sl[sl]));
149 
150  double const c_humus_2_tmp( cbm::bound_min( 1.0e-9,
151  spinup_.c_to_humus_2_sl[sl]
152  + spinup_.humify_humus_1_to_humus_2_sl[sl] * c_humus_1_sl[sl]
153  - delta_c_hum_2)
154  / cbm::bound_min( 1.0e-9, spinup_.decompose_hum_2[sl] + spinup_.humify_humus_2_to_humus_3_sl[sl]));
155 
156  double const c_humus_3_tmp( cbm::bound_min( 1.0e-9,
157  spinup_.c_to_humus_3_sl[sl]
158  + spinup_.humify_humus_2_to_humus_3_sl[sl] * c_humus_2_sl[sl]
159  - delta_c_hum_3)
160  / cbm::bound_min( 1.0e-9, spinup_.decompose_hum_3[sl] + spinup_.humify_humus_2_to_humus_3_sl[sl]));
161 
162  double const c_litter_1_tmp( cbm::bound_min( 1.0e-9, spinup_.c_to_lit_1[sl]) /
163  (cbm::bound_min( 1.0e-9, spinup_.loose_lit_1[sl])));
164 
165  double const c_litter_2_tmp( cbm::bound_min( 1.0e-9, spinup_.c_to_lit_2[sl]) /
166  (cbm::bound_min( 1.0e-9, spinup_.loose_lit_2[sl])));
167 
168  double const c_litter_3_tmp( cbm::bound_min( 1.0e-9, spinup_.c_to_lit_3[sl]) /
169  (cbm::bound_min( 1.0e-9, spinup_.loose_lit_3[sl])));
170 
171 
172  double const c_aorg_tmp( cbm::bound_min( 1.0e-9, spinup_.c_to_aorg[sl]) /
173  (cbm::bound_min( 1.0e-9, spinup_.loose_aorg[sl])));
174 
175  //idea for drained peat if spinup_delta_c explicitly not used
176  if ( spinup_.spinup_type() == 1)
177  {
178  c_humus_1_sl[sl] = c_humus_1_tmp;
179  double const scale( c_tot / (c_humus_1_sl[sl] + c_humus_2_sl[sl] + c_humus_3_sl[sl]));
180  c_humus_1_sl[sl] *= scale;
181  c_humus_2_sl[sl] *= scale;
182  c_humus_3_sl[sl] *= scale;
183  }
184  else if ( spinup_.spinup_type() == 2)
185  {
186  c_humus_2_sl[sl] = c_humus_2_tmp;
187  double const scale( c_tot / (c_humus_1_sl[sl] + c_humus_2_sl[sl] + c_humus_3_sl[sl]));
188  c_humus_1_sl[sl] *= scale;
189  c_humus_2_sl[sl] *= scale;
190  c_humus_3_sl[sl] *= scale;
191  }
192  else if ( spinup_.spinup_type() == 3)
193  {
194  c_humus_3_sl[sl] = c_humus_3_tmp;
195  double const scale( c_tot / (c_humus_1_sl[sl] + c_humus_2_sl[sl] + c_humus_3_sl[sl]));
196  c_humus_1_sl[sl] *= scale;
197  c_humus_2_sl[sl] *= scale;
198  c_humus_3_sl[sl] *= scale;
199  }
200  else
201  {
202  //change less with time
203  double const fraction( 1.0 / steps);
204 
205  double const c_tot_tmp( c_humus_1_tmp + c_humus_2_tmp + c_humus_3_tmp +
206  c_litter_1_tmp + c_litter_2_tmp + c_litter_3_tmp + c_aorg_tmp);
207 
208 
209  sc_.C_lit1_sl[sl] = cbm::bound_max( c_litter_1_tmp * fraction + c_lit_1 * (1.0 - fraction), c_litter_1_tmp / c_tot_tmp * c_tot);
210  sc_.C_lit2_sl[sl] = cbm::bound_max( c_litter_2_tmp * fraction + c_lit_2 * (1.0 - fraction), c_litter_2_tmp / c_tot_tmp * c_tot);
211  sc_.C_lit3_sl[sl] = cbm::bound_max( c_litter_3_tmp * fraction + c_lit_3 * (1.0 - fraction), c_litter_3_tmp / c_tot_tmp * c_tot);
212 
213  sc_.C_aorg_sl[sl] = cbm::bound_max( c_aorg_tmp * fraction + c_aorg * (1.0 - fraction), c_aorg_tmp / c_tot_tmp * c_tot);
214 
215  double const c_litter_aorg( sc_.C_lit1_sl[sl] + sc_.C_lit2_sl[sl] + sc_.C_lit3_sl[sl] + sc_.C_aorg_sl[sl]);
216 
217  //use upper limit for humus pool 1
218  c_humus_1_sl[sl] = cbm::bound_max( c_humus_1_tmp * fraction + c_hum_1 * (1.0 - fraction),
219  0.99 * c_humus_1_tmp / (c_humus_1_tmp + c_humus_2_tmp + c_humus_3_tmp)
220  * (c_tot - c_litter_aorg));
221  c_humus_2_sl[sl] = cbm::bound_max( c_humus_2_tmp * fraction + c_hum_2 * (1.0 - fraction),
222  0.99 * c_humus_2_tmp / (c_humus_2_tmp + c_humus_3_tmp)
223  * (c_tot - c_litter_aorg - c_humus_1_sl[sl]));
224  c_humus_3_sl[sl] = c_tot - c_litter_aorg - c_humus_1_sl[sl] - c_humus_2_sl[sl];
225 
226  //c_humus_2_sl[sl] = c_humus_2_tmp / (c_humus_2_tmp + c_humus_3_tmp) * (c_tot - c_humus_1_sl[sl]);
227  //c_humus_3_sl[sl] = c_humus_3_tmp / (c_humus_2_tmp + c_humus_3_tmp) * (c_tot - c_humus_1_sl[sl]);
228  }
229 
230  accumulated_n_humus_1_spinup_sl[sl] -= n_humus_1_sl[sl];
231  accumulated_n_humus_2_spinup_sl[sl] -= n_humus_2_sl[sl];
232  accumulated_n_humus_3_spinup_sl[sl] -= n_humus_3_sl[sl];
233 
234  sc_.N_lit1_sl[sl] = sc_.C_lit1_sl[sl] / (c_lit_1/n_lit_1);
235  sc_.N_lit2_sl[sl] = sc_.C_lit2_sl[sl] / (c_lit_2/n_lit_2);
236  sc_.N_lit3_sl[sl] = sc_.C_lit3_sl[sl] / (c_lit_3/n_lit_3);
237 
238  sc_.N_aorg_sl[sl] = sc_.C_aorg_sl[sl] / (c_aorg/n_aorg);
239 
240  n_humus_1_sl[sl] = c_humus_1_sl[sl] / cn_hum_1_sl[sl];
241  n_humus_2_sl[sl] = c_humus_2_sl[sl] / cn_hum_2_sl[sl];
242  n_humus_3_sl[sl] = c_humus_3_sl[sl] / cn_hum_3_sl[sl];
243 
244  double const n_tot_tmp( sc_.N_lit1_sl[sl] + sc_.N_lit2_sl[sl] + sc_.N_lit3_sl[sl] + sc_.N_aorg_sl[sl]
245  + n_humus_1_sl[sl] + n_humus_2_sl[sl] + n_humus_3_sl[sl]);
246 
247  double const scale( n_tot / n_tot_tmp);
248 
249  sc_.N_lit1_sl[sl] *= scale;
250  sc_.N_lit2_sl[sl] *= scale;
251  sc_.N_lit3_sl[sl] *= scale;
252 
253  sc_.N_aorg_sl[sl] *= scale;
254 
255  n_humus_1_sl[sl] *= scale;
256  n_humus_2_sl[sl] *= scale;
257  n_humus_3_sl[sl] *= scale;
258 
259  accumulated_n_humus_1_spinup_sl[sl] += n_humus_1_sl[sl];
260  accumulated_n_humus_2_spinup_sl[sl] += n_humus_2_sl[sl];
261  accumulated_n_humus_3_spinup_sl[sl] += n_humus_3_sl[sl];
262 
263  //adapt target cn of recalcitrant pools
264  cn_hum_2_sl[sl] = c_humus_2_sl[sl] / n_humus_2_sl[sl];
265  cn_hum_3_sl[sl] = c_humus_3_sl[sl] / n_humus_3_sl[sl];
266  }
267 
268  spinup_.cn_humus_2_temp_sl[sl] += cn_hum_2_sl[sl];
269  spinup_.cn_humus_3_temp_sl[sl] += cn_hum_3_sl[sl];
270 
271  spinup_.c_humus_1_temp_sl[sl] += c_humus_1_sl[sl];
272  spinup_.c_humus_2_temp_sl[sl] += c_humus_2_sl[sl];
273  spinup_.c_humus_3_temp_sl[sl] += c_humus_3_sl[sl];
274 
275  spinup_.c_litter_1_temp_sl[sl] += sc_.C_lit1_sl[sl];
276  spinup_.c_litter_2_temp_sl[sl] += sc_.C_lit2_sl[sl];
277  spinup_.c_litter_3_temp_sl[sl] += sc_.C_lit3_sl[sl];
278 
279  spinup_.c_aorg_temp_sl[sl] += sc_.C_aorg_sl[sl];
280  }
281 
282  spinup_.executed_months_ += 1;
283 
284  if ( true)//spinup_.executed_months_ == spinup_.spinup_months())
285  {
286  double const c_tot( c_humus_1_sl.sum() + c_humus_2_sl.sum() + c_humus_3_sl.sum()
287  + sc_.C_lit1_sl.sum() + sc_.C_lit2_sl.sum() + sc_.C_lit3_sl.sum() + sc_.C_aorg_sl.sum());
288 
289  double const c_hum_1_acc_tot( spinup_.c_humus_1_temp_sl.sum());
290  double const c_hum_2_acc_tot( spinup_.c_humus_2_temp_sl.sum());
291  double const c_hum_3_acc_tot( spinup_.c_humus_3_temp_sl.sum());
292 
293  double const c_lit_1_acc_tot( spinup_.c_litter_1_temp_sl.sum());
294  double const c_lit_2_acc_tot( spinup_.c_litter_2_temp_sl.sum());
295  double const c_lit_3_acc_tot( spinup_.c_litter_3_temp_sl.sum());
296 
297  double const c_aorg_acc_tot( spinup_.c_aorg_temp_sl.sum());
298 
299  double const c_acc_tot( c_hum_1_acc_tot + c_hum_2_acc_tot + c_hum_3_acc_tot
300  + c_lit_1_acc_tot + c_lit_2_acc_tot + c_lit_3_acc_tot + c_aorg_acc_tot);
301 
302  double const scale_c( c_tot / c_acc_tot);
303  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
304  {
305  //double const c_hum_1_tot( c_hum_1_acc_tot / c_hum_acc_tot * c_hum_tot);
306  //double const c_hum_2_tot( c_hum_2_acc_tot / c_hum_acc_tot * c_hum_tot);
307  //double const c_hum_3_tot( c_hum_3_acc_tot / c_hum_acc_tot * c_hum_tot);
308 
309  sc_.C_lit1_sl[sl] = spinup_.c_litter_1_temp_sl[sl] * scale_c;
310  sc_.C_lit2_sl[sl] = spinup_.c_litter_2_temp_sl[sl] * scale_c;
311  sc_.C_lit3_sl[sl] = spinup_.c_litter_3_temp_sl[sl] * scale_c;
312 
313  sc_.C_aorg_sl[sl] = spinup_.c_aorg_temp_sl[sl] * scale_c;
314 
315  c_humus_1_sl[sl] = spinup_.c_humus_1_temp_sl[sl] * scale_c;
316  c_humus_2_sl[sl] = spinup_.c_humus_2_temp_sl[sl] * scale_c;
317  c_humus_3_sl[sl] = spinup_.c_humus_3_temp_sl[sl] * scale_c;
318  }
319 
320  double const c_difference( c_tot - (c_humus_1_sl.sum() + c_humus_2_sl.sum() + c_humus_3_sl.sum()
321  + sc_.C_lit1_sl.sum() + sc_.C_lit2_sl.sum() + sc_.C_lit3_sl.sum() + sc_.C_aorg_sl.sum()));
322  if ( cbm::flt_greater( c_difference, 1.0e-10))
323  {
324  KLOGERROR( name(),": C-leakage during spinup: ", c_difference*cbm::M2_IN_HA, "[kg C ha-1]");
325  }
326 
327  double const n_old_total( n_humus_1_sl.sum() + n_humus_2_sl.sum() + n_humus_3_sl.sum());
328  double n_new_total( 0.0);
329  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
330  {
331  cn_hum_2_sl[sl] = spinup_.cn_humus_2_temp_sl[sl] / spinup_.executed_months_;
332  cn_hum_3_sl[sl] = spinup_.cn_humus_3_temp_sl[sl] / spinup_.executed_months_;
333 
334  n_new_total += c_humus_1_sl[sl] / cn_hum_1_sl[sl];
335  n_new_total += c_humus_2_sl[sl] / cn_hum_2_sl[sl];
336  n_new_total += c_humus_3_sl[sl] / cn_hum_3_sl[sl];
337  }
338 
339  double const scale( n_old_total / n_new_total);
340  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
341  {
342  accumulated_n_humus_1_spinup_sl[sl] -= n_humus_1_sl[sl];
343  accumulated_n_humus_2_spinup_sl[sl] -= n_humus_2_sl[sl];
344  accumulated_n_humus_3_spinup_sl[sl] -= n_humus_3_sl[sl];
345 
346  n_humus_1_sl[sl] = c_humus_1_sl[sl] / cn_hum_1_sl[sl] * scale;
347  n_humus_2_sl[sl] = c_humus_2_sl[sl] / cn_hum_2_sl[sl] * scale;
348  n_humus_3_sl[sl] = c_humus_3_sl[sl] / cn_hum_3_sl[sl] * scale;
349 
350  accumulated_n_humus_1_spinup_sl[sl] += n_humus_1_sl[sl];
351  accumulated_n_humus_2_spinup_sl[sl] += n_humus_2_sl[sl];
352  accumulated_n_humus_3_spinup_sl[sl] += n_humus_3_sl[sl];
353  }
354 
355  double const n_difference( n_old_total - (n_humus_1_sl.sum() + n_humus_2_sl.sum() + n_humus_3_sl.sum()));
356  if ( cbm::flt_greater( c_difference, 1.0e-10))
357  {
358  KLOGERROR( name(),": N-leakage during spinup: ", n_difference*cbm::M2_IN_HA, "[kg N ha-1]");
359  }
360 
361  if (spinup_.executed_months_ == spinup_.spinup_months())
362  {
363  spinup_.stop_spinup();
364  }
365  }
366 
367  spinup_.reset();
368  }
369 
370  return LDNDC_ERR_OK;
371 }
Here is the caller graph for this function:

◆ MeTrX_till()

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

Referenced by solve().

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

◆ MeTrX_update()

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

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

Referenced by solve().

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

Referenced by MeTrX_update().

20 {
21  if ( _update_litter && (sl_.soil_layers_in_litter_cnt() > 0))
22  {
23  double const raw_litter_above( sc_.c_raw_lit_1_above +
24  sc_.c_raw_lit_2_above +
25  sc_.c_raw_lit_3_above);
26 
27  double * h_litter_neq_sl = new double[sl_.soil_layers_in_litter_cnt()];
28  double h_litter_tot( 0.0);
29  double volume_water_tot( 0.0);
30  double volume_ice_tot( 0.0);
31  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
32  {
33  if ( sl < sl_.soil_layers_in_litter_cnt())
34  {
35  if ( cbm::flt_greater_zero( sc_.dens_sl[sl] * sc_.fcorg_sl[sl]) &&
36  cbm::flt_greater_zero( sc_.som_sl[sl]))
37  {
38  double const volume_water( wc_.wc_sl[sl] * sc_.h_sl[sl]);
39  volume_water_tot += volume_water;
40 
41  double const volume_ice( wc_.ice_sl[sl] * sc_.h_sl[sl]);
42  volume_ice_tot += volume_ice;
43 
44  double const mass_soil( sc_.min_sl[sl] + sc_.som_sl[sl] + raw_litter_above
45  / sl_.soil_layers_in_litter_cnt());
46  double const density_soil( cbm::DM3_IN_M3 * sc_.dens_sl[sl]);
47 
48  h_litter_neq_sl[sl] = mass_soil / density_soil;
49  h_litter_tot += mass_soil / density_soil;
50  }
51  }
52  }
53  double h_litter_eq_sl( h_litter_tot / sl_.soil_layers_in_litter_cnt());
54 
55  // Create a list of pool arrays (all same size)
56  std::vector<lvector_t<double>*> pools = {
57  &c_humus_1_sl,
58  &c_humus_2_sl,
59  &c_humus_3_sl,
60  &n_humus_1_sl,
61  &n_humus_2_sl,
62  &n_humus_3_sl,
63  &sc_.c_wood_sl,
64  &sc_.n_wood_sl,
65  &sc_.c_raw_lit_1_sl,
66  &sc_.c_raw_lit_2_sl,
67  &sc_.c_raw_lit_3_sl,
68  &sc_.n_raw_lit_1_sl,
69  &sc_.n_raw_lit_2_sl,
70  &sc_.n_raw_lit_3_sl,
71  &sc_.C_lit1_sl,
72  &sc_.C_lit2_sl,
73  &sc_.C_lit3_sl,
74  &sc_.N_lit1_sl,
75  &sc_.N_lit2_sl,
76  &sc_.N_lit3_sl,
77  &sc_.C_aorg_sl,
78  &sc_.N_aorg_sl
79  };
80 
81  std::vector<double> distribute_total( pools.size(), 0.0);
82 
83  size_t n = sl_.soil_layers_in_litter_cnt();
84 
85  for ( size_t sl = 0; sl < n; ++sl)
86  {
87  if ( h_litter_neq_sl[sl] > h_litter_eq_sl)
88  {
89  double fraction = 1.0 - h_litter_eq_sl / h_litter_neq_sl[sl];
90 
91  for (size_t p = 0; p < pools.size(); ++p)
92  {
93  double value_sl = (*pools[p])[sl];
94  double distribute_sl = fraction * value_sl;
95 
96  (*pools[p])[sl] -= distribute_sl;
97  distribute_total[p] += distribute_sl;
98  }
99  }
100  }
101 
102  for ( size_t sl = 0; sl < n; ++sl)
103  {
104  if ( h_litter_neq_sl[sl] < h_litter_eq_sl)
105  {
106  double fraction = h_litter_eq_sl / h_litter_neq_sl[sl] - 1.0;
107 
108  for ( size_t p = 0; p < pools.size(); ++p)
109  {
110  double value_sl = (*pools[p])[sl];
111  double need_sl = fraction * value_sl;
112 
113  // Limit by remaining pool-level supply
114  double distribute_sl = cbm::bound_max(need_sl, distribute_total[p]);
115 
116  (*pools[p])[sl] += distribute_sl;
117  distribute_total[p] -= distribute_sl;
118  }
119  }
120  }
121 
122  for ( size_t p = 0; p < pools.size(); ++p)
123  {
124  if ( cbm::flt_greater_zero( distribute_total[p]))
125  {
126  for ( size_t sl = 0; sl < n; ++sl)
127  {
128  (*pools[p])[sl] += distribute_total[p] / n;
129  }
130  distribute_total[p] = 0.0;
131  }
132  }
133 
134  double h_cum( 0.0);
135  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
136  {
137  if ( sl < sl_.soil_layers_in_litter_cnt())
138  {
139  sc_.h_sl[sl] = h_litter_eq_sl;
140 
141  double pore_vol_avail( 0.99 * sc_.poro_sl[sl] * sc_.h_sl[sl]);
142  double const ice_vol( (1.0 / sl_.soil_layers_in_litter_cnt() * volume_ice_tot));
143  if ( cbm::flt_greater( ice_vol, pore_vol_avail))
144  {
145  wc_.surface_ice += ice_vol - pore_vol_avail;
146  wc_.ice_sl[sl] = pore_vol_avail / sc_.h_sl[sl];
147  }
148  else
149  {
150  wc_.ice_sl[sl] = ice_vol / sc_.h_sl[sl];
151  }
152 
153  pore_vol_avail = cbm::bound_min( 0.0, 0.99 * sc_.poro_sl[sl] * sc_.h_sl[sl] - ice_vol);
154  double const water_vol( (1.0 / sl_.soil_layers_in_litter_cnt() * volume_water_tot));
155  if ( cbm::flt_greater( water_vol, pore_vol_avail))
156  {
157  wc_.surface_water += water_vol - pore_vol_avail;
158  wc_.wc_sl[sl] = pore_vol_avail / sc_.h_sl[sl];
159  }
160  else
161  {
162  wc_.wc_sl[sl] = water_vol / sc_.h_sl[sl];
163  }
164  }
165  h_cum += sc_.h_sl[sl];
166  sc_.depth_sl[sl] = h_cum;
167  }
168  }
169 
170  for( size_t sl = 0; sl < sl_.soil_layer_cnt()-1; ++sl)
171  {
172  delta_x[sl] = cbm::arithmetic_mean2( sc_.h_sl[sl], sc_.h_sl[sl+1]);
173  }
174  delta_x[sl_.soil_layer_cnt()-1] = sc_.h_sl[sl_.soil_layer_cnt()-1];
175 
176  return LDNDC_ERR_OK;
177 }
Here is the caller graph for this function:

◆ MeTrX_urea_hydrolysis()

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

Referenced by solve().

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

◆ MeTrX_write_output()

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

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

Referenced by solve().

17 {
18  if ( !output_data_ || !this->output_writer_.active())
19  {
20  return LDNDC_ERR_OK;
21  }
22 
23  if ( output_writer_.write_subdaily())
24  {
25  lerr_t rc_out = MeTrX_write_output_subdaily();
26  if ( rc_out){ return LDNDC_ERR_FAIL; }
27  }
28 
29  if ( output_writer_.write_fluxes())
30  {
31  lerr_t rc_out = MeTrX_write_output_fluxes();
32  if ( rc_out){ return LDNDC_ERR_FAIL; }
33  }
34 
35  if ( lclock()->is_position( TMODE_POST_DAILY))
36  {
37  if ( output_writer_.write_pools())
38  {
39  lerr_t rc_out = MeTrX_write_output_pools();
40  if ( rc_out){ return LDNDC_ERR_FAIL; }
41  }
42 
43  if ( output_writer_.write_daily())
44  {
45  lerr_t rc_out = MeTrX_write_output_daily();
46  if ( rc_out){ return LDNDC_ERR_FAIL; }
47  }
48 
49  if ( output_writer_.write_layer_daily())
50  {
51  lerr_t rc_out = MeTrX_write_output_layer_daily();
52  if ( rc_out){ return LDNDC_ERR_FAIL; }
53  }
54  }
55 
56  if ( lclock()->is_position( TMODE_POST_YEARLY))
57  {
58  if ( output_writer_.write_yearly())
59  {
60  lerr_t rc_out = MeTrX_write_output_yearly();
61  if ( rc_out){ return LDNDC_ERR_FAIL; }
62  }
63 
64  if ( output_writer_.write_layer_yearly())
65  {
66  lerr_t rc_out = MeTrX_write_output_layer_yearly();
67  if ( rc_out){ return LDNDC_ERR_FAIL; }
68  }
69  }
70 
71  return LDNDC_ERR_OK;
72 }
lerr_t MeTrX_write_output_layer_yearly()
Definition: soilchemistry-metrx-output.cpp:630
lerr_t MeTrX_write_output_subdaily()
Definition: soilchemistry-metrx-output.cpp:972
lerr_t MeTrX_write_output_pools()
Definition: soilchemistry-metrx-output.cpp:657
lerr_t MeTrX_write_output_daily()
Definition: soilchemistry-metrx-output.cpp:76
lerr_t MeTrX_write_output_fluxes()
Definition: soilchemistry-metrx-output.cpp:726
lerr_t MeTrX_write_output_layer_daily()
Definition: soilchemistry-metrx-output.cpp:454
lerr_t MeTrX_write_output_yearly()
Definition: soilchemistry-metrx-output.cpp:410
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 c_stub( sc_.c_stubble_lit1 + sc_.c_stubble_lit2 + sc_.c_stubble_lit3);
82  double const n_stub( sc_.n_stubble_lit1 + sc_.n_stubble_lit2 + sc_.n_stubble_lit3);
83 
84  double const c_litter_above( sc_.c_raw_lit_1_above + sc_.c_raw_lit_2_above + sc_.c_raw_lit_3_above);
85  double const n_litter_above( sc_.n_raw_lit_1_above + sc_.n_raw_lit_2_above + sc_.n_raw_lit_3_above);
86 
87  double const c_litter_soil_1( sc_.C_lit1_sl.sum() + sc_.c_raw_lit_1_sl.sum());
88  double const c_litter_soil_2( sc_.C_lit2_sl.sum() + sc_.c_raw_lit_2_sl.sum());
89  double const c_litter_soil_3( sc_.C_lit3_sl.sum() + sc_.c_raw_lit_3_sl.sum());
90  double const n_litter_soil_1( sc_.N_lit1_sl.sum() + sc_.n_raw_lit_1_sl.sum());
91  double const n_litter_soil_2( sc_.N_lit2_sl.sum() + sc_.n_raw_lit_2_sl.sum());
92  double const n_litter_soil_3( sc_.N_lit3_sl.sum() + sc_.n_raw_lit_3_sl.sum());
93 
94  double const c_mic_1( sc_.C_micro1_sl.sum());
95  double const c_mic_2( sc_.C_micro2_sl.sum());
96  double const c_mic_3( sc_.C_micro3_sl.sum());
97  double const n_mic_1( n_micro_1_sl.sum());
98  double const n_mic_2( n_micro_2_sl.sum());
99  double const n_mic_3( n_micro_3_sl.sum());
100 
101  double const c_hum_1( c_humus_1_sl.sum());
102  double const c_hum_2( c_humus_2_sl.sum());
103  double const c_hum_3( c_humus_3_sl.sum());
104  double const n_hum_1( n_humus_1_sl.sum());
105  double const n_hum_2( n_humus_2_sl.sum());
106  double const n_hum_3( n_humus_3_sl.sum());
107 
108  double const c_aorg( sc_.C_aorg_sl.sum());
109  double const n_aorg( sc_.N_aorg_sl.sum());
110 
111  double const c_wood( sc_.c_wood_sl.sum() + sc_.c_wood);
112  double const n_wood( sc_.n_wood_sl.sum() + sc_.n_wood);
113 
114  double const n_algae_tot( n_algae + n_dead_algae);
115  double const don_sum( don_ae_sl.sum()+don_an_sl.sum()+sb_.don_sbl.sum());
116  double const nh4_sum( nh4_ae_sl.sum()+nh4_an_sl.sum()+sb_.nh4_sbl.sum());
117  double const nh4_clay_sum( sc_.clay_nh4_sl.sum());
118  double const coated_nh4_sum( sc_.coated_nh4_sl.sum());
119  double const urea_sum( sc_.urea_sl.sum()+sb_.urea_sbl.sum());
120  double const no2_sum( sc_.no2_sl.sum());
121  double const an_no2_sum( sc_.an_no2_sl.sum());
122  double const no3_sum( no3_ae_sl.sum());
123  double const an_no3_sum( no3_an_sl.sum()+sb_.no3_sbl.sum());
124  double const n2o_sum( n2o_gas_sl.sum()+n2o_liq_sl.sum());
125  double const an_n2o_sum( an_n2o_gas_sl.sum()+an_n2o_liq_sl.sum());
126  double const no_sum( no_gas_sl.sum()+no_liq_sl.sum());
127  double const an_no_sum( an_no_gas_sl.sum()+an_no_liq_sl.sum());
128  double const nh3_gas_sum( sc_.nh3_gas_sl.sum());
129  double const nh3_liq_sum( sc_.nh3_liq_sl.sum()+sb_.nh3_sbl.sum());
130 
131  double const n_sbl( sb_.don_sbl.sum() + sb_.nh4_sbl.sum()
132  + sb_.urea_sbl.sum() + sb_.no3_sbl.sum() + sb_.nh3_sbl.sum());
133  double const n_sol( nh4_sum + nh4_clay_sum + don_sum
134  + nh3_gas_sum + nh3_liq_sum + urea_sum
135  + no3_sum + an_no3_sum + no2_sum + an_no2_sum
136  + n2o_sum + an_n2o_sum + no_sum + an_no_sum);
137 
138  double const c_algae_tot( c_algae + c_dead_algae);
139  double const doc_sum( sc_.doc_sl.sum());
140  double const an_doc_sum( sc_.an_doc_sl.sum());
141  double const acetate_sum( ae_acetate_sl.sum() + an_acetate_sl.sum());
142  double const ch4_gas_sum( ch4_gas_sl.sum());
143  double const ch4_liq_sum( ch4_liq_sl.sum());
144 
145  double const c_sol( doc_sum + an_doc_sum + acetate_sum + ch4_gas_sum + ch4_liq_sum);
146 
147  double soc20( 0.0);
148  double soc40( 0.0);
149  double totn20( 0.0);
150  double totn40( 0.0);
151  double soilmass20( 0.0);
152  double soilmass40( 0.0);
153  double anvf_avg( 0.0);
154 #ifdef METRX_ANVF_TYPES
155  double anvf_avg_pnet( 0.0);
156  double anvf_avg_dndc_can( 0.0);
157  double anvf_avg_nloss( 0.0);
158 #endif
159  double pore_connect_avg( 0.0);
160  double d_eff_avg( 0.0);
161  double wfps_avg( 0.0);
162  double air_avg( 0.0);
163  double root_conduct_avg( 0.0);
164  double o2_sum( 0.0);
165  double depth_sum( 0.0);
166 
167  double nitrification_inhibition( 0.0);
168  double urease_inhibition( 0.0);
169 
170  double mineral_efficiency_scale_sum( 0.0);
171  double mineral_efficiency( 0.0);
172  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
173  {
174  double const c_mic_sl( sc_.C_micro1_sl[sl] + sc_.C_micro2_sl[sl] + sc_.C_micro3_sl[sl]);
175  double const n_mic_sl( n_micro_1_sl[sl] + n_micro_2_sl[sl] + n_micro_3_sl[sl]);
176  mineral_efficiency += MeTrX_get_mineral_efficiency( c_mic_sl / n_mic_sl, cn_opt_mic_sl[sl]) * c_mic_sl;
177  mineral_efficiency_scale_sum += c_mic_sl;
178 
179  anvf_avg += sc_.anvf_sl[sl] * sc_.h_sl[sl];
180 #ifdef METRX_ANVF_TYPES
181  anvf_avg_pnet += anvf_pnet_sl[sl] * sc_.h_sl[sl];
182  anvf_avg_dndc_can += anvf_dndccan_sl[sl] * sc_.h_sl[sl];
183  anvf_avg_nloss += anvf_nloss_sl[sl] * sc_.h_sl[sl];
184 #endif
185  pore_connect_avg += pore_connectivity_sl[sl] * sc_.h_sl[sl];
186  d_eff_avg += D_eff_air_sl[sl] * sc_.h_sl[sl];
187  wfps_avg += MeTrX_get_wfps( sl) * sc_.h_sl[sl];
188  air_avg += (v_air_sl[sl] / sc_.h_sl[sl]) * sc_.h_sl[sl];
189  root_conduct_avg += D_eff_plant_sl[sl] * sc_.h_sl[sl];
190  o2_sum += o2_gas_sl[sl] + o2_liq_sl[sl];
191  depth_sum += sc_.h_sl[sl];
192 
193  if ( cbm::flt_less_equal( sc_.depth_sl[sl], 0.2))
194  {
195  soc20 += sc_.C_aorg_sl[sl] +c_humus_1_sl[sl]+c_humus_2_sl[sl]+c_humus_3_sl[sl]
196  + sc_.C_micro1_sl[sl]+sc_.C_micro2_sl[sl]+sc_.C_micro3_sl[sl]
197  + sc_.C_lit1_sl[sl]+sc_.C_lit2_sl[sl]+sc_.C_lit3_sl[sl];
198  totn20 += sc_.N_aorg_sl[sl] +n_humus_1_sl[sl]+n_humus_2_sl[sl]+n_humus_3_sl[sl]
199  + sc_.N_micro_sl[sl] +sc_.N_lit1_sl[sl]+sc_.N_lit2_sl[sl]+sc_.N_lit3_sl[sl];
200  soilmass20 += sc_.dens_sl[sl] * cbm::DM3_IN_M3 * sc_.h_sl[sl];
201  }
202 
203  if ( cbm::flt_less_equal( sc_.depth_sl[sl], 0.4))
204  {
205  soc40 += sc_.C_aorg_sl[sl] +c_humus_1_sl[sl]+c_humus_2_sl[sl]+c_humus_3_sl[sl]
206  + sc_.C_micro1_sl[sl]+sc_.C_micro2_sl[sl]+sc_.C_micro3_sl[sl]
207  + sc_.C_lit1_sl[sl]+sc_.C_lit2_sl[sl]+sc_.C_lit3_sl[sl];
208  totn40 += sc_.N_aorg_sl[sl] +n_humus_1_sl[sl]+n_humus_2_sl[sl]+n_humus_3_sl[sl]
209  + sc_.N_micro_sl[sl] +sc_.N_lit1_sl[sl]+sc_.N_lit2_sl[sl]+sc_.N_lit3_sl[sl];
210  soilmass40 += sc_.dens_sl[sl] * cbm::DM3_IN_M3 * sc_.h_sl[sl];
211  }
212  }
213 
214  int ui_counter( 0);
215  int ni_counter( 0);
216  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
217  {
218  double const ui_inhibition( crnf_.get_urease_inhibition( sc_.ui_sl[sl]));
219  if ( cbm::flt_greater_zero( ui_inhibition))
220  {
221  ui_counter += 1;
222  urease_inhibition += ui_inhibition;
223  }
224  double const ni_inhibition( crnf_.get_nitrification_inhibition( sc_.ni_sl[sl]));
225  if ( cbm::flt_greater_zero( ni_inhibition))
226  {
227  ni_counter += 1;
228  nitrification_inhibition += ni_inhibition;
229  }
230  }
231 
232  if ( ui_counter > 0)
233  {
234  urease_inhibition /= ui_counter;
235  }
236  if ( ni_counter > 0)
237  {
238  nitrification_inhibition /= ni_counter;
239  }
240 
241  double const litter_height( (sl_.soil_layers_in_litter_cnt() > 0) ? sc_.depth_sl[sl_.soil_layers_in_litter_cnt()-1] : 0.0);
242  anvf_avg /= depth_sum;
243 #ifdef METRX_ANVF_TYPES
244  anvf_avg_pnet /= depth_sum;
245  anvf_avg_dndc_can /= depth_sum;
246  anvf_avg_nloss /= depth_sum;
247 #endif
248  pore_connect_avg /= depth_sum;
249  d_eff_avg /= depth_sum;
250  wfps_avg /= depth_sum;
251  air_avg /= depth_sum;
252  root_conduct_avg /= depth_sum;
253 
254  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( anvf_avg);
255 #ifdef METRX_ANVF_TYPES
256  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( anvf_avg_pnet);
257  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( anvf_avg_dndc_can);
258  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( anvf_avg_nloss);
259 #endif
260  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( pore_connect_avg);
261  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( d_eff_avg);
262  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( wfps_avg);
263  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( air_avg);
264  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( root_conduct_avg);
265  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( o2_sum * cbm::M2_IN_HA);
266  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( crnf_.get_crnf_teff_mean());
267  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( crnf_.get_crnf_release_fraction_mean());
268  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nitrification_inhibition);
269  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( urease_inhibition);
270  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( mineral_efficiency / (mineral_efficiency_scale_sum * sl_.soil_layer_cnt()));
271  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( don_sum * cbm::M2_IN_HA);
272  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nh4_sum * cbm::M2_IN_HA);
273  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nh4_clay_sum * cbm::M2_IN_HA);
274  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( coated_nh4_sum * cbm::M2_IN_HA);
275  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( urea_sum * cbm::M2_IN_HA);
276  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( no2_sum * cbm::M2_IN_HA);
277  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( an_no2_sum * cbm::M2_IN_HA);
278  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( no3_sum * cbm::M2_IN_HA);
279  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( an_no3_sum * cbm::M2_IN_HA);
280  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( n2o_sum * cbm::M2_IN_HA);
281  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( an_n2o_sum * cbm::M2_IN_HA);
282  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( no_sum * cbm::M2_IN_HA);
283  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( an_no_sum * cbm::M2_IN_HA);
284  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nh3_gas_sum * cbm::M2_IN_HA);
285  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nh3_liq_sum * cbm::M2_IN_HA);
286  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( doc_sum * cbm::M2_IN_HA);
287  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( an_doc_sum * cbm::M2_IN_HA);
288  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( acetate_sum * cbm::M2_IN_HA);
289  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( ch4_gas_sum * cbm::M2_IN_HA);
290  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( ch4_liq_sum * cbm::M2_IN_HA);
291  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_aorg * cbm::M2_IN_HA);
292  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( n_aorg * cbm::M2_IN_HA);
293  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_mic_1 * cbm::M2_IN_HA);
294  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_mic_2 * cbm::M2_IN_HA);
295  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_mic_3 * cbm::M2_IN_HA);
296  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( n_mic_1 * cbm::M2_IN_HA);
297  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( n_mic_2 * cbm::M2_IN_HA);
298  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( n_mic_3 * cbm::M2_IN_HA);
299  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_hum_1 * cbm::M2_IN_HA);
300  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_hum_2 * cbm::M2_IN_HA);
301  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_hum_3 * cbm::M2_IN_HA);
302  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( n_hum_1 * cbm::M2_IN_HA);
303  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( n_hum_2 * cbm::M2_IN_HA);
304  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( n_hum_3 * cbm::M2_IN_HA);
305  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_litter_soil_1 * cbm::M2_IN_HA);
306  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_litter_soil_2 * cbm::M2_IN_HA);
307  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_litter_soil_3 * cbm::M2_IN_HA);
308  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( n_litter_soil_1 * cbm::M2_IN_HA);
309  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( n_litter_soil_2 * cbm::M2_IN_HA);
310  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( n_litter_soil_3 * cbm::M2_IN_HA);
311  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_algae_tot * cbm::M2_IN_HA);
312  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( n_algae_tot * cbm::M2_IN_HA);
313  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_stub * cbm::M2_IN_HA);
314  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( n_stub * cbm::M2_IN_HA);
315  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_litter_above * cbm::M2_IN_HA);
316  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( n_litter_above * cbm::M2_IN_HA);
317  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( (c_wood + c_aorg + c_mic_1 + c_mic_2 + c_mic_3 +
318  c_hum_1 + c_hum_2 + c_hum_3 + c_litter_soil_1 + c_litter_soil_2 + c_litter_soil_3 +
319  c_algae + c_stub + c_sol) * cbm::M2_IN_HA);
320  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( (n_wood + n_aorg + n_mic_1 + n_mic_2 + n_mic_3 +
321  n_hum_1 + n_hum_2 + n_hum_3 + n_litter_soil_1 + n_litter_soil_2 + n_litter_soil_3 +
322  n_algae + n_stub + n_sol) * cbm::M2_IN_HA);
323 
324  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( n_sbl * cbm::M2_IN_HA);
325 
326  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( soc20 / soilmass20);
327  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( soc40 / soilmass40);
328  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( totn20 / soilmass20);
329  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( totn40 / soilmass40);
330  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.fe2_sl.sum() * cbm::M2_IN_HA);
331  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.fe3_sl.sum() * cbm::M2_IN_HA);
332  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.till_effect_sl.sum() / sl_.soil_layer_cnt());
333  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( freeze_thaw_fact_sl.sum());
334  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( litter_height);
335  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( MeTrX_get_ph_wl());
336  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.ph_sl[0]);
337  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_no3_groundwater_access * cbm::M2_IN_HA);
338  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);
339  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_nit_nh4_no2 * cbm::M2_IN_HA);
340  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_nit_no2_no3_sl.sum() * cbm::M2_IN_HA);
341  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_nit_no2_no * cbm::M2_IN_HA);
342  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_nit_no2_n2o * cbm::M2_IN_HA);
343  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_denit_no3_no2 * cbm::M2_IN_HA);
344  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_denit_no2_no * cbm::M2_IN_HA);
345  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_denit_no2_n2o * cbm::M2_IN_HA);
346  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_denit_no2_n2 * cbm::M2_IN_HA);
347  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_denit_no_n2o * cbm::M2_IN_HA);
348  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_denit_no_n2 * cbm::M2_IN_HA);
349  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_denit_n2o_n2 * cbm::M2_IN_HA);
350  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_chemodenit_no2_no * cbm::M2_IN_HA);
351  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_ch4_oxidation_sl.sum() * cbm::M2_IN_HA);
352  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_ch4_production_hydrogen_sl.sum() * cbm::M2_IN_HA);
353  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_ch4_production_acetate_sl.sum() * cbm::M2_IN_HA);
354  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_ch4_plant.sum() * cbm::M2_IN_HA);
355  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_ch4_soil.sum() * cbm::M2_IN_HA);
356  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_ch4_water.sum() * cbm::M2_IN_HA);
357  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_ch4_bubbling.sum() * cbm::M2_IN_HA);
358  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_ch4_leach.sum() * cbm::M2_IN_HA);
359  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_o2_plant.sum() * cbm::M2_IN_HA);
360 
361  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);
362  accumulated_c_litter_above_old = sc_.accumulated_c_litter_stubble + sc_.accumulated_c_litter_wood_above;
363 
364  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);
365  accumulated_c_litter_below_old = sc_.accumulated_c_litter_below_sl.sum() + sc_.accumulated_c_litter_wood_below_sl.sum();
366 
367  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_c_fix_algae * cbm::M2_IN_HA);
368  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_n_fix_algae * cbm::M2_IN_HA);
369  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);
370  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_decay_c_mic_sl.sum()*cbm::M2_IN_HA);
371  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_co2_prod_mic_1_growth * cbm::M2_IN_HA);
372  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_co2_prod_mic_1_maintenance * cbm::M2_IN_HA);
373  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_co2_prod_mic_2 * cbm::M2_IN_HA);
374  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_co2_prod_mic_3_acetate_prod * cbm::M2_IN_HA);
375  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_co2_prod_mic_3_acetate_cons * cbm::M2_IN_HA);
376  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_co2_prod_ch4_prod * cbm::M2_IN_HA);
377  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_co2_prod_ch4_cons * cbm::M2_IN_HA);
378  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_h2_c_eq_prod_sl.sum() * cbm::M2_IN_HA);
379  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_acetate_prod_sl.sum() * cbm::M2_IN_HA);
380  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_acetate_cons_fe3_sl.sum() * cbm::M2_IN_HA/FE3_ACETATE_REDUCTION_RATIO);
381  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_h2_c_eq_cons_fe3_sl.sum() * cbm::M2_IN_HA/FE3_ACETATE_REDUCTION_RATIO);
382  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_doc_prod_decomp_litter * cbm::M2_IN_HA);
383  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_doc_prod_decomp_humus * cbm::M2_IN_HA);
384  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_doc_prod_decomp_aorg * cbm::M2_IN_HA);
385  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( dC_root_exsudates * cbm::M2_IN_HA);
386  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_doc_prod_sl.sum() * cbm::M2_IN_HA);
387  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_c_humify_doc_hum_1_sl.sum() * cbm::M2_IN_HA);
388  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_c_humify_sol_hum_1_sl.sum() * cbm::M2_IN_HA);
389  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_c_humify_cel_hum_1_sl.sum() * cbm::M2_IN_HA);
390  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_c_humify_lig_hum_1_sl.sum() * cbm::M2_IN_HA);
391  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_c_humify_lig_hum_2_sl.sum() * cbm::M2_IN_HA);
392  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_c_humify_mic_hum_1_sl.sum() * cbm::M2_IN_HA);
393  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_c_humify_mic_hum_2_sl.sum() * cbm::M2_IN_HA);
394  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_c_humify_hum_1_hum_2_sl.sum() * cbm::M2_IN_HA);
395  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_c_humify_hum_2_hum_3_sl.sum() * cbm::M2_IN_HA);
396  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_min_n_decomp * cbm::M2_IN_HA);
397  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_min_n_aorg * cbm::M2_IN_HA);
398  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_min_n_mic_1 * cbm::M2_IN_HA);
399  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_min_n_mic_2 * cbm::M2_IN_HA);
400  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_min_n_mic_3 * cbm::M2_IN_HA);
401  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_assi_c_mic_1 * cbm::M2_IN_HA);
402  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_assi_c_mic_2 * cbm::M2_IN_HA);
403  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( day_assi_c_mic_3 * cbm::M2_IN_HA);
404 
405  return output_writer_.write_daily( output_data_);
406 }
double MeTrX_get_ph_wl()
Definition: soilchemistry-metrx-physics-chemistry.cpp:601
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().

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

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

631 {
632  for ( size_t l = 0; l < sl_.soil_layer_cnt(); ++l)
633  {
634  LDNDC_OUTPUT_SET_COLUMN_INDEX(0);
635  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( -sc_.depth_sl[l]);
636  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_humus_1_sl[l]);
637  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_humus_2_sl[l]);
638  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_humus_3_sl[l]);
639  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.C_aorg_sl[l]);
640  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.C_micro1_sl[l]+sc_.C_micro2_sl[l]+sc_.C_micro3_sl[l]);
641 
642  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]);
643  output_writer_.output_writer_layer_yearly.accumulated_n_no3_no2_denitrification_sl[l] = accumulated_n_no3_no2_denitrification_sl[l];
644 
645  lerr_t rc_write = output_writer_.write_layer_yearly( l, output_data_);
646  if ( rc_write)
647  {
648  return LDNDC_ERR_FAIL;
649  }
650  }
651 
652  return LDNDC_ERR_OK;
653 }
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().

658 {
659  for ( size_t l = 0; l < sl_.soil_layer_cnt(); ++l)
660  {
661  LDNDC_OUTPUT_SET_COLUMN_INDEX(0);
662  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( -sc_.depth_sl[l]);
663 
664  //pools that exist for each soil layer
665  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.urea_sl[l]);
666  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]);
667  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.N_aorg_sl[l]);
668  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( n_humus_1_sl[l]);
669  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( n_humus_2_sl[l]);
670  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( n_humus_3_sl[l]);
671  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( n_micro_1_sl[l] + n_micro_2_sl[l] + n_micro_3_sl[l]);
672  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.nh3_liq_sl[l] + sc_.nh3_gas_sl[l]);
673  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nh4_ae_sl[l] + nh4_an_sl[l] + sc_.clay_nh4_sl[l]);
674  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( don_ae_sl[l] + don_an_sl[l]);
675  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( no3_ae_sl[l] + no3_an_sl[l]);
676  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.no2_sl[l] + sc_.an_no2_sl[l]);
677  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]);
678  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]);
679 
680  //surface pools
681  if( l == 0 )
682  {
683  double nplant(0.0);
684  for ( PlantIterator vt = this->m_veg->begin(); vt != this->m_veg->end(); ++vt)
685  {
686  nplant += (*vt)->total_nitrogen();
687  }
688 
689  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sb_.nh4_sbl.sum() );
690  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sb_.nh3_sbl.sum() );
691  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sb_.n2o_sbl.sum() );
692  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sb_.no_sbl.sum() );
693  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sb_.urea_sbl.sum() );
694  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sb_.no3_sbl.sum() );
695  //METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sb_.don_sbl.sum() );
696  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nplant );
697  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.n_wood + sc_.n_stubble_lit1 + sc_.n_stubble_lit2 + sc_.n_stubble_lit3 +
698  sc_.n_raw_lit_1_above + sc_.n_raw_lit_2_above + sc_.n_raw_lit_3_above);
699  }
700  else
701  {
702  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0 );
703  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0 );
704  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0 );
705  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0 );
706  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0 );
707  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0 );
708  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0 );
709  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0 );
710  //METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0 );
711  //METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( 0 );
712  }
713 
714  lerr_t rc_write = output_writer_.write_pools( l, output_data_);
715  if ( rc_write)
716  {
717  return LDNDC_ERR_FAIL;
718  }
719  }
720 
721  return LDNDC_ERR_OK;
722 }
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().

973 {
974  size_t s( lclock()->subday()-1);
975  LDNDC_OUTPUT_SET_COLUMN_INDEX(0);
976  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.C_micro1_sl.sum());
977  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.C_micro2_sl.sum());
978  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.C_micro3_sl.sum());
979  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.C_aorg_sl.sum());
980  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( nh4_ae_sl.sum()+nh4_an_sl.sum()+sc_.clay_nh4_sl.sum());
981  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( no3_ae_sl.sum());
982  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( no3_an_sl.sum());
983  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.doc_sl.sum());
984  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.an_doc_sl.sum());
985  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( ae_acetate_sl.sum());
986  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( an_acetate_sl.sum());
987 
988  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_ch4_bubbling[s]);
989  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_ch4_plant[s]);
990  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_ch4_soil[s]);
991  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_ch4_water[s]);
992  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_ch4_leach[s]);
993  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_ch4_prod[s]);
994  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_ch4_ox[s]);
995 
996  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_acetate_prod[s]);
997  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_doc_prod[s]);
998 
999  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( accumulated_n_no2_no3_nitrification_sl.sum() - output_writer_.output_writer_subdaily.accumulated_n_no2_no3_nitrification);
1000  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( accumulated_n_no3_no2_denitrification_sl.sum() - output_writer_.output_writer_subdaily.accumulated_n_no3_no2_denitrification);
1001 
1002  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_n2o_bubbling[s]);
1003  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_n2o_plant[s]);
1004  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_n2o_soil[s]);
1005  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_n2o_water[s]);
1006  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_no_bubbling[s]);
1007  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_no_plant[s]);
1008  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_no_soil[s]);
1009  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_no_water[s]);
1010  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_nh3_bubbling[s]);
1011  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_nh3_plant[s]);
1012  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_nh3_soil[s]);
1013  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_nh3_water[s]);
1014 
1015  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_plant_o2_cons[s]);
1016  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_o2_plant[s]);
1017  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( subdaily_algae_o2_prod[s]);
1018 
1019  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( MeTrX_get_ph_wl());
1020  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( sc_.ph_sl[0]);
1021  double anvf_mean( sc_.anvf_sl.sum() / sl_.soil_layer_cnt());
1022  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( anvf_mean);
1023 
1024  lerr_t rc_write = output_writer_.write_subdaily( output_data_);
1025  if ( rc_write)
1026  {
1027  return LDNDC_ERR_FAIL;
1028  }
1029 
1030  output_writer_.output_writer_subdaily.accumulated_n_no2_no3_nitrification = accumulated_n_no2_no3_nitrification_sl.sum();
1031  output_writer_.output_writer_subdaily.accumulated_n_no3_no2_denitrification = accumulated_n_no3_no2_denitrification_sl.sum();
1032 
1033  return LDNDC_ERR_OK;
1034 }
double MeTrX_get_ph_wl()
Definition: soilchemistry-metrx-physics-chemistry.cpp:601
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().

411 {
412  double surface_litter( c_algae + c_dead_algae + sc_.c_stubble_lit1 + sc_.c_stubble_lit2 + sc_.c_stubble_lit3);
413  double soc20( 0.0);
414  double c_hum_1_20( 0.0);
415  double c_hum_2_20( 0.0);
416  double c_hum_3_20( 0.0);
417  double c_litter_20( 0.0);
418  double c_aorg_20( 0.0);
419  for( size_t sl = 0; sl < sl_.soil_layer_cnt(); ++sl)
420  {
421  if ( cbm::flt_less_equal( sc_.depth_sl[sl], 0.2))
422  {
423  soc20 += sc_.C_aorg_sl[sl] + c_humus_1_sl[sl] + c_humus_2_sl[sl] + c_humus_3_sl[sl]
424  + sc_.C_micro1_sl[sl] + sc_.C_micro2_sl[sl] + sc_.C_micro3_sl[sl]
425  + sc_.C_lit1_sl[sl] + sc_.C_lit2_sl[sl] + sc_.C_lit3_sl[sl];
426  c_hum_1_20 += c_humus_1_sl[sl];
427  c_hum_2_20 += c_humus_2_sl[sl];
428  c_hum_3_20 += c_humus_3_sl[sl];
429  c_litter_20 += sc_.C_lit1_sl[sl] + sc_.C_lit2_sl[sl] + sc_.C_lit3_sl[sl];
430  c_aorg_20 += sc_.C_aorg_sl[sl];
431  }
432  else
433  {
434  break;
435  }
436  }
437 
438 #define METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT(__val__) LDNDC_OUTPUT_SET_COLUMN_((__val__),=,output_data_,1)
439  LDNDC_OUTPUT_SET_COLUMN_INDEX(0);
440 
441  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( surface_litter);
442  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( soc20);
443  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_hum_1_20);
444  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_hum_2_20);
445  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_hum_3_20);
446  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_litter_20);
447  METRX_OUTPUT_SET_COLUMN_AND_GOTO_NEXT( c_aorg_20);
448 
449  return output_writer_.write_yearly( output_data_);
450 }
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  sc_.accumulated_radon_emis += subdaily_radon_soil[ts] + subdaily_radon_plant[ts] + subdaily_radon_water[ts];
59 
60  sc_.accumulated_ch4_leach += subdaily_ch4_leach[ts];
61  }
62 
63  sc_.accumulated_co2_emis_auto += co2_auto_sl.sum();
64  sc_.accumulated_co2_emis_hetero += co2_hetero_sl.sum();
65 
66  if (timemode_ == TMODE_SUBDAILY)
67  {
68  for ( PlantIterator vt = this->m_veg->begin(); vt != this->m_veg->end(); ++vt)
69  {
70  accumulated_n_to_living_plant_and_algae_from_extern_sl[0] += (*vt)->n2_fixation;
71  }
72  }
73  else
74  {
75  for ( PlantIterator vt = this->m_veg->begin(); vt != this->m_veg->end(); ++vt)
76  {
77  accumulated_n_to_living_plant_and_algae_from_extern_sl[0] += (*vt)->d_n2_fixation;
78  }
79  }
80 
81  if ( timemode_ != TMODE_SUBDAILY || lclock()->is_position( TMODE_POST_DAILY))
82  {
83  /*************************/
84  /* Yearly rate variables */
85  /*************************/
86 
87  sc_.accumulated_c_fix_algae += day_c_fix_algae;
88  sc_.accumulated_n_fix_algae += day_n_fix_algae;
89  }
90 
92 
93  return LDNDC_ERR_OK;
94 }
lerr_t MeTrX_send_state()
Definition: soilchemistry-metrx-communicate.cpp:335
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_radon_source_sink(), 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  {
57 
61  MeTrX_advection();
64 
66 
68 
69  lerr_t rc_meta = MeTrX_metabolism();
70  if (rc_meta) { return rc_meta; }
71 
72  lerr_t rc_pertub = MeTrX_pertubation();
73  if (rc_pertub) { return rc_pertub; }
74 
77 
82 
87 
91 
93 
96 
99 
100  subdaily_time_step_ += 1;
101  }
102 
103  rc = MeTrX_balance_check( 2);
104  if ( rc) return LDNDC_ERR_FAIL;
105 
108 
109  rc = MeTrX_check_for_negative_value( "exit");
110  if ( rc) return LDNDC_ERR_FAIL;
111 
112  return LDNDC_ERR_OK;
113 }
lerr_t MeTrX_update()
Definition: soilchemistry-metrx-communicate.cpp:62
lerr_t MeTrX_spinup()
Definition: soilchemistry-metrx-spinup.cpp:68
void MeTrX_groundwater_access()
Definition: soilchemistry-metrx-transport.cpp:768
lerr_t MeTrX_nitrogen_fertilizer_release()
Transforms nitrogen from slow release nitrogen fertilizer to nh4.
Definition: soilchemistry-metrx-management.cpp:946
lerr_t MeTrX_till()
Definition: soilchemistry-metrx-management.cpp:702
lerr_t MeTrX_freeze_thaw()
Definition: soilchemistry-metrx-physics-chemistry.cpp:412
lerr_t MeTrX_radon_source_sink()
Definition: soilchemistry-metrx-physics-chemistry.cpp:475
void MeTrX_pH_calculation()
Definition: soilchemistry-metrx-physics-chemistry.cpp:615
lerr_t MeTrX_write_rates()
Definition: soilchemistry-metrx-integrate.cpp:19
lerr_t MeTrX_fertilize()
Definition: soilchemistry-metrx-management.cpp:33
void MeTrX_soil_organic_matter_turnover()
void MeTrX_nh3_nh4_equilibrium()
Definition: soilchemistry-metrx-physics-chemistry.cpp:32
void MeTrX_leaching()
Downwards transport of solutes, litter and humus with percolation water.
Definition: soilchemistry-metrx-transport.cpp:25
void MeTrX_urea_hydrolysis()
Definition: soilchemistry-metrx-management.cpp:879
lerr_t MeTrX_pertubation()
Definition: soilchemistry-metrx-transport.cpp:1638
lerr_t MeTrX_fragmentation()
Definition: soilchemistry-metrx-fragmentation.cpp:24
lerr_t MeTrX_plant_respiration(size_t)
Updates o2 and co2 concentrations in soil layers. There is no o2 mass conservation guaranteed because...
Definition: soilchemistry-metrx-management.cpp:1039
lerr_t MeTrX_manure()
Definition: soilchemistry-metrx-management.cpp:264
lerr_t MeTrX_write_output()
Definition: soilchemistry-metrx-output.cpp:16
lerr_t MeTrX_reset()
Definition: soilchemistry-metrx-reset.cpp:185
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:215
void MeTrX_clay_nh4_equilibrium()
Definition: soilchemistry-metrx-physics-chemistry.cpp:95
Here is the call graph for this function:

Member Data Documentation

◆ TNORM

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

Reference temperature [K]

Referenced by MeTrX_clay_nh4_equilibrium().