Newer
Older
/**
* \copyright
* Copyright (c) 2012-2020, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
*/
#include "Subdivision.h"
#include <algorithm>
#include <cmath>
#include <BaseLib/Error.h>
namespace BaseLib
{
GradualSubdivision::GradualSubdivision(const double L,
const double dL0,
const double max_dL,
const double multiplier)
: _length(L), _dL0(dL0), _max_dL(max_dL), _multiplier(multiplier)
{
// Check if accumulated subdivisions can ever sum up to length.
// Cf. geometric series formula.
if (multiplier < 1.0 && dL0 / (1.0 - multiplier) < L) {
OGS_FATAL(
"Using dL0=%g and multiplier=%g the generated subdivisions can not "
"sum up to a total length of %g.",
dL0,
multiplier,
L);
}
}
std::vector<double> GradualSubdivision::operator()() const
{
std::vector<double> vec_x;
double x = 0;
unsigned i = 0;
do {
vec_x.push_back(x);
x += std::min(_max_dL,
_dL0 * std::pow(_multiplier, static_cast<double>(i)));
i++;
} while (x < _length);
if (vec_x.back() < _length) {
double last_dx = vec_x[vec_x.size() - 1] - vec_x[vec_x.size() - 2];
if (_length - vec_x.back() < last_dx)
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
GradualSubdivisionFixedNum::GradualSubdivisionFixedNum(
const double L, const std::size_t num_subdivisions, const double multiplier)
: _length{L}, _num_subdivisions{num_subdivisions}, _multiplier{multiplier}
{
}
std::vector<double> GradualSubdivisionFixedNum::operator()() const
{
std::vector<double> subdivisions;
subdivisions.reserve(_num_subdivisions + 1);
subdivisions.push_back(0.0);
auto const q = _multiplier;
if (q == 1.0) {
double const dx = _length / _num_subdivisions;
for (std::size_t i = 1; i < _num_subdivisions; ++i) {
subdivisions.push_back(dx * i);
}
} else {
// compute initial subdivision size
auto const a =
_length * (q - 1.0) / (std::pow(q, _num_subdivisions) - 1.0);
double qi = q; // q^i
for (std::size_t i = 1; i < _num_subdivisions; ++i) {
subdivisions.push_back(a * (qi - 1.0) / (q - 1.0));
qi *= q;
}
}
subdivisions.push_back(_length);
return subdivisions;
}
} // namespace BaseLib