Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists_files.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ list (APPEND MAIN_SOURCE_FILES
opm/simulators/wells/BlackoilWellModelWBP.cpp
opm/simulators/wells/ConnFiltrateData.cpp
opm/simulators/wells/GuideRateHandler.cpp
opm/simulators/wells/ConnFractureData.cpp
opm/simulators/wells/FractionCalculator.cpp
opm/simulators/wells/GasLiftCommon.cpp
opm/simulators/wells/GasLiftGroupInfo.cpp
Expand Down
10 changes: 9 additions & 1 deletion opm/simulators/wells/ConnFiltrateData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ void ConnFiltrateData<Scalar>::resize(std::size_t num_perf)
this->poro.resize(num_perf);
this->radius.resize(num_perf);
this->area_of_flow.resize(num_perf);
// Share of the connection flow entering the matrix: 1 unless a
// fracture model registers a competing fracture contribution.
this->flow_factor.resize(num_perf, Scalar{1});
this->fracture_rate.resize(num_perf);
}

template<class Scalar>
Expand All @@ -52,6 +56,8 @@ ConnFiltrateData<Scalar>::serializationTestObject()
result.poro = {0.3};
result.radius = {0.05};
result.area_of_flow = {0.7};
result.flow_factor = {0.1};
result.fracture_rate = {7.};
return result;
}

Expand All @@ -65,7 +71,9 @@ bool ConnFiltrateData<Scalar>::operator==(const ConnFiltrateData& rhs) const
this->perm == rhs.perm &&
this->poro == rhs.poro &&
this->radius == rhs.radius &&
this->area_of_flow == rhs.area_of_flow;
this->area_of_flow == rhs.area_of_flow &&
this->flow_factor == rhs.flow_factor &&
this->fracture_rate == rhs.fracture_rate;
}

template struct ConnFiltrateData<double>;
Expand Down
6 changes: 5 additions & 1 deletion opm/simulators/wells/ConnFiltrateData.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ struct ConnFiltrateData {
serializer(poro);
serializer(radius);
serializer(area_of_flow);
serializer(flow_factor);
serializer(fracture_rate);
}

static ConnFiltrateData serializationTestObject();
Expand All @@ -54,8 +56,10 @@ struct ConnFiltrateData {
std::vector<Scalar> poro;
std::vector<Scalar> radius;
std::vector<Scalar> area_of_flow;
std::vector<Scalar> flow_factor;
std::vector<Scalar> fracture_rate;
};

}
} // namespace Opm

#endif // OPM_CONNFILTRATEDATA_HPP
92 changes: 92 additions & 0 deletions opm/simulators/wells/ConnFractureData.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
Copyright 2023 Equinor ASA.

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/>.
*/

#if HAVE_CONFIG_H
#include "config.h"
#endif // HAVE_CONFIG_H

#include <opm/simulators/wells/ConnFractureData.hpp>

namespace Opm {

template<class Scalar>
void ConnFractureData<Scalar>::resize(std::size_t num_perf)
{
this->area.resize(num_perf);
this->flux.resize(num_perf);
this->height.resize(num_perf);
this->length.resize(num_perf);
this->WI.resize(num_perf);
this->volume.resize(num_perf);
this->filter_volume.resize(num_perf);
this->avg_width.resize(num_perf);
this->avg_filter_width.resize(num_perf);
this->inj_pressure.resize(num_perf);
this->inj_bhp.resize(num_perf);
this->inj_wellrate.resize(num_perf);
this->water_rate.resize(num_perf);
}

template<class Scalar>
ConnFractureData<Scalar>
ConnFractureData<Scalar>::serializationTestObject()
{
ConnFractureData result;
result.area = {8.};
result.flux = {100.};
result.height = {0.5};
result.length = {0.05};
result.WI = {10.0};
result.volume = {4.0};
result.filter_volume = {0.4};
result.avg_width = {0.5};
result.avg_filter_width = {0.05};
result.inj_pressure = {250.0};
result.inj_bhp = {200.0};
result.inj_wellrate = {150.0};
result.water_rate = {123.4};
return result;
}

template<class Scalar>
bool ConnFractureData<Scalar>::operator==(const ConnFractureData& rhs) const
{
return (this->area == rhs.area)
&& (this->flux == rhs.flux)
&& (this->height == rhs.height)
&& (this->length == rhs.length)
&& (this->WI == rhs.WI)
&& (this->volume == rhs.volume)
&& (this->filter_volume == rhs.filter_volume)
&& (this->avg_width == rhs.avg_width)
&& (this->avg_filter_width == rhs.avg_filter_width)
&& (this->inj_pressure == rhs.inj_pressure)
&& (this->inj_bhp == rhs.inj_bhp)
&& (this->inj_wellrate == rhs.inj_wellrate)
&& (this->water_rate == rhs.water_rate)
;
}

template struct ConnFractureData<double>;

#if FLOW_INSTANTIATE_FLOAT
template struct ConnFractureData<float>;
#endif

}
70 changes: 70 additions & 0 deletions opm/simulators/wells/ConnFractureData.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
Copyright 2023 Equinor ASA.

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_CONNFRACTUREDATA_HPP
#define OPM_CONNFRACTUREDATA_HPP

