-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathdryrockwalton.cpp
162 lines (119 loc) · 4.06 KB
/
dryrockwalton.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#include "rplib/dryrockwalton.h"
#include "rplib/solid.h"
#include "nrlib/math/constants.hpp"
#include <cassert>
#include <cmath>
DryRockWalton::DryRockWalton(const Solid * solid,
const double & friction_weight,
const double & pressure,
const double & porosity,
const double & coord_number,
const std::vector<double> & u)
: DryRock()
{
u_ = u; // u contains independent samples used in quantiles of friction_weight, pressure, porosity, coord_number
solid_ = solid->Clone();
friction_weight_ = friction_weight;
//unit conversion MPa -> GPa
pressure_ = pressure/1000.0;
total_porosity_ = porosity;
if (coord_number < 0) {
coord_number_ = CalcCoordNumber();
calc_coord_number_ = true;
}
else {
coord_number_ = coord_number;
calc_coord_number_ = false;
}
ComputeElasticParams();
}
DryRockWalton::DryRockWalton()
: DryRock()
{
solid_ = NULL;
friction_weight_ = 0;
calc_coord_number_ = 0;
pressure_ = 0;
coord_number_ = 0;
}
DryRockWalton::~DryRockWalton()
{
delete solid_;
}
DryRockWalton& DryRockWalton::operator=(const DryRockWalton& rhs)
{
if (this != &rhs) {
DryRock::operator=(rhs);
friction_weight_ = rhs.friction_weight_;
pressure_ = rhs.pressure_;
coord_number_ = rhs.coord_number_;
calc_coord_number_ = rhs.calc_coord_number_;
delete solid_;
solid_ = rhs.solid_->Clone();
}
return *this;
}
DryRock *
DryRockWalton::Clone() const {
// Provide base class variables.
DryRockWalton * r = new DryRockWalton(*this);
// Provide variables specific to DryRockWalton.
r->solid_ = this->solid_->Clone(); // Deep copy.
r->friction_weight_ = this->friction_weight_;
r->pressure_ = this->pressure_;
r->coord_number_ = this->coord_number_;
r->calc_coord_number_ = this->calc_coord_number_;
return r;
}
void
DryRockWalton::SetTotalPorosity(double porosity) {
DryRock::SetTotalPorosity(porosity);
if (calc_coord_number_ == true)
coord_number_ = CalcCoordNumber();
ComputeElasticParams();
}
void
DryRockWalton::ComputeElasticParams() {
static const double pi = NRLib::Pi;
static const double pi4_inv = 1.0/(4*pi);
double mu_solid, k_solid, rho_solid;
solid_->GetElasticParams(k_solid, mu_solid, rho_solid);
mineral_moduli_k_ = k_solid;
//unit conversion from kPa->GPa, pressure is stored in GPa so no conversion is necessary.
const double fac = 1000000.0;
k_solid /= fac;
mu_solid /= fac;
const double mu_solid_inv = 1.0/mu_solid;
const double lambda = k_solid - (2.0*mu_solid)/3.0;
const double modulus_inv = 1.0/(mu_solid + lambda);
double a = pi4_inv*(mu_solid_inv - modulus_inv);
double b = pi4_inv*(mu_solid_inv + modulus_inv);
double x = std::pow((3*coord_number_*coord_number_*(1 - total_porosity_)*(1 - total_porosity_)*pressure_)/(pi*pi*pi*pi*b*b), 1.0/3.0);
double k_rough = x/6.0;
double mu_rough = (3.0/5.0)*k_rough*(5.0*b + a)/(2.0*b + a);
double mu_smooth = x/10.0;
//double k_smooth = 5.0*mu_smooth/3.0; //== k_rough
k_ = k_rough;
mu_ = friction_weight_*mu_rough + (1.0 - friction_weight_)*mu_smooth;
//unit conversion from GPa -> kPa
k_ *= fac;
mu_ *= fac;
rho_ = (1-total_porosity_)*rho_solid;
}
double
DryRockWalton::CalcCoordNumber() const {
static const double coord [] = {14.007, 12.336, 10.843, 9.5078, 8.3147, 7.2517, 6.3108, 5.4878, 4.7826, 4.1988, 3.7440};
//int size = 11;
double dp = 0.05;
double p_min = 0.2;
double p_max = 0.7;
if (total_porosity_ <= p_min)
return p_min;
else if (total_porosity_ >= p_max)
return p_max;
double x = (total_porosity_ - p_min)/dp;
int i1 = static_cast<int>(std::floor(x));
double t = x - i1;
double ret = t*coord[i1 + 1] + (1.0 - t)*coord[i1];
return ret;
}