mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Merge from upstream.
This commit is contained in:
commit
fede5f4c5f
@ -211,8 +211,7 @@ namespace Opm
|
|||||||
|
|
||||||
|
|
||||||
void writeVtkDataGeneralGrid(const UnstructuredGrid* grid,
|
void writeVtkDataGeneralGrid(const UnstructuredGrid* grid,
|
||||||
const std::vector<double>& pressure,
|
const DataMap& data,
|
||||||
const std::vector<double>& saturation,
|
|
||||||
std::ostream& os)
|
std::ostream& os)
|
||||||
{
|
{
|
||||||
if (grid->dimensions != 3) {
|
if (grid->dimensions != 3) {
|
||||||
@ -350,37 +349,32 @@ namespace Opm
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
pm.clear();
|
pm.clear();
|
||||||
pm["Scalars"] = "saturation";
|
if (data.find("saturation") != data.end()) {
|
||||||
|
pm["Scalars"] = "saturation";
|
||||||
|
} else if (data.find("pressure") != data.end()) {
|
||||||
|
pm["Scalars"] = "pressure";
|
||||||
|
}
|
||||||
Tag celldatatag("CellData", pm, os);
|
Tag celldatatag("CellData", pm, os);
|
||||||
pm.clear();
|
pm.clear();
|
||||||
pm["type"] = "Int32";
|
pm["type"] = "Int32";
|
||||||
pm["NumberOfComponents"] = "1";
|
pm["NumberOfComponents"] = "1";
|
||||||
pm["format"] = "ascii";
|
pm["format"] = "ascii";
|
||||||
pm["type"] = "Float64";
|
pm["type"] = "Float64";
|
||||||
{
|
for (DataMap::const_iterator dit = data.begin(); dit != data.end(); ++dit) {
|
||||||
pm["Name"] = "pressure";
|
pm["Name"] = dit->first;
|
||||||
|
const std::vector<double>& field = *(dit->second);
|
||||||
|
// We always print only the first data item for every
|
||||||
|
// cell, using 'stride'.
|
||||||
|
// This is a hack to get water saturation nicely.
|
||||||
|
// \TODO: Extend to properly printing vector data.
|
||||||
|
const int stride = field.size()/grid->number_of_cells;
|
||||||
Tag ptag("DataArray", pm, os);
|
Tag ptag("DataArray", pm, os);
|
||||||
const int num_per_line = 5;
|
const int num_per_line = 5;
|
||||||
for (int c = 0; c < num_cells; ++c) {
|
for (int c = 0; c < num_cells; ++c) {
|
||||||
if (c % num_per_line == 0) {
|
if (c % num_per_line == 0) {
|
||||||
Tag::indent(os);
|
Tag::indent(os);
|
||||||
}
|
}
|
||||||
os << pressure[c] << ' ';
|
os << field[stride*c] << ' ';
|
||||||
if (c % num_per_line == num_per_line - 1
|
|
||||||
|| c == num_cells - 1) {
|
|
||||||
os << '\n';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{
|
|
||||||
pm["Name"] = "saturation";
|
|
||||||
Tag ptag("DataArray", pm, os);
|
|
||||||
const int num_per_line = 5;
|
|
||||||
for (int c = 0; c < num_cells; ++c) {
|
|
||||||
if (c % num_per_line == 0) {
|
|
||||||
Tag::indent(os);
|
|
||||||
}
|
|
||||||
os << saturation[2*c] << ' ';
|
|
||||||
if (c % num_per_line == num_per_line - 1
|
if (c % num_per_line == num_per_line - 1
|
||||||
|| c == num_cells - 1) {
|
|| c == num_cells - 1) {
|
||||||
os << '\n';
|
os << '\n';
|
||||||
|
@ -106,6 +106,12 @@ namespace Opm
|
|||||||
ug_ = create_cart_grid_3d(nx, ny, nz);
|
ug_ = create_cart_grid_3d(nx, ny, nz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Grid(int nx, int ny, int nz,
|
||||||
|
double dx, double dy, double dz)
|
||||||
|
{
|
||||||
|
ug_ = create_hexa_grid_3d(nx, ny, nz, dx, dy, dz);
|
||||||
|
}
|
||||||
|
|
||||||
~Grid()
|
~Grid()
|
||||||
{
|
{
|
||||||
free_grid(ug_);
|
free_grid(ug_);
|
||||||
@ -204,9 +210,10 @@ namespace Opm
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef std::map<std::string, const std::vector<double>*> DataMap;
|
||||||
|
|
||||||
void writeVtkDataGeneralGrid(const UnstructuredGrid* grid,
|
void writeVtkDataGeneralGrid(const UnstructuredGrid* grid,
|
||||||
const std::vector<double>& pressure,
|
const DataMap& data,
|
||||||
const std::vector<double>& saturation,
|
|
||||||
std::ostream& os);
|
std::ostream& os);
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include <opm/core/pressure/tpfa/trans_tpfa.h>
|
#include <opm/core/pressure/tpfa/trans_tpfa.h>
|
||||||
|
|
||||||
#include <opm/core/utility/cart_grid.h>
|
#include <opm/core/utility/cart_grid.h>
|
||||||
|
#include <opm/core/utility/linearInterpolation.hpp>
|
||||||
#include <opm/core/utility/ErrorMacros.hpp>
|
#include <opm/core/utility/ErrorMacros.hpp>
|
||||||
#include <opm/core/utility/StopWatch.hpp>
|
#include <opm/core/utility/StopWatch.hpp>
|
||||||
#include <opm/core/utility/Units.hpp>
|
#include <opm/core/utility/Units.hpp>
|
||||||
@ -60,13 +61,64 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class AdHocProps : public Opm::IncompPropertiesBasic
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AdHocProps(const Opm::parameter::ParameterGroup& param, int dim, int num_cells)
|
||||||
|
: Opm::IncompPropertiesBasic(param, dim, num_cells)
|
||||||
|
{
|
||||||
|
ASSERT(numPhases() == 2);
|
||||||
|
sw_.resize(3);
|
||||||
|
sw_[0] = 0.2;
|
||||||
|
sw_[1] = 0.7;
|
||||||
|
sw_[2] = 1.0;
|
||||||
|
krw_.resize(3);
|
||||||
|
krw_[0] = 0.0;
|
||||||
|
krw_[1] = 0.7;
|
||||||
|
krw_[2] = 1.0;
|
||||||
|
so_.resize(2);
|
||||||
|
so_[0] = 0.3;
|
||||||
|
so_[1] = 0.8;
|
||||||
|
kro_.resize(2);
|
||||||
|
kro_[0] = 0.0;
|
||||||
|
kro_[1] = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void relperm(const int n,
|
||||||
|
const double* s,
|
||||||
|
const int* /*cells*/,
|
||||||
|
double* kr,
|
||||||
|
double* dkrds) const
|
||||||
|
{
|
||||||
|
ASSERT(dkrds == 0);
|
||||||
|
for (int i = 0; i < n; ++i) {
|
||||||
|
kr[2*i] = krw(s[2*i]);
|
||||||
|
kr[2*i+1] = kro(s[2*i+1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
double krw(double s) const
|
||||||
|
{
|
||||||
|
return Opm::linearInterpolation(sw_, krw_, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
double kro(double s) const
|
||||||
|
{
|
||||||
|
return Opm::linearInterpolation(so_, kro_, s);
|
||||||
|
}
|
||||||
|
std::vector<double> sw_;
|
||||||
|
std::vector<double> krw_;
|
||||||
|
std::vector<double> so_;
|
||||||
|
std::vector<double> kro_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class ReservoirState
|
class ReservoirState
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ReservoirState(const UnstructuredGrid* g, const int num_phases = 2)
|
ReservoirState(const UnstructuredGrid* g, const int num_phases = 2, const double init_sat = 0.0)
|
||||||
: press_ (g->number_of_cells, 0.0),
|
: press_ (g->number_of_cells, 0.0),
|
||||||
fpress_(g->number_of_faces, 0.0),
|
fpress_(g->number_of_faces, 0.0),
|
||||||
flux_ (g->number_of_faces, 0.0),
|
flux_ (g->number_of_faces, 0.0),
|
||||||
@ -75,7 +127,8 @@ public:
|
|||||||
cmax_(g->number_of_cells, 0.0)
|
cmax_(g->number_of_cells, 0.0)
|
||||||
{
|
{
|
||||||
for (int cell = 0; cell < g->number_of_cells; ++cell) {
|
for (int cell = 0; cell < g->number_of_cells; ++cell) {
|
||||||
sat_[num_phases*cell + num_phases - 1] = 1.0;
|
sat_[num_phases*cell] = init_sat;
|
||||||
|
sat_[num_phases*cell + num_phases - 1] = 1.0 - init_sat;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,7 +162,11 @@ private:
|
|||||||
|
|
||||||
double polymerInflowAtTime(double time)
|
double polymerInflowAtTime(double time)
|
||||||
{
|
{
|
||||||
return time >= 4.0*Opm::unit::day ? 1.0 : 0.0;
|
if (time >= 300.0*Opm::unit::day && time < 800.0*Opm::unit::day) {
|
||||||
|
return 5.0;
|
||||||
|
} else {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -121,13 +178,30 @@ void outputState(const UnstructuredGrid* grid,
|
|||||||
const int step,
|
const int step,
|
||||||
const std::string& output_dir)
|
const std::string& output_dir)
|
||||||
{
|
{
|
||||||
|
// Write data in VTK format.
|
||||||
std::ostringstream vtkfilename;
|
std::ostringstream vtkfilename;
|
||||||
vtkfilename << output_dir << "/output-" << std::setw(3) << std::setfill('0') << step << ".vtu";
|
vtkfilename << output_dir << "/output-" << std::setw(3) << std::setfill('0') << step << ".vtu";
|
||||||
std::ofstream vtkfile(vtkfilename.str().c_str());
|
std::ofstream vtkfile(vtkfilename.str().c_str());
|
||||||
if (!vtkfile) {
|
if (!vtkfile) {
|
||||||
THROW("Failed to open " << vtkfilename.str());
|
THROW("Failed to open " << vtkfilename.str());
|
||||||
}
|
}
|
||||||
Opm::writeVtkDataGeneralGrid(grid, state.pressure(), state.saturation(), vtkfile);
|
Opm::DataMap dm;
|
||||||
|
dm["saturation"] = &state.saturation();
|
||||||
|
dm["pressure"] = &state.pressure();
|
||||||
|
dm["concentration"] = &state.concentration();
|
||||||
|
Opm::writeVtkDataGeneralGrid(grid, dm, vtkfile);
|
||||||
|
|
||||||
|
// Write data (not grid) in Matlab format
|
||||||
|
for (Opm::DataMap::const_iterator it = dm.begin(); it != dm.end(); ++it) {
|
||||||
|
std::ostringstream fname;
|
||||||
|
fname << output_dir << "/" << it->first << "-" << std::setw(3) << std::setfill('0') << step << ".dat";
|
||||||
|
std::ofstream file(fname.str().c_str());
|
||||||
|
if (!file) {
|
||||||
|
THROW("Failed to open " << fname.str());
|
||||||
|
}
|
||||||
|
const std::vector<double>& d = *(it->second);
|
||||||
|
std::copy(d.begin(), d.end(), std::ostream_iterator<double>(file, "\n"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -176,23 +250,34 @@ main(int argc, char** argv)
|
|||||||
const int nx = param.getDefault("nx", 100);
|
const int nx = param.getDefault("nx", 100);
|
||||||
const int ny = param.getDefault("ny", 100);
|
const int ny = param.getDefault("ny", 100);
|
||||||
const int nz = param.getDefault("nz", 1);
|
const int nz = param.getDefault("nz", 1);
|
||||||
grid.reset(new Opm::Grid(nx, ny, nz));
|
const int dx = param.getDefault("dx", 1.0);
|
||||||
|
const int dy = param.getDefault("dy", 1.0);
|
||||||
|
const int dz = param.getDefault("dz", 1.0);
|
||||||
|
grid.reset(new Opm::Grid(nx, ny, nz, dx, dy, dz));
|
||||||
// Rock and fluid init.
|
// Rock and fluid init.
|
||||||
props.reset(new Opm::IncompPropertiesBasic(param, grid->c_grid()->dimensions, grid->c_grid()->number_of_cells));
|
// props.reset(new Opm::IncompPropertiesBasic(param, grid->c_grid()->dimensions, grid->c_grid()->number_of_cells));
|
||||||
polydata.c_max_limit = param.getDefault("c_max_limit", 1.0);
|
props.reset(new AdHocProps(param, grid->c_grid()->dimensions, grid->c_grid()->number_of_cells));
|
||||||
|
// Setting polydata defaults to mimic a simple example case.
|
||||||
|
polydata.c_max_limit = param.getDefault("c_max_limit", 5.0);
|
||||||
polydata.omega = param.getDefault("omega", 1.0);
|
polydata.omega = param.getDefault("omega", 1.0);
|
||||||
polydata.rhor = param.getDefault("rock_density", 1000.0);
|
polydata.rhor = param.getDefault("rock_density", 1000.0);
|
||||||
polydata.dps = param.getDefault("dead_pore_space", 0.15);
|
polydata.dps = param.getDefault("dead_pore_space", 0.15);
|
||||||
polydata.c_vals_visc.resize(2);
|
polydata.c_vals_visc.resize(2);
|
||||||
polydata.c_vals_visc[0] = 0.0;
|
polydata.c_vals_visc[0] = 0.0;
|
||||||
polydata.c_vals_visc[0] = polydata.c_max_limit;
|
polydata.c_vals_visc[1] = 7.0;
|
||||||
polydata.visc_mult_vals.resize(2);
|
polydata.visc_mult_vals.resize(2);
|
||||||
polydata.visc_mult_vals[0] = 1.0;
|
polydata.visc_mult_vals[0] = 1.0;
|
||||||
polydata.visc_mult_vals[1] = param.getDefault("c_max_viscmult", 30.0);
|
// polydata.visc_mult_vals[1] = param.getDefault("c_max_viscmult", 30.0);
|
||||||
polydata.c_vals_ads = polydata.c_vals_visc;
|
polydata.visc_mult_vals[1] = 20.0;
|
||||||
polydata.ads_vals.resize(2);
|
polydata.c_vals_ads.resize(3);
|
||||||
polydata.ads_vals[0] = 1.0;
|
polydata.c_vals_ads[0] = 0.0;
|
||||||
polydata.ads_vals[1] = param.getDefault("c_max_ads", 0.0025);
|
polydata.c_vals_ads[1] = 2.0;
|
||||||
|
polydata.c_vals_ads[2] = 8.0;
|
||||||
|
polydata.ads_vals.resize(3);
|
||||||
|
polydata.ads_vals[0] = 0.0;
|
||||||
|
// polydata.ads_vals[1] = param.getDefault("c_max_ads", 0.0025);
|
||||||
|
polydata.ads_vals[1] = 0.0015;
|
||||||
|
polydata.ads_vals[2] = 0.0025;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extra rock init.
|
// Extra rock init.
|
||||||
@ -205,11 +290,15 @@ main(int argc, char** argv)
|
|||||||
|
|
||||||
// State-related and source-related variables init.
|
// State-related and source-related variables init.
|
||||||
std::vector<double> totmob;
|
std::vector<double> totmob;
|
||||||
ReservoirState state(grid->c_grid(), props->numPhases());
|
double init_sat = param.getDefault("init_sat", 0.0);
|
||||||
|
ReservoirState state(grid->c_grid(), props->numPhases(), init_sat);
|
||||||
// We need a separate reorder_sat, because the reorder
|
// We need a separate reorder_sat, because the reorder
|
||||||
// code expects a scalar sw, not both sw and so.
|
// code expects a scalar sw, not both sw and so.
|
||||||
std::vector<double> reorder_sat(grid->c_grid()->number_of_cells);
|
std::vector<double> reorder_sat(grid->c_grid()->number_of_cells);
|
||||||
double flow_per_sec = 0.1*tot_porevol/Opm::unit::day;
|
double flow_per_sec = 0.1*tot_porevol/Opm::unit::day;
|
||||||
|
if (param.has("injection_rate_per_day")) {
|
||||||
|
flow_per_sec = param.get<double>("injection_rate_per_day")/Opm::unit::day;
|
||||||
|
}
|
||||||
std::vector<double> src (grid->c_grid()->number_of_cells, 0.0);
|
std::vector<double> src (grid->c_grid()->number_of_cells, 0.0);
|
||||||
src[0] = flow_per_sec;
|
src[0] = flow_per_sec;
|
||||||
src[grid->c_grid()->number_of_cells - 1] = -flow_per_sec;
|
src[grid->c_grid()->number_of_cells - 1] = -flow_per_sec;
|
||||||
|
@ -43,15 +43,13 @@ struct ParametersCRes
|
|||||||
double porosity;
|
double porosity;
|
||||||
PolymerSolverData* psdata;
|
PolymerSolverData* psdata;
|
||||||
int cell;
|
int cell;
|
||||||
NonlinearSolverCtrl* ctrl;
|
|
||||||
double s;
|
double s;
|
||||||
const PolymerData* polydata;
|
const PolymerData* polydata;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static struct ParametersSRes get_parameters_s(struct PolymerSolverData *d, int cell);
|
static struct ParametersSRes get_parameters_s(struct PolymerSolverData *d, int cell);
|
||||||
static struct ParametersCRes get_parameters_c(struct PolymerSolverData *d, int cell,
|
static struct ParametersCRes get_parameters_c(struct PolymerSolverData *d, int cell);
|
||||||
NonlinearSolverCtrl* ctrl);
|
|
||||||
static double residual_s(double s, void *data);
|
static double residual_s(double s, void *data);
|
||||||
static double residual_c(double c, void *data);
|
static double residual_c(double c, void *data);
|
||||||
static double fluxfun_props(double s,
|
static double fluxfun_props(double s,
|
||||||
@ -124,12 +122,21 @@ init_solverdata(struct UnstructuredGrid *grid,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Solver for single-cell bvp calls root-finder in nlsolvers.c */
|
/* Solver for single-cell bvp calls root-finder in nlsolvers.c */
|
||||||
void polymer_solvecell(void *data, struct NonlinearSolverCtrl *ctrl, int cell)
|
void polymer_solvecell(void *data, int cell)
|
||||||
{
|
{
|
||||||
struct PolymerSolverData *d = (struct PolymerSolverData*) data;
|
struct PolymerSolverData *d = (struct PolymerSolverData*) data;
|
||||||
struct ParametersCRes prm = get_parameters_c(d, cell, ctrl);
|
|
||||||
|
|
||||||
d->concentration[cell] = find_zero(residual_c, &prm, ctrl);
|
struct NonlinearSolverCtrl ctrl;
|
||||||
|
ctrl.maxiterations = 20;
|
||||||
|
ctrl.nltolerance = 1e-9;
|
||||||
|
ctrl.method = NonlinearSolverCtrl::REGULAFALSI;
|
||||||
|
ctrl.initialguess = 0.3*d->polydata->c_max_limit;
|
||||||
|
ctrl.min_bracket = 0.0;
|
||||||
|
ctrl.max_bracket = d->polydata->c_max_limit;
|
||||||
|
|
||||||
|
struct ParametersCRes prm = get_parameters_c(d, cell);
|
||||||
|
|
||||||
|
d->concentration[cell] = find_zero(residual_c, &prm, &ctrl);
|
||||||
d->cmax[cell] = std::max(d->cmax[cell], d->concentration[cell]);
|
d->cmax[cell] = std::max(d->cmax[cell], d->concentration[cell]);
|
||||||
d->saturation[cell] = prm.s;
|
d->saturation[cell] = prm.s;
|
||||||
d->fractionalflow[cell] = fluxfun_props(d->saturation[cell], d->concentration[cell], cell, d->props, d->polydata);
|
d->fractionalflow[cell] = fluxfun_props(d->saturation[cell], d->concentration[cell], cell, d->props, d->polydata);
|
||||||
@ -160,7 +167,14 @@ residual_c(double c, void *data)
|
|||||||
int cell = p->cell;
|
int cell = p->cell;
|
||||||
struct ParametersSRes prm_s = get_parameters_s(p->psdata, cell);
|
struct ParametersSRes prm_s = get_parameters_s(p->psdata, cell);
|
||||||
prm_s.c = c;
|
prm_s.c = c;
|
||||||
double s = find_zero(residual_s, &prm_s, p->ctrl);
|
struct NonlinearSolverCtrl ctrl;
|
||||||
|
ctrl.maxiterations = 20;
|
||||||
|
ctrl.nltolerance = 1e-9;
|
||||||
|
ctrl.method = NonlinearSolverCtrl::REGULAFALSI;
|
||||||
|
ctrl.initialguess = 0.5;
|
||||||
|
ctrl.min_bracket = 0.2; // TODO: Make this a proper s_min value.
|
||||||
|
ctrl.max_bracket = 1.0;
|
||||||
|
double s = find_zero(residual_s, &prm_s, &ctrl);
|
||||||
p->s = s;
|
p->s = s;
|
||||||
double ff = fluxfun_props(s, c, p->cell, prm_s.props, p->polydata);
|
double ff = fluxfun_props(s, c, p->cell, prm_s.props, p->polydata);
|
||||||
double mc = compute_mc(c, prm_s.props, p->polydata);
|
double mc = compute_mc(c, prm_s.props, p->polydata);
|
||||||
@ -176,7 +190,7 @@ residual_c(double c, void *data)
|
|||||||
+ rhor*((1.0 - porosity)/porosity)*(ads - ads0)
|
+ rhor*((1.0 - porosity)/porosity)*(ads - ads0)
|
||||||
+ p->dtpv*(p->outflux*ff*mc + p->influx_polymer);
|
+ p->dtpv*(p->outflux*ff*mc + p->influx_polymer);
|
||||||
#ifdef EXTRA_DEBUG_OUTPUT
|
#ifdef EXTRA_DEBUG_OUTPUT
|
||||||
std::cout << "res(c) = " << res << std::endl;
|
std::cout << "c = " << c << " s = " << s << " c-residual = " << res << std::endl;
|
||||||
#endif
|
#endif
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -226,7 +240,7 @@ get_parameters_s(struct PolymerSolverData *d, int cell)
|
|||||||
|
|
||||||
|
|
||||||
static struct ParametersCRes
|
static struct ParametersCRes
|
||||||
get_parameters_c(struct PolymerSolverData *d, int cell, NonlinearSolverCtrl* ctrl)
|
get_parameters_c(struct PolymerSolverData *d, int cell)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct UnstructuredGrid *g = d->grid;
|
struct UnstructuredGrid *g = d->grid;
|
||||||
@ -241,11 +255,10 @@ get_parameters_c(struct PolymerSolverData *d, int cell, NonlinearSolverCtrl* ctr
|
|||||||
double src = d->source[cell];
|
double src = d->source[cell];
|
||||||
p.influx = src > 0 ? -src : 0.0;
|
p.influx = src > 0 ? -src : 0.0;
|
||||||
p.influx_polymer = src > 0 ? -src*compute_mc(d->inflow_c, d->props, d->polydata) : 0.0;
|
p.influx_polymer = src > 0 ? -src*compute_mc(d->inflow_c, d->props, d->polydata) : 0.0;
|
||||||
p.outflux = d->source[cell] <= 0 ? -d->source[cell] : 0.0;
|
p.outflux = src <= 0 ? -src : 0.0;
|
||||||
p.porosity = d->porosity[cell];
|
p.porosity = d->porosity[cell];
|
||||||
p.psdata = d;
|
p.psdata = d;
|
||||||
p.cell = cell;
|
p.cell = cell;
|
||||||
p.ctrl = ctrl;
|
|
||||||
p.s = -1e100;
|
p.s = -1e100;
|
||||||
p.polydata = d->polydata;
|
p.polydata = d->polydata;
|
||||||
for (i=g->cell_facepos[cell]; i<g->cell_facepos[cell+1]; ++i) {
|
for (i=g->cell_facepos[cell]; i<g->cell_facepos[cell+1]; ++i) {
|
||||||
@ -272,8 +285,12 @@ get_parameters_c(struct PolymerSolverData *d, int cell, NonlinearSolverCtrl* ctr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef EXTRA_DEBUG_OUTPUT
|
#ifdef EXTRA_DEBUG_OUTPUT
|
||||||
std::cout << "in: " << p.influx << " in(polymer): " << p.influx_polymer
|
std::cout << "Cell: " << cell
|
||||||
<< " out: " << p.outflux << std::endl;
|
<< " in: " << p.influx
|
||||||
|
<< " in(polymer): " << p.influx_polymer
|
||||||
|
<< " out: " << p.outflux << '\n'
|
||||||
|
<< " c0: " << p.c0
|
||||||
|
<< " s0: " << p.s0 << std::endl;
|
||||||
#endif
|
#endif
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
@ -51,11 +51,9 @@ struct PolymerSolverData {
|
|||||||
double *mc;
|
double *mc;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NonlinearSolverCtrl;
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
polymer_solvecell(void *data, struct NonlinearSolverCtrl *ctrl, int cell);
|
polymer_solvecell(void *data, int cell);
|
||||||
|
|
||||||
void
|
void
|
||||||
destroy_solverdata(struct PolymerSolverData *d);
|
destroy_solverdata(struct PolymerSolverData *d);
|
||||||
|
@ -39,10 +39,6 @@ void polymertransport(
|
|||||||
inflow_c, saturation,
|
inflow_c, saturation,
|
||||||
concentration, cmax);
|
concentration, cmax);
|
||||||
|
|
||||||
|
|
||||||
struct NonlinearSolverCtrl ctrl;
|
|
||||||
|
|
||||||
|
|
||||||
/* Compute sequence of single-cell problems */
|
/* Compute sequence of single-cell problems */
|
||||||
sequence = (int*) malloc( grid->number_of_cells * sizeof *sequence);
|
sequence = (int*) malloc( grid->number_of_cells * sizeof *sequence);
|
||||||
components = (int*) malloc(( grid->number_of_cells+1) * sizeof *components);
|
components = (int*) malloc(( grid->number_of_cells+1) * sizeof *components);
|
||||||
@ -50,13 +46,6 @@ void polymertransport(
|
|||||||
compute_sequence(grid, darcyflux, sequence, components, &ncomponents);
|
compute_sequence(grid, darcyflux, sequence, components, &ncomponents);
|
||||||
assert(ncomponents == grid->number_of_cells);
|
assert(ncomponents == grid->number_of_cells);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ctrl.maxiterations = 20;
|
|
||||||
ctrl.nltolerance = 1e-9;
|
|
||||||
ctrl.method = NonlinearSolverCtrl::REGULAFALSI;
|
|
||||||
ctrl.initialguess = 0.5;
|
|
||||||
|
|
||||||
/* Assume all strong components are single-cell domains. */
|
/* Assume all strong components are single-cell domains. */
|
||||||
for(i=0; i<grid->number_of_cells; ++i)
|
for(i=0; i<grid->number_of_cells; ++i)
|
||||||
{
|
{
|
||||||
@ -68,7 +57,7 @@ void polymertransport(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
polymer_solvecell(data, &ctrl, sequence[i]);
|
polymer_solvecell(data, sequence[i]);
|
||||||
/*print("iterations:%d residual:%20.16f\n",
|
/*print("iterations:%d residual:%20.16f\n",
|
||||||
* ctrl.iterations, ctrl.residual);*/
|
* ctrl.iterations, ctrl.residual);*/
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user