Beispiel #1
0
 /// @brief Computes injected and produced volumes of all phases.
 /// Note 1: assumes that only the first phase is injected.
 /// Note 2: assumes that transport has been done with an
 ///         implicit method, i.e. that the current state
 ///         gives the mobilities used for the preceding timestep.
 /// @param[in]  props     fluid and rock properties.
 /// @param[in]  s         saturation values (for all P phases)
 /// @param[in]  src       if < 0: total outflow, if > 0: first phase inflow.
 /// @param[in]  dt        timestep used
 /// @param[out] injected  must point to a valid array with P elements,
 ///                       where P = s.size()/src.size().
 /// @param[out] produced  must also point to a valid array with P elements.
 void computeInjectedProduced(const IncompPropertiesInterface& props,
                              const std::vector<double>& s,
                              const std::vector<double>& src,
                              const double dt,
                              double* injected,
                              double* produced)
 {
     const int num_cells = src.size();
     const int np = s.size()/src.size();
     if (int(s.size()) != num_cells*np) {
         OPM_THROW(std::runtime_error, "Sizes of s and src vectors do not match.");
     }
     std::fill(injected, injected + np, 0.0);
     std::fill(produced, produced + np, 0.0);
     const double* visc = props.viscosity();
     std::vector<double> mob(np);
     for (int c = 0; c < num_cells; ++c) {
         if (src[c] > 0.0) {
             injected[0] += src[c]*dt;
         } else if (src[c] < 0.0) {
             const double flux = -src[c]*dt;
             const double* sat = &s[np*c];
             props.relperm(1, sat, &c, &mob[0], 0);
             double totmob = 0.0;
             for (int p = 0; p < np; ++p) {
                 mob[p] /= visc[p];
                 totmob += mob[p];
             }
             for (int p = 0; p < np; ++p) {
                 produced[p] += (mob[p]/totmob)*flux;
             }
         }
     }
 }
 /// @brief Computes injected and produced surface volumes of all phases.
 /// Note 1: assumes that only the first phase is injected.
 /// Note 2: assumes that transport has been done with an
 ///         implicit method, i.e. that the current state
 ///         gives the mobilities used for the preceding timestep.
 /// Note 3: Gives surface volume values, not reservoir volumes
 ///         (as the incompressible version of the function does).
 ///         Also, assumes that transport_src is given in surface volumes
 ///         for injector terms!
 /// @param[in]  props           fluid and rock properties.
 /// @param[in]  state           state variables (pressure, sat, surfvol)
 /// @param[in]  transport_src   if < 0: total resv outflow, if > 0: first phase surfv inflow
 /// @param[in]  dt              timestep used
 /// @param[out] injected        must point to a valid array with P elements,
 ///                             where P = s.size()/src.size().
 /// @param[out] produced        must also point to a valid array with P elements.
 void computeInjectedProduced(const BlackoilPropertiesInterface& props,
                              const BlackoilState& state,
                              const std::vector<double>& transport_src,
                              const double dt,
                              double* injected,
                              double* produced)
 {
     const int num_cells = transport_src.size();
     if (props.numCells() != num_cells) {
         OPM_THROW(std::runtime_error, "Size of transport_src vector does not match number of cells in props.");
     }
     const int np = props.numPhases();
     if (int(state.saturation().size()) != num_cells*np) {
         OPM_THROW(std::runtime_error, "Sizes of state vectors do not match number of cells.");
     }
     const std::vector<double>& press = state.pressure();
     const std::vector<double>& temp = state.temperature();
     const std::vector<double>& s = state.saturation();
     const std::vector<double>& z = state.surfacevol();
     std::fill(injected, injected + np, 0.0);
     std::fill(produced, produced + np, 0.0);
     std::vector<double> visc(np);
     std::vector<double> mob(np);
     std::vector<double> A(np*np);
     std::vector<double> prod_resv_phase(np);
     std::vector<double> prod_surfvol(np);
     for (int c = 0; c < num_cells; ++c) {
         if (transport_src[c] > 0.0) {
             // Inflowing transport source is a surface volume flux
             // for the first phase.
             injected[0] += transport_src[c]*dt;
         } else if (transport_src[c] < 0.0) {
             // Outflowing transport source is a total reservoir
             // volume flux.
             const double flux = -transport_src[c]*dt;
             const double* sat = &s[np*c];
             props.relperm(1, sat, &c, &mob[0], 0);
             props.viscosity(1, &press[c], &temp[c], &z[np*c], &c, &visc[0], 0);
             props.matrix(1, &press[c], &temp[c], &z[np*c], &c, &A[0], 0);
             double totmob = 0.0;
             for (int p = 0; p < np; ++p) {
                 mob[p] /= visc[p];
                 totmob += mob[p];
             }
             std::fill(prod_surfvol.begin(), prod_surfvol.end(), 0.0);
             for (int p = 0; p < np; ++p) {
                 prod_resv_phase[p] = (mob[p]/totmob)*flux;
                 for (int q = 0; q < np; ++q) {
                     prod_surfvol[q] += prod_resv_phase[p]*A[q + np*p];
                 }
             }
             for (int p = 0; p < np; ++p) {
                 produced[p] += prod_surfvol[p];
             }
         }
     }
 }
