00001 #include "dfchaventmobility.h"
00002
00003
00004 DFChaventMobility::DFChaventMobility(double vw,double vo,double Srw,double Sro)
00005 :Function1D(1)
00006 {
00007 m_M=vw/vo;
00008
00009 MaxSo=1-Srw;
00010 MaxSw=1-Sro;
00011 MinSw=Srw;
00012 MinSo=Sro;
00013
00014
00015
00016
00017
00018 _c = m_M*MaxSo*MaxSo/(MaxSw*MaxSw);
00019 _d = 2*_c*(MaxSw-MinSw);
00020 _a1=_c+1;
00021 _a2=-2*(MinSw + _c*MaxSw);
00022 _a3=_c*MaxSw*MaxSw+MinSw*MinSw;
00023
00024 m_inflectPoint = getInflectionDerivativePoint(m_M);
00025 m_inflectPointDeriv=(*this)(m_inflectPoint);
00026 }
00027
00028
00029
00030
00031 double DFChaventMobility::operator()(double x,unsigned cmp) const
00032 {
00033 if (x >= MaxSw || x <= MinSw )
00034 return 0.0;
00035 register double quot=(_a1*x + _a2)*x + _a3;
00036 quot*=quot;
00037 return _d*(MaxSw-x)*(x-MinSw)/quot;
00038 }
00039
00040
00041 void DFChaventMobility::getMinMaxValues(double a, double b,double &min,double &max) const
00042 {
00043
00044 assert(a<=b);
00045 if (a<0.0) a=0.0;
00046 if (b>1.0) b=1.0;
00047 if (b< m_inflectPoint)
00048 {
00049 min=(*this)(a,0);
00050 max=(*this)(b,0);
00051 }
00052 else if (a>m_inflectPoint)
00053 {
00054 max=(*this)(a,0);
00055 min=(*this)(b,0);
00056 }
00057 else
00058 {
00059 max=m_inflectPointDeriv;
00060 min=std::min( (*this)(a,0), (*this)(b,0));
00061 }
00062 }
00063
00064
00065 double DFChaventMobility::getMaxNorm(double a, double b) const
00066 {
00067 assert(a<=b);
00068 if (a<0.0) a=0.0;
00069 if (b>1.0) b=1.0;
00070 if (b< m_inflectPoint)
00071 {
00072 return (*this)(b,0);
00073 }
00074 else if (a>m_inflectPoint)
00075 {
00076 return (*this)(a,0);
00077 }
00078 else
00079 {
00080 return m_inflectPointDeriv;
00081 }
00082
00083 }
00084
00085 void DFChaventMobility::updateInflectionPoint()
00086 {
00087 m_inflectPoint = getInflectionDerivativePoint(m_M);
00088 m_inflectPointDeriv=(*this)(m_inflectPoint);
00089 }
00090
00091
00092
00093
00094 double DFChaventMobility::getInflectionDerivativePoint(double M)
00095 {
00096 static double sqrt3 = sqrt(3.0);
00097
00098
00099 double dd=MaxSw-MinSw;
00100 double dd2=dd*dd;
00101 double dd3=dd*dd2;
00102
00103 double b = -sqrt(_c)*dd3/(4*(_c+1));
00104 double a = (1-_c)*dd3/(8*(_c+1));
00105 double r=pow(hypot(a,b),1.0/3.0);
00106 double theta=atan2(b,a)/3.0;
00107 a=r*cos(theta);
00108 b=r*sin(theta);
00109 double aux1=(-sqrt3*b-a)/2.0;
00110
00111 return aux1*dd2/(4*(b*b + a*a)) + aux1 + (MaxSw+MinSw)/2.0;
00112
00113
00114
00115 }
00116
00117
00118 void DFChaventMobility::setParameters(const VecDouble &v)
00119 {
00120 assert(v.size() ==2);
00121 m_M=v(0)/v(1);
00122 }
00123
00124
00125 DFChaventMobility::~DFChaventMobility()
00126 {
00127
00128 }