Пример #1
0
void 
UZRectMollerup::drain (const GeometryRect& geo,
                       const std::vector<size_t>& drain_cell,
		       const double drain_water_level,
                       const ublas::vector<double>& h,
                       const ublas::vector<double>& Theta_previous,
                       const ublas::vector<double>& Theta,
                       const ublas::vector<double>& S_vol,
#ifdef TEST_OM_DEN_ER_BRUGT
                       const ublas::vector<double>& S_macro,
#endif
                       const ublas::vector<double>& dq,
                       const double& ddt,
                       std::vector<bool>& drain_cell_on,
                       Solver::Matrix& A,
                       ublas::vector<double>& b,
                       const int debug, Treelog& msg)
{
  const size_t drain_size  = drain_cell.size (); // // number of drains   
    
  std::ostringstream tmp;

  for (size_t d = 0; d < drain_size; d++)
    {
      const size_t cell = drain_cell[d];

      // Pressure in drain cell [cm].
      const double drain_h = drain_water_level - geo.cell_z (cell); 
      
      if (drain_cell_on[d])    //drain on
        {
          //Calculate fluxes to drain from last timestep 
          
          double drain_sink = Theta_previous (cell);
          drain_sink -= Theta (cell);
          drain_sink -= ddt * (S_vol (cell)
#ifdef TEST_OM_DEN_ER_BRUGT
                               + S_macro (cell)
#endif
                               )/
            geo.cell_volume (cell);
                    
          const std::vector<size_t>& edges = geo.cell_edges (cell);
          const size_t edge_size = edges.size ();
          for (size_t i = 0; i < edge_size; i++)
            {
              const size_t edge = edges[i]; 
              const double flux = dq (edge) * geo.edge_area (edge) * ddt;
              const int from = geo.edge_from (edge);
              const int to = geo.edge_to (edge);
              
              if (cell == from)
                drain_sink  -= flux / geo.cell_volume (cell);
              else if (cell == to)
                drain_sink  += flux / geo.cell_volume (cell); 
            }
          if (drain_sink <= 0.0)
            drain_cell_on[d] = false;
        }
      else			// drain off
	if (h (cell) > 0.0)
	  drain_cell_on[d] = true;   	
          
      if (drain_h > 0.0 || drain_cell_on[d] == true)
        {
          const std::vector<size_t>& edges = geo.cell_edges (cell);
          const size_t edge_size = edges.size ();
          
          // Force pressure to be zero.
          for (size_t i = 0; i < edge_size; i++)
            {
              const size_t edge =  edges[i];
              if (!geo.edge_is_internal (edge))
                continue;
              
              const size_t other = geo.edge_other (edge, cell);
              A (cell, other) = 0.0;
            }
          A (cell, cell) = 1.0;
          b (cell) = std::max (drain_h, 0.0);
        }
    }
}