Beispiel #3
0
void death( char_data* victim, char_data* ch, char* dt )
{
  char               tmp  [ TWO_LINES ];
  obj_data*       corpse;
  content_array*   where  = victim->array;
  char_data*         rch;
  bool           survive;
 
  remove_bit( &victim->status, STAT_BERSERK );

  if( ch == NULL ) 
    for( int i = 0; i < *where; i++ ) 
      if( ( rch = character( where->list[i] ) ) != NULL 
        && includes( rch->aggressive, victim ) ) {
        ch = rch;
        break;
        }

  stop_fight( victim );
  clear_queue( victim );

  if( !can_die( victim ) )
    return;
 
  disburse_exp( victim );
  register_death( victim, ch, dt );

  clear_queue( victim );
  death_cry( victim );

  if( survive = !die_forever( victim ) )
    raw_kill( victim );

  corpse = make_corpse( victim, where );
  loot_corpse( corpse, ch, victim );

  if( survive ) 
    return;

  if( mob( victim ) != NULL ) {
    victim->Extract( );
    return;
    }

  sprintf( tmp, "%s's soul is taken by death.", victim->Name( ) );
  info( tmp, LEVEL_BUILDER, tmp, IFLAG_DEATHS, 1, victim );

  clear_screen( victim );
  reset_screen( victim );

  send( victim, "Death is surprisingly peaceful.\n\r" );
  send( victim, "Good night.\n\r" );

  purge( player( victim ) );
}
Beispiel #4
0
void
PorousFlowDarcyBase::harmonicMean(JacRes res_or_jac, unsigned int ph, unsigned int pvar)
{
  // The number of nodes in the element
  const unsigned int num_nodes = _test.size();

  std::vector<Real> mob(num_nodes);
  unsigned num_zero = 0;
  unsigned zero_mobility_node = std::numeric_limits<unsigned>::max();
  Real harmonic_mob = 0;
  for (unsigned n = 0; n < num_nodes; ++n)
  {
    mob[n] = mobility(n, ph);
    if (mob[n] == 0.0)
    {
      zero_mobility_node = n;
      num_zero++;
    }
    else
      harmonic_mob += 1.0 / mob[n];
  }
  if (num_zero > 0)
    harmonic_mob = 0.0;
  else
    harmonic_mob = (1.0 * num_nodes) / harmonic_mob;

  // d(harmonic_mob)/d(PorousFlow variable at node n)
  std::vector<Real> dharmonic_mob(num_nodes, 0.0);
  if (res_or_jac == JacRes::CALCULATE_JACOBIAN)
  {
    const Real harm2 = std::pow(harmonic_mob, 2) / (1.0 * num_nodes);
    if (num_zero == 0)
      for (unsigned n = 0; n < num_nodes; ++n)
        dharmonic_mob[n] = dmobility(n, ph, pvar) * harm2 / std::pow(mob[n], 2);
    else if (num_zero == 1)
      dharmonic_mob[zero_mobility_node] =
          num_nodes * dmobility(zero_mobility_node, ph, pvar); // other derivs are zero
    // if num_zero > 1 then all dharmonic_mob = 0.0
  }

  if (res_or_jac == JacRes::CALCULATE_JACOBIAN)
    for (unsigned n = 0; n < num_nodes; ++n)
      for (_j = 0; _j < _phi.size(); _j++)
      {
        _jacobian[ph][n][_j] *= harmonic_mob;
        if (_test.size() == _phi.size())
          _jacobian[ph][n][_j] += dharmonic_mob[_j] * _proto_flux[ph][n];
      }

  if (res_or_jac == JacRes::CALCULATE_RESIDUAL)
    for (unsigned n = 0; n < num_nodes; ++n)
      _proto_flux[ph][n] *= harmonic_mob;
}
int main()  {  
    int t, n, m, p, i, j;  
    //筛法算出num[]以及h[]  
    for (i = 2; i < M; i++)  {  
        if (num[i]) continue;  
        for (j = i; j < M; j+=i) {  
            int tp = cal(j, i);  
            num[j] += tp;  
            if (tp > 1)      //j中含有多个i,必然存在平方因子  
                h[j] = -1;  
            else if (h[j] >= 0)    
                ++h[j];  
        }  
    }  
    //枚举i作为公因子,对B(j)的贡献值为:mob(j/i)  
    for (i = 1; i < M; i++) 
        for (j = i; j < M; j+=i)  
            F[j][num[i]] += mob(j/i);  
   
    //为了表示素因子数<=j的意义,求j的前缀和  
    for (i = 1; i < M; i++)  
        for (j = 1; j < N; j++)  
            F[i][j] += F[i][j-1];  
    
    //为了分组加速求解,求i的前缀和  
    for (i = 1; i < M; i++)  
        for (j = 0; j < N; j++)  
            F[i][j] += F[i-1][j];  
    
    scanf("%d", &t);  
    while (t--) {  
        scanf("%d%d%d", &n, &m, &p);  
        LL ans = 0;  
        if (p >= N) ans = (LL)n*m;  
        else  {  
            if (n > m)  {  
                n ^= m;  
                m ^= n;  
                n ^= m;  
            }  
            for (i = 1; i <= n; i = j + 1) {  
                j = min(n/(n/i), m/(m/i));  
                ans += ((LL)F[j][p]-F[i-1][p])*(n/i)*(m/i);  
            }  
        }  
        printf("%I64d\n", ans);  
    }  
    return 0;  
}  
Beispiel #6
0
char_data* active_shop( char_data* ch )
{
  room_data*    room  = ch->in_room;
  char_data*  keeper;

  if( !is_set( &room->room_flags, RFLAG_PET_SHOP )
    && !is_set( &room->room_flags, RFLAG_SHOP ) ) 
    return NULL;

  for( int i = 0; i < room->contents; i++ )
    if( ( keeper = mob( room->contents[i] ) ) != NULL
      && keeper->pShop != NULL && keeper->pShop->room == room 
      && IS_AWAKE( keeper ) && ch->Seen( keeper ) )
      return keeper;

  return NULL;
}
Beispiel #7
0
char_data* find_keeper( char_data* ch )
{
  char_data* keeper = NULL;

  for( int i = 0; ; i++ ) {
    if( i >= *ch->array ) {
      if( is_set( &ch->in_room->room_flags, RFLAG_PET_SHOP )
        || is_set( &ch->in_room->room_flags, RFLAG_SHOP ) ) {
        send( ch, "The shop keeper is not around right now.\r\n" );
        return NULL;
        }
      send( ch, "You are not in a shop.\r\n" );
      return NULL;
      } 
    if( ( keeper = mob( ch->array->list[i] ) ) != NULL
      && keeper->pShop != NULL )
      break;
    }

  if( !IS_AWAKE( keeper ) ) {
    send( ch, "The shopkeeper seems to be asleep.\r\n" );
    return NULL;
    }
   
  if( !ch->Seen( keeper ) && ch->shdata->level < LEVEL_APPRENTICE ) {
    do_say( keeper, "I don't trade with folks I can't see." );
    return NULL;
    }

  if( ch->species != NULL
    && !is_set( &ch->species->act_flags, ACT_HUMANOID ) ) {
    send( ch,
      "You can't carry anything so shopping is rather pointless.\r\n" );
    return NULL;
    }

  return keeper;
}
Beispiel #8
0
void do_shedit( char_data* ch, char* argument )
{
  char                  buf  [MAX_STRING_LENGTH ];
  mob_data*          keeper;
  shop_data*           shop;
  char_data*         victim;
  species_data*     species;
  int                number;
  
  for( shop = shop_list; shop != NULL; shop = shop->next )
    if( ch->in_room == shop->room ) 
      break;  

  if( *argument != '\0' && !can_edit( ch, ch->in_room ) )
    return;

  if( exact_match( argument, "new" ) ) {
    if( shop != NULL ) {
      send( ch, "There is already a shop here.\r\n" );
      return;
      }
    shop = new shop_data;
    shop->room = ch->in_room;
    shop->custom = NULL;
    shop->keeper = -1;
    shop->repair = 0;
    shop->materials = 0;
    shop->buy_type[0] = 0;
    shop->buy_type[1] = 0;
    shop->next = shop_list;
    shop_list = shop;
    send( ch, "New shop created here.\r\n" );
    return;
    }

  if( shop == NULL ) {
    send( ch, "There is no shop associated with this room.\r\n" );
    return;
    }

  if( *argument == '\0' ) {
    species = get_species( shop->keeper ); 
    sprintf( buf, "Shop Keeper: %s  [ Vnum: %d ]\r\n\r\n", ( species == NULL
      ? "none" : species->descr->name ), shop->keeper );
    sprintf( buf+strlen( buf ), "Repair: %d\r\n\r\n", shop->repair );
    send( buf, ch );
    return;
    }
  
  if( exact_match( argument, "delete" ) ) {
    remove( shop_list, shop );
    for( int i = 0; i < mob_list; i++ )
      if( mob_list[i]->pShop == shop )
        mob_list[i]->pShop = NULL;
    send( ch, "Shop deleted.\r\n" );
    return;
    }
   
  if( matches( argument, "keeper" ) ) {
    if( ( victim = one_character( ch, argument, "set keepr",
      ch->array ) ) == NULL )
      return;

    if( ( keeper = mob( victim ) ) == NULL ) {
      send( ch, "Players can not be shop keepers.\r\n" );
      return;
      }
    shop->keeper = keeper->species->vnum;
    keeper->pShop = shop;
    send( ch, "Shop keeper set to %s.\r\n", keeper->descr->name );
    return;
    }

  if( matches( argument, "repair" ) ) {
    if( ( number = atoi( argument ) ) < 0 || number > 10 ) {
      send( ch,
        "A shop's repair level must be between 0 and 10.\r\n" ); 
      return;
      }
    shop->repair = number;
    send( ch, "The shop's repair level is set to %d.\r\n", number );
    } 
}
 /// @brief Computes injected and produced volumes of all phases,
 ///        and injected and produced polymer mass - in the compressible case.
 /// Note 1: assumes that only the first phase is injected.
 /// Note 2: assumes that transport has been done with an
 ///         implicit method, i.e. that the current state
 ///         gives the mobilities used for the preceding timestep.
 /// @param[in]  props     fluid and rock properties.
 /// @param[in]  polyprops polymer properties
 /// @param[in]  state     state variables (pressure, fluxes etc.)
 /// @param[in]  transport_src  if < 0: total reservoir volume outflow,
 ///                       if > 0: first phase *surface volume* inflow.
 /// @param[in]  inj_c     injected concentration by cell
 /// @param[in]  dt        timestep used
 /// @param[out] injected  must point to a valid array with P elements,
 ///                       where P = s.size()/transport_src.size().
 /// @param[out] produced  must also point to a valid array with P elements.
 /// @param[out] polyinj   injected mass of polymer
 /// @param[out] polyprod  produced mass of polymer
 void computeInjectedProduced(const BlackoilPropertiesInterface& props,
                              const Opm::PolymerProperties& polyprops,
                              const PolymerBlackoilState& state,
                              const std::vector<double>& transport_src,
                              const std::vector<double>& inj_c,
                              const double dt,
                              double* injected,
                              double* produced,
                              double& polyinj,
                              double& polyprod)
 {
     const int num_cells = transport_src.size();
     if (props.numCells() != num_cells) {
         OPM_THROW(std::runtime_error, "Size of transport_src vector does not match number of cells in props.");
     }
     const int np = props.numPhases();
     if (int(state.saturation().size()) != num_cells*np) {
         OPM_THROW(std::runtime_error, "Sizes of state vectors do not match number of cells.");
     }
     const std::vector<double>& press = state.pressure();
     const std::vector<double>& temp = state.temperature();
     const std::vector<double>& s = state.saturation();
     const std::vector<double>& z = state.surfacevol();
     const std::vector<double>& c = state.getCellData( state.CONCENTRATION );
     const std::vector<double>& cmax = state.getCellData( state.CMAX );
     std::fill(injected, injected + np, 0.0);
     std::fill(produced, produced + np, 0.0);
     polyinj = 0.0;
     polyprod = 0.0;
     std::vector<double> visc(np);
     std::vector<double> kr_cell(np);
     std::vector<double> mob(np);
     std::vector<double> A(np*np);
     std::vector<double> prod_resv_phase(np);
     std::vector<double> prod_surfvol(np);
     double mc;
     for (int cell = 0; cell < num_cells; ++cell) {
         if (transport_src[cell] > 0.0) {
             // Inflowing transport source is a surface volume flux
             // for the first phase.
             injected[0] += transport_src[cell]*dt;
             polyinj += transport_src[cell]*dt*inj_c[cell];
         } else if (transport_src[cell] < 0.0) {
             // Outflowing transport source is a total reservoir
             // volume flux.
             const double flux = -transport_src[cell]*dt;
             const double* sat = &s[np*cell];
             props.relperm(1, sat, &cell, &kr_cell[0], 0);
             props.viscosity(1, &press[cell], &temp[cell], &z[np*cell], &cell, &visc[0], 0);
             props.matrix(1, &press[cell], &temp[cell], &z[np*cell], &cell, &A[0], 0);
             polyprops.effectiveMobilities(c[cell], cmax[cell], &visc[0],
                                           &kr_cell[0], &mob[0]);
             double totmob = 0.0;
             for (int p = 0; p < np; ++p) {
                 totmob += mob[p];
             }
             std::fill(prod_surfvol.begin(), prod_surfvol.end(), 0.0);
             for (int p = 0; p < np; ++p) {
                 prod_resv_phase[p] = (mob[p]/totmob)*flux;
                 for (int q = 0; q < np; ++q) {
                     prod_surfvol[q] += prod_resv_phase[p]*A[q + np*p];
                 }
             }
             for (int p = 0; p < np; ++p) {
                 produced[p] += prod_surfvol[p];
             }
             polyprops.computeMc(c[cell], mc);
             polyprod += produced[0]*mc;
         }
     }
 }
