void Movement1D::tick (const Soil& soil, SoilWater& soil_water, const SoilHeat& soil_heat, Surface& surface, Groundwater& groundwater, const Time& time, const Weather& weather, const double dt, Treelog& msg) { const size_t edge_size = geo->edge_size (); const size_t cell_size = geo->cell_size (); TREELOG_MODEL (msg); // Cells. std::vector<double> S_sum (cell_size); std::vector<double> h_old (cell_size); std::vector<double> Theta_old (cell_size); std::vector<double> h_ice (cell_size); std::vector<double> h (cell_size); std::vector<double> Theta (cell_size); for (size_t c = 0; c < cell_size; c++) { S_sum[c] = soil_water.S_sum (c); h_old[c] = soil_water.h_old (c); Theta_old[c] = soil_water.Theta_old (c); h_ice[c] = soil_water.h_ice (c); h[c] = soil_water.h (c); Theta[c] = soil_water.Theta (c); } // Edges. std::vector<double> q (edge_size, 0.0); std::vector<double> q_p (edge_size, 0.0); for (size_t e = 0; e < edge_size; e++) { q[e] = soil_water.q_matrix (e); q_p[e] = soil_water.q_tertiary (e); } tick_water (*geo, soil, soil_heat, surface, groundwater, S_sum, h_old, Theta_old, h_ice, h, Theta, q, q_p, dt, msg); soil_water.set_matrix (h, Theta, q); }
void MovementSolute::divide_top_incomming (const Geometry& geo, const SoilWater& soil_water, const double J_above, // [g/cm^2/h] std::map<size_t, double>& J_primary, std::map<size_t, double>& J_secondary, std::map<size_t, double>& J_tertiary) { daisy_assert (J_above < 0.0); // Negative upward flux. const std::vector<size_t>& edge_above = geo.cell_edges (Geometry::cell_above); const size_t edge_above_size = edge_above.size (); double total_water_in = 0.0; // [cm^3 W/h] double total_area = 0.0; // [cm^2 S] // Find incomming water in all domain. for (size_t i = 0; i < edge_above_size; i++) { const size_t edge = edge_above[i]; const int cell = geo.edge_other (edge, Geometry::cell_above); daisy_assert (geo.cell_is_internal (cell)); const double area = geo.edge_area (edge); // [cm^2 S] total_area += area; const double in_sign = geo.cell_is_internal (geo.edge_to (edge)) ? 1.0 : -1.0; daisy_assert (in_sign < 0); // Tertiary domain. const double q_tertiary = soil_water.q_tertiary (edge); daisy_assert (std::isfinite (q_tertiary)); const double tertiary_in = q_tertiary * in_sign; // [cm^3 W/cm^2 S/h] if (tertiary_in > 0) { total_water_in += tertiary_in * area; J_tertiary[edge] = q_tertiary; // [cm^3 W/cm^2 S/h] } else J_tertiary[edge] = 0.0; // Secondary domain. const double q_secondary = soil_water.q_secondary (edge); const double secondary_in = q_secondary * in_sign; // [cm^3 W/cm^2 S/h] if (secondary_in > 0) { total_water_in += secondary_in * area; J_secondary[edge] = q_secondary; // [cm^3 W/cm^2 S/h] } else J_secondary[edge] = 0.0; // Primary domain. const double q_primary = soil_water.q_primary (edge); const double primary_in = q_primary * in_sign; // [cm^3 W/cm^2 S/h] if (primary_in > 0) { total_water_in += primary_in * area; J_primary[edge] = q_primary; // [cm^3 W/cm^2 S/h] } else J_primary[edge] = 0.0; } daisy_approximate (total_area, geo.surface_area ()); if (total_water_in > 1e-9 * total_area) // Scale with incomming solute. { // [g/cm^3 W] = [g/cm^2 S/h] * [cm^2 S] / [cm^3 W/h] const double C_above = -J_above * total_area / total_water_in; daisy_assert (std::isfinite (C_above)); for (size_t i = 0; i < edge_above_size; i++) { const size_t edge = edge_above[i]; // [g/cm^2 S/h] = [cm^3 W/cm^2 S/h] * [g/cm^3 W] J_tertiary[edge] *= C_above; J_secondary[edge] *= C_above; J_primary[edge] *= C_above; } } else { daisy_assert (total_water_in >= 0.0); for (size_t i = 0; i < edge_above_size; i++) { const size_t edge = edge_above[i]; const double in_sign = geo.cell_is_internal (geo.edge_to (edge)) ? 1.0 : -1.0; J_tertiary[edge] = 0.0; J_secondary[edge] = 0.0; J_primary[edge] = -J_above * in_sign; } } }