#include <vector>

namespace Opm {

template<class Scalar>
struct ConnFractureData {

void resize(std::size_t num_perf);

template<class Serializer>
void serializeOp(Serializer& serializer) {
serializer(area);
serializer(flux);
serializer(height);
serializer(length);
serializer(WI);
serializer(volume);
serializer(filter_volume);
serializer(avg_width);
serializer(avg_filter_width);
serializer(inj_pressure);
serializer(inj_bhp);
serializer(inj_wellrate);
serializer(water_rate);
}

static ConnFractureData serializationTestObject();

bool operator==(const ConnFractureData& rhs) const;

std::vector<Scalar> area;
std::vector<Scalar> flux;
std::vector<Scalar> height;
std::vector<Scalar> length;
std::vector<Scalar> WI;
std::vector<Scalar> volume;
std::vector<Scalar> filter_volume;
std::vector<Scalar> avg_width;
std::vector<Scalar> avg_filter_width;
std::vector<Scalar> inj_pressure;
std::vector<Scalar> inj_bhp;
std::vector<Scalar> inj_wellrate;
std::vector<Scalar> water_rate;
};

}

#endif // OPM_CONNFRACTUREDATA_HPP
6 changes: 6 additions & 0 deletions opm/simulators/wells/PerfData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ void PerfData<Scalar>::prepareInjectorContainers()
this->skin_pressure.resize(num_perf);
this->water_velocity.resize(num_perf);
this->filtrate_data.resize(num_perf);
// fracture_data is deliberately not sized here: a fracture model calls
// resize() when it has something to store, so a run without one pays
// nothing. Everything reading it must tolerate the empty state.
}

template<class Scalar>
Expand Down Expand Up @@ -99,6 +102,7 @@ PerfData<Scalar> PerfData<Scalar>::serializationTestObject()
result.skin_pressure = {27.0, 28.0};
result.water_velocity = {29.0, 30.0};
result.filtrate_data = ConnFiltrateData<Scalar>::serializationTestObject();
result.fracture_data = ConnFractureData<Scalar>::serializationTestObject();
result.connFracStatistics.assign(3, ConnFracStatistics<Scalar>::serializationTestObject());
result.gas_mass_rates = {31.0};
result.wat_mass_rates = {32.0};
Expand Down Expand Up @@ -145,6 +149,7 @@ bool PerfData<Scalar>::try_assign(const PerfData& other)
this->skin_pressure = other.skin_pressure;
this->water_velocity = other.water_velocity;
this->filtrate_data = other.filtrate_data;
this->fracture_data = other.fracture_data;
this->connFracStatistics = other.connFracStatistics;
this->gas_mass_rates = other.gas_mass_rates;
this->wat_mass_rates = other.wat_mass_rates;
Expand Down Expand Up @@ -180,6 +185,7 @@ bool PerfData<Scalar>::operator==(const PerfData& rhs) const
&& (this->skin_pressure == rhs.skin_pressure)
&& (this->water_velocity == rhs.water_velocity)
&& (this->filtrate_data == rhs.filtrate_data)
&& (this->fracture_data == rhs.fracture_data)
&& (this->connFracStatistics == rhs.connFracStatistics)
&& (this->gas_mass_rates == rhs.gas_mass_rates)
&& (this->wat_mass_rates == rhs.wat_mass_rates)
Expand Down
3 changes: 3 additions & 0 deletions opm/simulators/wells/PerfData.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#define OPM_PERFDATA_HEADER_INCLUDED

#include <opm/simulators/wells/ConnFiltrateData.hpp>
#include <opm/simulators/wells/ConnFractureData.hpp>
#include <opm/simulators/wells/ConnFracStatistics.hpp>

#include <cstddef>
Expand Down Expand Up @@ -80,6 +81,7 @@ class PerfData
serializer(skin_pressure);
serializer(water_velocity);
serializer(filtrate_data);
serializer(fracture_data);
serializer(connFracStatistics);
serializer(gas_mass_rates);
serializer(wat_mass_rates);
Expand Down Expand Up @@ -123,6 +125,7 @@ class PerfData
std::vector<Scalar> water_velocity{};

ConnFiltrateData<Scalar> filtrate_data{};
ConnFractureData<Scalar> fracture_data{};
std::vector<ConnFracStatistics<Scalar>> connFracStatistics{};
};

