bool Well::setInjectionProperties(size_t timeStep , const WellInjectionProperties newProperties) { if (isProducer(timeStep)) switchToInjector( timeStep ); m_isProducer->update(timeStep , false); return m_injectionProperties->update(timeStep, newProperties); }
Entity* EntityPool::getNew(Info name) { int i = contains(name.getName()); if (i != -1) { // if already have one if (isProducer(name)) { return sendToInUseAndReturn(i); } else { return pool[i]; } } else { // don't already have one Entity *e = create(name.getName()); if (isProducer(name)) { inUse.push_back(e); return e; } pool.push_back(e); return e; } }
bool Well::setInjectionProperties(size_t timeStep , const WellInjectionProperties& newProperties) { if (isProducer(timeStep)) switchToInjector( timeStep ); m_isProducer.update(timeStep , false); bool update = m_injectionProperties.update(timeStep, newProperties); if (update) addEvent( ScheduleEvents::INJECTION_UPDATE, timeStep ); return update; }
void* routine(void* info) { struct thInfo* thinfo = (struct thInfo*) info; if(isConsumer(&thinfo->flags)) { CriticalAdd(&cCountLock, &cCount, 1); int r=0; while(r == 0 && getAmount(&thinfo->flags) > 0 ) { r = Consumer(thinfo->persist, ConsumerAction, thinfo); } CriticalAdd(&cCountLock, &cCount, -1); } if(isProducer(&thinfo->flags)) { CriticalAdd(&pCountLock, &pCount, 1); int r=0; while(r == 0 && getAmount(&thinfo->flags) > 0 ) { r = Producer(thinfo->persist, ProducerAction, thinfo); } CriticalAdd(&pCountLock, &pCount, -1); } return NULL; }
pair<Date, double> FlowEnd::getFlowplanDateQuantity(const FlowPlan* fl) const { if (isConsumer() && !fl->getOperationPlan()->getConsumeMaterial()) return make_pair(fl->getOperationPlan()->getEnd(), 0.0); else if (isProducer() && !fl->getOperationPlan()->getProduceMaterial()) return make_pair(fl->getOperationPlan()->getEnd(), 0.0); else if (fl->getConfirmed()) return make_pair( fl->getOperationPlan()->getEnd(), fl->getQuantity() ); else return make_pair( fl->getOperationPlan()->getEnd(), getEffective().within(fl->getDate()) && fl->getOperationPlan()->getQuantity() ? getQuantityFixed() + fl->getOperationPlan()->getQuantity() * getQuantity() : 0.0 ); }
bool Well::isInjector(size_t timeStep) const { return !isProducer(timeStep); }
pair<Date, double> FlowTransferBatch::getFlowplanDateQuantity(const FlowPlan* fl) const { double batch_quantity = getTransferBatch(); if (!batch_quantity || fl->getOperationPlan()->getSetupEnd() == fl->getOperationPlan()->getEnd()) // Default to a simple flowplan at the start or end return make_pair( isConsumer() ? fl->getOperationPlan()->getSetupEnd() : fl->getOperationPlan()->getEnd(), getQuantityFixed() + getQuantity() * fl->getOperationPlan()->getQuantity() ); // Compute the number of batches double total_quantity = getQuantityFixed() + fl->getOperationPlan()->getQuantity() * getQuantity(); if (isConsumer() && !fl->getOperationPlan()->getConsumeMaterial()) total_quantity = 0.0; else if (isProducer() && !fl->getOperationPlan()->getProduceMaterial()) total_quantity = 0.0; double batches = ceil((getQuantity() > 0 ? total_quantity : -total_quantity) / getTransferBatch()); if (!batches) batches = 1; else if (batches > 50) { // Put a limit to the number of batches batches = 50; batch_quantity = (getQuantity() > 0 ? total_quantity : -total_quantity) / 50; } // Count the index of this batch bool found = false; long count = 0; long totalcount = 0; FlowPlan* cur_flpln = fl->getOperationPlan()->firstflowplan; FlowPlan* prev_flpln = nullptr; while (cur_flpln) { if (cur_flpln == fl) found = true; if (cur_flpln->getFlow() == fl->getFlow()) { ++totalcount; if (totalcount > batches && !count) { if (cur_flpln->oper->firstflowplan == cur_flpln) cur_flpln->oper->firstflowplan = cur_flpln->nextFlowPlan; else prev_flpln->nextFlowPlan = cur_flpln->nextFlowPlan; auto almost_dead = cur_flpln; cur_flpln = cur_flpln->nextFlowPlan; delete almost_dead; continue; } if (!found) ++count; } prev_flpln = cur_flpln; cur_flpln = cur_flpln->nextFlowPlan; } Duration op_delta; Date op_date = fl->getOperation()->calculateOperationTime( fl->getOperationPlan(), fl->getOperationPlan()->getSetupEnd(), fl->getOperationPlan()->getEnd(), &op_delta ).getStart(); if (!count) { // The first flowplan in the list will always be there, even when the quantity becomes 0. // It is responsible for creating extra flowplans when required. while (totalcount < batches) { auto newflowplan = new FlowPlan(fl->getOperationPlan(), this); newflowplan->setFollowingBatch(true); ++totalcount; } } if (getQuantity() > 0 || getQuantityFixed() > 0) { // Producing a batch op_delta = static_cast<long>(op_delta) / static_cast<long>(batches) * (count + 1); total_quantity -= count * batch_quantity; if (total_quantity < 0.0) total_quantity = 0.0; return make_pair( fl->getOperation()->calculateOperationTime( fl->getOperationPlan(), op_date, op_delta, true ).getEnd(), total_quantity > batch_quantity ? batch_quantity : total_quantity ); } else { // Consuming a batch op_delta = static_cast<long>(op_delta) / static_cast<long>(batches) * count; total_quantity += count * getTransferBatch(); if (total_quantity > 0.0) total_quantity = 0.0; return make_pair( fl->getOperation()->calculateOperationTime( fl->getOperationPlan(), op_date, op_delta, true ).getEnd(), total_quantity < -batch_quantity ? -batch_quantity : total_quantity ); } }
bool Well::setTracerProperties(size_t timeStep , const WellTracerProperties& newProperties) { if (isProducer(timeStep)) throw std::invalid_argument("WTRACER keyword can only be applied to injectors"); return m_tracerProperties.update(timeStep, newProperties); }