Example #1
0
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);
}
Example #2
0
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;
        }
    }
}