/// @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]; } } } }
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 ) ); }
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; }
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; }
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; }
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; } } }
/// @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]; } } }