Computes Kmin according to Wathelet et al. (2008) More...
#include <KminSolver.h>
Public Member Functions | |
| double | calculate (bool &ok) |
| double | groundLevel (double kminHalf, double kmax) |
| KminSolver (const QVector< Point2D > &stations) | |
Computes Kmin according to Wathelet et al. (2008)
Kmin is defined by the width of the peak at its mid-height (from -kmin/2 to kmin/2).
| ArrayCore::KminSolver::KminSolver | ( | const QVector< Point2D > & | stations | ) | [inline] |
: TheoreticalLinearFK(stations) {}
| double ArrayCore::KminSolver::calculate | ( | bool & | ok | ) |
Returns Kmin of the station array. ok is set to false if no value at 0.5 can be found in at least one direction. The range of search is arbitrarily set to pi/(5*dmax) to 3*sqrt(2)*pi/dmin where dmin and dmax are the minimum and maximum distances between stations. In some extreme cases, kmin is larger than 3*sqrt(2)*pi/dmin and false is set to ok.
References QGpCoreTools::RootSolverTemplate< double, FunctionClass >::lower(), QGpCoreTools::RootSolverTemplate< double, FunctionClass >::neville(), QGpCoreTools::RootSolverTemplate< double, FunctionClass >::searchUpSlope(), QGpCoreTools::RootSolverTemplate< double, FunctionClass >::setPolarity(), QGpCoreTools::RootSolverTemplate< double, FunctionClass >::setPrecision(), QGpCoreWave::TheoreticalLinearFK::setRadians(), QGpCoreTools::RootSolverTemplate< double, FunctionClass >::setRelativeStep(), QGpCoreTools::sqrt(), QGpCoreWave::TheoreticalFK::stations(), and TRACE.
Referenced by Simulator::init(), ArrayGui::ArrayResponse::setArray(), and ToolFK::setDefaultGridParameters().
{
TRACE;
ok=true;
// Get possible limits for array response map
const QVector<Point2D>& s=stations();
double dmin=1e99, dmax=0, d;
int i, j, n=s.count();
// Get min and max distances
for(i=0; i<n; i++) {
for(j=i+1; j<n; j++) {
d=s[i].distanceTo(s[j]);
if(d>0) {
if(d<dmin) {
dmin=d;
}
if(d>dmax) {
dmax=d;
}
}
}
}
// 5 and 3 are default values that work well
double gridMin=M_PI/(dmax*5.0);
double gridMax=3.0*sqrt(2.0)*M_PI/dmin;
double kminHalf=0.0;
// Get the theoretical limit kmin
RootSolver<KminSolver> kInv(this);
for(double a=M_PI;a>0.0;a-=0.0628) {
setRadians(a);
kInv.setPrecision(1e-7);
kInv.setRelativeStep(0.5);
kInv.setPolarity(0.0);
if(kInv.searchUpSlope(gridMin, gridMin, gridMax) ) {
kInv.neville();
double k=kInv.lower();
if(k>kminHalf) kminHalf=k;
} else {
ok=false;
return 0.0;
}
}
return 2.0*kminHalf;
}
| double ArrayCore::KminSolver::groundLevel | ( | double | kminHalf, |
| double | kmax | ||
| ) |
References QGpCoreWave::TheoreticalLinearFK::setRadians(), TRACE, and QGpCoreWave::TheoreticalLinearFK::value().
{
TRACE;
double sum=0;
double dk=0.02*(kmax-kminHalf);
for(double a=M_PI;a>0.0;a-=0.0628) {
setRadians(a);
for(double k=kminHalf;k<kmax;k+=dk) {
double v=value(k);
sum+=v;
}
}
return sum*0.0004;
}