Beispiel #10
0
    /// @brief Computes injected and produced volumes of all phases,
    ///        and injected and produced polymer mass - in the compressible case.
    /// Note 1: assumes that only the first phase is injected.
    /// Note 2: assumes that transport has been done with an
    ///         implicit method, i.e. that the current state
    ///         gives the mobilities used for the preceding timestep.
    /// @param[in]  props     fluid and rock properties.
    /// @param[in]  polyprops polymer properties
    /// @param[in]  state     state variables (pressure, fluxes etc.)
    /// @param[in]  transport_src  if < 0: total reservoir volume outflow,
    ///                       if > 0: first phase *surface volume* inflow.
    /// @param[in]  inj_c     injected concentration by cell
    /// @param[in]  dt        timestep used
    /// @param[out] injected  must point to a valid array with P elements,
    ///                       where P = s.size()/transport_src.size().
    /// @param[out] produced  must also point to a valid array with P elements.
    /// @param[out] polyinj   injected mass of polymer
    /// @param[out] polyprod  produced mass of polymer
    void computeInjectedProduced(const BlackoilPropsAdInterface& props,
                                 const Opm::PolymerPropsAd& polymer_props,
                                 const PolymerBlackoilState& state,
                                 const std::vector<double>& transport_src,
                                 const std::vector<double>& inj_c,
                                 const double dt,
                                 double* injected,
                                 double* produced,
                                 double& polyinj,
                                 double& polyprod)
    {
        const int num_cells = transport_src.size();
        if (props.numCells() != num_cells) {
            OPM_THROW(std::runtime_error, "Size of transport_src vector does not match number of cells in props.");
        }
        const int np = props.numPhases();
        if (int(state.saturation().size()) != num_cells*np) {
            OPM_THROW(std::runtime_error, "Sizes of state vectors do not match number of cells.");
        }
		std::vector<int> cells(num_cells);
		const V p = Eigen::Map<const V>(&state.pressure()[0], num_cells, 1);
        const DataBlock s = Eigen::Map<const DataBlock>(&state.saturation()[0], num_cells, np);
		const V sw = s.col(0);
		const V so = s.col(1);
		const V c = Eigen::Map<const V>(&state.concentration()[0], num_cells, 1);
		const V cmax = Eigen::Map<const V>(&state.maxconcentration()[0], num_cells, 1);
		const V trans_src = Eigen::Map<const V>(&transport_src[0], num_cells, 1);
		V src = V::Constant(num_cells, -1.0); // negative is injec, positive is producer.
		for (int cell = 0; cell < num_cells; ++cell) {
			cells[cell] = cell;
			if(transport_src[cell] > 0.0) {
				src[cell] = 1.0;
			}
		}
        //Add PhasePresence make muOil() happy.
        std::vector<PhasePresence> phaseCondition(num_cells);
        for (int c = 0; c < num_cells; ++c) {
            phaseCondition[c] = PhasePresence();
            phaseCondition[c].setFreeWater();
            phaseCondition[c].setFreeOil();
        }
		const Selector<double> src_selector(src);
		const V one = V::Constant(num_cells, 1.0);
		const V zero = V::Zero(num_cells);
		const std::vector<V> kr = props.relperm(sw, so, zero, cells);
		const V muw = props.muWat(p, cells);
		const V muo = props.muOil(p, zero, phaseCondition, cells);
        const V krw_eff = polymer_props.effectiveRelPerm(c, cmax, kr[0]);
		const V inv_muw_eff = polymer_props.effectiveInvWaterVisc(c, muw.data());
		std::vector<V> mob(np);
		mob[0] = krw_eff * inv_muw_eff;
		mob[1] = kr[1] / muo;
		
		const V watmob_c = src_selector.select(mob[0], one);
		const V oilmob_c = src_selector.select(mob[1], zero);
		const V flux = trans_src * dt;
	    const V totmob_c = watmob_c + oilmob_c;
		const V wat_src = flux * (watmob_c / totmob_c);
		const V oil_src = flux * (oilmob_c / totmob_c);
		const V mc = polymer_props.polymerWaterVelocityRatio(c);
		
        polyinj = 0.0;
        polyprod = 0.0;
		std::fill(injected, injected + np , 0.0);
		std::fill(produced, produced + np , 0.0);
		for (int cell = 0; cell < num_cells; ++cell) {
			if (wat_src[cell] < 0) {
				injected[0] += wat_src[cell];
				polyinj += injected[0] * inj_c[cell];
			} else {
				produced[0] += wat_src[cell];
				produced[1] += oil_src[cell];
				polyprod += produced[0] * mc[cell];
			}
		}
    }