Expand Down
1 change: 1 addition & 0 deletions opm/simulators/wells/SingleWellState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,7 @@ bool SingleWellState<Scalar, IndexTraits>::operator==(const SingleWellState& rhs
this->surface_rates == rhs.surface_rates &&
this->reservoir_rates == rhs.reservoir_rates &&
this->prev_surface_rates == rhs.prev_surface_rates &&
this->frac_rate == rhs.frac_rate &&
this->perf_data == rhs.perf_data &&
this->filtrate_conc == rhs.filtrate_conc &&
this->trivial_group_target == rhs.trivial_group_target &&
Expand Down
2 changes: 2 additions & 0 deletions opm/simulators/wells/SingleWellState.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ class SingleWellState {
serializer(surface_rates);
serializer(reservoir_rates);
serializer(prev_surface_rates);
serializer(frac_rate);
serializer(trivial_group_target);
serializer(segments);
serializer(events);
Expand Down Expand Up @@ -153,6 +154,7 @@ class SingleWellState {
std::vector<Scalar> surface_rates;
std::vector<Scalar> reservoir_rates;
std::vector<Scalar> prev_surface_rates;
Scalar frac_rate{0.0};
PerfData<Scalar> perf_data;
bool trivial_group_target;
std::optional<GroupTarget> group_target;
Expand Down
42 changes: 42 additions & 0 deletions opm/simulators/wells/WellState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,7 @@ report(const int* globalCellIdxMap,
const auto& well_potentials = ws.well_potentials;
const auto& wpi = ws.productivity_index;
const auto& wv = ws.surface_rates;
const auto frac_rate = ws.frac_rate;
const auto& wname = this->name(well_index);

auto dummyWell = data::Well{};
Expand All @@ -565,6 +566,7 @@ report(const int* globalCellIdxMap,
if (pu.phaseIsActive(waterPhaseIdx)) {
const int phase_pos = pu.canonicalToActivePhaseIdx(waterPhaseIdx);
well.rates.set(rt::wat, wv[phase_pos]);
well.rates.set(rt::wat_frac, frac_rate);
well.rates.set(rt::reservoir_water, reservoir_rates[phase_pos]);
well.rates.set(rt::productivity_index_water, wpi[phase_pos]);
well.rates.set(rt::well_potential_water, well_potentials[phase_pos]);
Expand Down Expand Up @@ -702,6 +704,7 @@ reportConnections(std::vector<data::Connection>& connections,

if (! ws.producer) {
this->reportConnectionFilterCake(well_index, connections);
this->reportConnectionFracture(well_index, connections);
}

if (! perf_data.connFracStatistics.empty()) {
Expand Down Expand Up @@ -1318,6 +1321,45 @@ reportConnectionFilterCake(const std::size_t well_index,
filtrate.perm = filtrate_data.perm[i];
filtrate.radius = filtrate_data.radius[i];
filtrate.area_of_flow = filtrate_data.area_of_flow[i];
filtrate.flow_factor = filtrate_data.flow_factor[i];
filtrate.fracture_rate = filtrate_data.fracture_rate[i];
}
}


template<typename Scalar, typename IndexTraits>
void WellState<Scalar, IndexTraits>::
reportConnectionFracture(const std::size_t well_index,
std::vector<data::Connection>& connections) const
{
const auto& perf_data = this->well(well_index).perf_data;
const auto num_perf_well = perf_data.size();

const auto& data = perf_data.fracture_data;
if (data.area.size() != num_perf_well) {
// No fracture model has claimed this well, so there is nothing to
// report and the containers were never sized.
return;
}

for (auto i = 0*num_perf_well; i < num_perf_well; ++i) {
auto& fracture = connections[i].fracture;

fracture.area = data.area[i];
fracture.flux = data.flux[i];
fracture.height = data.height[i];
fracture.length = data.length[i];
fracture.WI = data.WI[i];
fracture.volume = data.volume[i];
fracture.filter_volume = data.filter_volume[i];
fracture.avg_width = data.avg_width[i];
fracture.avg_filter_width = data.avg_filter_width[i];
fracture.inj_pressure = data.inj_pressure[i];
fracture.inj_bhp = data.inj_bhp[i];
fracture.inj_wellrate = data.inj_wellrate[i];

connections[i].rates.set(data::Rates::opt::wat_frac,
data.water_rate[i]);
}
}

Expand Down
3 changes: 3 additions & 0 deletions opm/simulators/wells/WellState.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,9 @@ class WellState
void reportConnectionFilterCake(const std::size_t well_index,
std::vector<data::Connection>& connections) const;

void reportConnectionFracture(const std::size_t well_index,
std::vector<data::Connection>& connections) const;

void reportFractureStatistics(const std::vector<ConnFracStatistics<Scalar>>& stats,
std::vector<data::Connection>& connections) const;
};
Expand Down