mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
WIP of the WellMultiSegment and WellStateMultiSegment
This commit is contained in:
parent
c91e144a1d
commit
60dd7743c3
@ -46,6 +46,7 @@ list (APPEND MAIN_SOURCE_FILES
|
|||||||
opm/autodiff/VFPProperties.cpp
|
opm/autodiff/VFPProperties.cpp
|
||||||
opm/autodiff/VFPProdProperties.cpp
|
opm/autodiff/VFPProdProperties.cpp
|
||||||
opm/autodiff/VFPInjProperties.cpp
|
opm/autodiff/VFPInjProperties.cpp
|
||||||
|
opm/autodiff/WellMultiSegment.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -147,5 +148,7 @@ list (APPEND PUBLIC_HEADER_FILES
|
|||||||
opm/autodiff/VFPHelpers.hpp
|
opm/autodiff/VFPHelpers.hpp
|
||||||
opm/autodiff/VFPProdProperties.hpp
|
opm/autodiff/VFPProdProperties.hpp
|
||||||
opm/autodiff/VFPInjProperties.hpp
|
opm/autodiff/VFPInjProperties.hpp
|
||||||
|
opm/autodiff/WellStateMultiSegment.hpp
|
||||||
|
opm/autodiff/WellMultiSegment.hpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <opm/autodiff/WellMultiSegment.hpp>
|
||||||
|
|
||||||
namespace Opm
|
namespace Opm
|
||||||
{
|
{
|
||||||
@ -137,6 +138,19 @@ namespace Opm
|
|||||||
WellState well_state;
|
WellState well_state;
|
||||||
well_state.init(wells, state, prev_well_state);
|
well_state.init(wells, state, prev_well_state);
|
||||||
|
|
||||||
|
const std::vector<WellConstPtr>& wells_ecl = eclipse_state_->getSchedule()->getWells(timer.currentStepNum());
|
||||||
|
|
||||||
|
std::vector<WellMutliSegmentPtr> wells_multisegment;
|
||||||
|
|
||||||
|
wells_multisegment.reserve(wells_ecl.size());
|
||||||
|
|
||||||
|
/* std::cout << " the number of the wells from EclipseState " << wells_ecl.size() << std::endl;
|
||||||
|
for (size_t i = 0; i < wells_ecl.size(); ++i) {
|
||||||
|
std::cout << " well name " << wells_ecl[i]->name() << std::endl;
|
||||||
|
std::cout << " segment wells " << wells_ecl[i]->isMultiSegment() << std::endl;
|
||||||
|
}
|
||||||
|
std::cin.ignore(); */
|
||||||
|
|
||||||
// give the polymer and surfactant simulators the chance to do their stuff
|
// give the polymer and surfactant simulators the chance to do their stuff
|
||||||
asImpl().handleAdditionalWellInflow(timer, wells_manager, well_state, wells);
|
asImpl().handleAdditionalWellInflow(timer, wells_manager, well_state, wells);
|
||||||
|
|
||||||
|
135
opm/autodiff/WellMultiSegment.cpp
Normal file
135
opm/autodiff/WellMultiSegment.cpp
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
Copyright 2015 SINTEF ICT, Applied Mathematics.
|
||||||
|
|
||||||
|
This file is part of the Open Porous Media project (OPM).
|
||||||
|
|
||||||
|
OPM is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OPM is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <opm/autodiff/WellMultiSegment.hpp>
|
||||||
|
#include <opm/parser/eclipse/EclipseState/Schedule/SegmentSet.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
namespace Opm
|
||||||
|
{
|
||||||
|
|
||||||
|
// how to find the order of the well?
|
||||||
|
void WellMultiSegment::init(WellConstPtr well, size_t time_step, const Wells* wells) {
|
||||||
|
CompletionSetConstPtr completion_set = well->getCompletions(time_step);
|
||||||
|
|
||||||
|
if (well->isMultiSegment()) {
|
||||||
|
m_is_multi_segment_ = true;
|
||||||
|
SegmentSetConstPtr segment_set = well->getSegmentSet(time_step);
|
||||||
|
m_number_of_segments_ = segment_set->numberSegment();
|
||||||
|
|
||||||
|
m_comp_pressure_drop_ = segment_set->compPressureDrop();
|
||||||
|
m_multiphase_model_ = segment_set->multiPhaseModel();
|
||||||
|
|
||||||
|
// m_number_of_perforations_ from wells
|
||||||
|
// m_well_index_ from wells
|
||||||
|
m_outlet_segment_.resize(m_number_of_segments_);
|
||||||
|
m_segment_length_.resize(m_number_of_segments_);
|
||||||
|
m_segment_internal_diameter_.resize(m_number_of_segments_);
|
||||||
|
m_segment_roughness_.resize(m_number_of_segments_);
|
||||||
|
m_segment_volume_.resize(m_number_of_segments_);
|
||||||
|
// what is the point to do this?
|
||||||
|
|
||||||
|
// we change the ID to location now for easier use later.
|
||||||
|
for (size_t i = 0; i < m_number_of_segments_; ++i) {
|
||||||
|
// now the segment for top segment is 0, then its outlet segment will be -1
|
||||||
|
// it is also the flag to indicate the top segment
|
||||||
|
m_outlet_segment_[i] = segment_set->numberToLocation((*segment_set)[i]->outletSegment());
|
||||||
|
m_segment_length_[i] = (*segment_set)[i]->length();
|
||||||
|
m_segment_depth_[i] = (*segment_set)[i]->depth();
|
||||||
|
m_segment_internal_diameter_[i] = (*segment_set)[i]->internalDiameter();
|
||||||
|
m_segment_roughness_[i] = (*segment_set)[i]->roughness();
|
||||||
|
m_segment_volume_[i] = (*segment_set)[i]->volume();
|
||||||
|
}
|
||||||
|
// update the completion related information
|
||||||
|
// find the location of the well in wells first
|
||||||
|
// through well names?
|
||||||
|
for (size_t i = 0; i < completion_set->size(); ++i) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// how to build the relation between segments and completions
|
||||||
|
// the completion should be in a global array (all the wells) or local scope (this well)?
|
||||||
|
// we handle with in the local scope first
|
||||||
|
// need to change the related segments to the new segment ID (location in the arrary)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// building a segment structure for the non-segmented well
|
||||||
|
// basically, for each well, only one segment, which means the top segment
|
||||||
|
// and all the completions will contribute to the top segment.
|
||||||
|
// only hydrostatic pressure drop calculation (H--) and homogenous multiphase
|
||||||
|
// flow model (HO) will be used.
|
||||||
|
// so each well will have four primary variables
|
||||||
|
// G_t, F_w, F_g, bhp
|
||||||
|
// This is NOT something we are totally sure about at the moment.
|
||||||
|
// The major point will be if the pressure difference between the
|
||||||
|
// location of bhp reference point is exactly same with the current
|
||||||
|
// way to compute the connection pressure difference.
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t WellMultiSegment::numberOfPerforations() const {
|
||||||
|
return m_number_of_perforations_;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t WellMultiSegment::numberOfSegment() const {
|
||||||
|
return m_number_of_segments_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<double>& WellMultiSegment::wellIndex() const {
|
||||||
|
return m_well_index_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<double>& WellMultiSegment::perfDepth() const {
|
||||||
|
return m_perf_depth_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<int>& WellMultiSegment::wellCell() const {
|
||||||
|
return m_well_cell_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<int>& WellMultiSegment::outletSegment() const {
|
||||||
|
return m_outlet_segment_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<double>& WellMultiSegment::segmentLength() const {
|
||||||
|
return m_segment_length_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<double>& WellMultiSegment::segmentDepth() const {
|
||||||
|
return m_segment_depth_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<double>& WellMultiSegment::segmentCrossArea() const {
|
||||||
|
return m_segment_cross_area_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<double>& WellMultiSegment::segmentRoughness() const {
|
||||||
|
return m_segment_roughness_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<double>& WellMultiSegment::segmentVolume() const {
|
||||||
|
return m_segment_volume_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<std::vector<int>>& WellMultiSegment::segmentPerforatioins() const {
|
||||||
|
return m_segment_perforations_;
|
||||||
|
}
|
||||||
|
}
|
119
opm/autodiff/WellMultiSegment.hpp
Normal file
119
opm/autodiff/WellMultiSegment.hpp
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2015 SINTEF ICT, Applied Mathematics.
|
||||||
|
|
||||||
|
This file is part of the Open Porous Media project (OPM).
|
||||||
|
|
||||||
|
OPM is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OPM is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef OPM_WELLMULTISEGMENT_HEADER_INCLUDED
|
||||||
|
#define OPM_WELLMULTISEGMENT_HEADER_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include <opm/core/wells.h>
|
||||||
|
#include <opm/core/well_controls.h>
|
||||||
|
#include <opm/core/simulator/WellState.hpp>
|
||||||
|
#include <opm/core/utility/ErrorMacros.hpp>
|
||||||
|
#include <opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.hpp>
|
||||||
|
#include <opm/parser/eclipse/EclipseState/Schedule/SegmentSet.hpp>
|
||||||
|
#include <opm/parser/eclipse/EclipseState/Schedule/Well.hpp>
|
||||||
|
#include <vector>
|
||||||
|
#include <cassert>
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
#include <map>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
namespace Opm
|
||||||
|
{
|
||||||
|
|
||||||
|
class WellMultiSegment
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
size_t numberOfPerforations() const;
|
||||||
|
size_t numberOfSegment() const;
|
||||||
|
|
||||||
|
const std::vector<double>& wellIndex() const;
|
||||||
|
const std::vector<double>& perfDepth() const;
|
||||||
|
const std::vector<int>& wellCell() const;
|
||||||
|
const std::vector<int>& outletSegment() const;
|
||||||
|
const std::vector<double>& segmentLength() const;
|
||||||
|
const std::vector<double>& segmentDepth() const;
|
||||||
|
const std::vector<double>& segmentCrossArea() const;
|
||||||
|
const std::vector<double>& segmentRoughness() const;
|
||||||
|
const std::vector<double>& segmentVolume() const;
|
||||||
|
const std::vector<std::vector<int>>& segmentPerforatioins() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// for the moment, we use the information from wells.
|
||||||
|
// TODO: remove the dependency on wells from opm-core.
|
||||||
|
void init(WellConstPtr well, size_t time_step, const Wells* wells);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// name of the well
|
||||||
|
std::string m_well_name;
|
||||||
|
// flag to indicate if this well is a
|
||||||
|
// multi-segmented well
|
||||||
|
bool m_is_multi_segment_;
|
||||||
|
// components of the pressure drop to be included
|
||||||
|
WellSegment::CompPresureDropEnum m_comp_pressure_drop_;
|
||||||
|
// multi-phase flow model
|
||||||
|
WellSegment::MultiPhaseModelEnum m_multiphase_model_;
|
||||||
|
// number of perforation for this well
|
||||||
|
size_t m_number_of_perforations_;
|
||||||
|
// number of segments for this well
|
||||||
|
size_t m_number_of_segments_;
|
||||||
|
// well index for each completion
|
||||||
|
std::vector<double> m_well_index_;
|
||||||
|
// depth for each completion
|
||||||
|
std::vector<double> m_perf_depth_;
|
||||||
|
// well cell for each completion
|
||||||
|
std::vector<int> m_well_cell_;
|
||||||
|
// how to organize the segment structure here?
|
||||||
|
// indicate the outlet segment for each segment
|
||||||
|
// maybe here we can use the location in the vector
|
||||||
|
// at the moment, we still use the ID number
|
||||||
|
// then a mapping from the ID number to the actual location will be required
|
||||||
|
std::vector<int> m_outlet_segment_;
|
||||||
|
std::map<int, int> m_number_to_location_;
|
||||||
|
// has not decided to use the absolute length from the well head
|
||||||
|
// or the length of this single segment
|
||||||
|
// using the absolute length first
|
||||||
|
std::vector<double> m_segment_length_;
|
||||||
|
// the depth of the segmnet node
|
||||||
|
std::vector<double> m_segment_depth_;
|
||||||
|
// the internal diameter of the segment
|
||||||
|
std::vector<double> m_segment_internal_diameter_;
|
||||||
|
// the roughness of the segment
|
||||||
|
std::vector<double> m_segment_roughness_;
|
||||||
|
// the cross area of the segment
|
||||||
|
std::vector<double> m_segment_cross_area_;
|
||||||
|
// the volume of the segment
|
||||||
|
std::vector<double> m_segment_volume_;
|
||||||
|
// the completions that is related to each segment
|
||||||
|
// the completions's ids are their location in the vector m_well_index_
|
||||||
|
// m_well_cell_
|
||||||
|
std::vector<std::vector<int>> m_segment_perforations_;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::shared_ptr<WellMultiSegment> WellMutliSegmentPtr;
|
||||||
|
typedef std::shared_ptr<const WellMultiSegment> WellMutliSegmentConstPtr;
|
||||||
|
|
||||||
|
} // namespace Opm
|
||||||
|
|
||||||
|
|
||||||
|
#endif // OPM_WELLMULTISEGMENT_HEADER_INCLUDE
|
70
opm/autodiff/WellStateMultiSegment.hpp
Normal file
70
opm/autodiff/WellStateMultiSegment.hpp
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2015 SINTEF ICT, Applied Mathematics.
|
||||||
|
|
||||||
|
This file is part of the Open Porous Media project (OPM).
|
||||||
|
|
||||||
|
OPM is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OPM is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef OPM_WELLSTATEMULTISEGMENT_HEADER_INCLUDED
|
||||||
|
#define OPM_WELLSTATEMULTISEGMENT_HEADER_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include <opm/core/wells.h>
|
||||||
|
#include <opm/core/well_controls.h>
|
||||||
|
#include <opm/core/simulator/WellState.hpp>
|
||||||
|
#include <opm/core/utility/ErrorMacros.hpp>
|
||||||
|
#include <vector>
|
||||||
|
#include <cassert>
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
#include <map>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
namespace Opm
|
||||||
|
{
|
||||||
|
|
||||||
|
/// The state of a set of multi-sgemnet wells
|
||||||
|
class WellStateMultiSegment
|
||||||
|
: public WellState
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// typedef std::array< int, 3 > mapentry_t;
|
||||||
|
// typedef std::map< std::string, mapentry_t > WellMapType;
|
||||||
|
|
||||||
|
/// Allocate and initialize if wells is non-null. Also tries
|
||||||
|
/// to give useful initial values to the bhp(), wellRates()
|
||||||
|
/// and perfPhaseRates() fields, depending on controls
|
||||||
|
template <class State, class PrevState>
|
||||||
|
void init(const Wells* wells, const State& state, const PrevState& prevState)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// pressure for the segment nodes
|
||||||
|
// pressure for the top segment nodes are the bhp
|
||||||
|
std::vector<double> segpressure_;
|
||||||
|
// phase rates for the segments
|
||||||
|
std::vector<double> segphaserates_;
|
||||||
|
// phase rates for the completions
|
||||||
|
std::vector<double> perfphaserates_;
|
||||||
|
std::vector<int> current_controls_;
|
||||||
|
// WellMapType wellMap_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Opm
|
||||||
|
|
||||||
|
|
||||||
|
#endif // OPM_WELLSTATEMULTISEGMENT_HEADER_INCLUDE
|
Loading…
Reference in New Issue
Block a user