00001 #include "facefluxwithgravity.h"
00002 #include "numericmethods.h"
00003
00004 FaceFluxWithGravity::FaceFluxWithGravity(OrthoMesh &mesh,Function1D &fMobW,Function1D &DfMobW,Function1D &fMobGrav,Function1D &DfMobGrav,const VecDouble &cK,double gc)
00005 :FaceFluxFunction(1),m_fMobW(fMobW),m_DfMobW(DfMobW),m_fMobGrav(fMobGrav),m_DfMobGrav(DfMobGrav),m_Vn(mesh.numFaces()),m_mesh(mesh),m_cK(cK)
00006 {
00007
00008 m_gc = gc;
00009 m_maxK = m_cK.linfty_norm();
00010 }
00011
00012
00013
00014
00015
00025 void FaceFluxWithGravity::exactFluxAtFace(VecDouble &vFlux, const FaceInfo &face,const VecDouble &Q1,const VecDouble &Q2)
00026 {
00027 assert( (unsigned) face.index < m_Vn.size());
00028 assert( (unsigned) face.cell1 < m_cK.size());
00029 assert( (unsigned) face.cell2 < m_cK.size());
00030
00031
00032
00033 double v = m_Vn(face.index);
00034 double fMin,fMax;
00035 double ul = Q1(0);
00036 double ur = Q2(0);
00037
00038
00039 if (v > 0)
00040 {
00041 if (ul > ur)
00042 {
00043 m_fMobW.getMinMaxValues(ur,ul,fMin,fMax);
00044 vFlux(0)=fMax*v;
00045 }
00046 else
00047 {
00048 m_fMobW.getMinMaxValues(ul,ur,fMin,fMax);
00049 vFlux(0)=fMin*v;
00050 }
00051
00052 }
00053 else
00054 {
00055 if (ul > ur)
00056 {
00057 m_fMobW.getMinMaxValues(ur,ul,fMin,fMax);
00058 vFlux(0)=fMin*v;
00059 }
00060 else
00061 {
00062 m_fMobW.getMinMaxValues(ul,ur,fMin,fMax);
00063 vFlux(0)=fMax*v;
00064 }
00065 }
00066
00067
00068
00069 if (face.normal == Z && !face.at_boundary )
00070 {
00071 const VecDouble &cK = getPermeability();
00072 double K1 = cK(face.cell1);
00073 double K2 = cK(face.cell2);
00074 vFlux(0) += (m_fMobGrav(ul) + m_fMobGrav(ur)) * K1*K2/(K1+K2) * m_gc;
00075 }
00076 }
00077
00078
00079
00086 void FaceFluxWithGravity::fluxAtFace(VecDouble &vFlux, const FaceInfo &face,const VecDouble &Q1,const VecDouble &Q2)
00087 {
00088 assert( (unsigned) face.index < m_Vn.size());
00089 assert( (unsigned) face.cell1 < m_cK.size());
00090 assert( (unsigned) face.cell2 < m_cK.size());
00091
00092 const double& u1 = Q1(0);
00093 const double& u2 = Q2(0);
00094
00095 double dMobW1 = m_fMobW(u1);
00096 double dMobW2 = m_fMobW(u2);
00097
00098 double v = m_Vn(face.index);
00099 vFlux(0) = (dMobW1+dMobW2)/2.0*v;
00100
00101
00102 if (face.normal == Z && !(face.at_boundary) )
00103 {
00104 const VecDouble &cK = getPermeability();
00105 double K1 = cK(face.cell1);
00106 double K2 = cK(face.cell2);
00107 vFlux(0) += (m_fMobGrav(u1) + m_fMobGrav(u2)) * K1*K2/(K1+K2) * m_gc;
00108
00109 }
00110 }
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 void FaceFluxWithGravity::maxGlobalCharVelocity(double vel[3])
00121 {
00122 static VecDouble normalVel(3);
00123 m_mesh.getMaxAbsVelocitiesInFacesByComponents(normalVel,m_Vn);
00124 vel[X]= normalVel(X)*m_DfMobW.getMaxNorm(0,1);
00125 vel[Y]= normalVel(Y)*m_DfMobW.getMaxNorm(0,1);
00126 vel[Z]= normalVel(Z)*m_DfMobW.getMaxNorm(0,1) + m_maxK*fabs(m_DfMobGrav.getMaxNorm(0,1)*m_gc);
00127 printf("Max Vel %g, GradMob %g\n",std::max(normalVel(X), std::max(normalVel(Y),normalVel(Z))),m_DfMobW.getMaxNorm(0,1));
00128 }
00129
00130
00131
00132 double FaceFluxWithGravity::maxLocalCharVelocity(const FaceInfo &face,const VecDouble &vQ1,const VecDouble &vQ2)
00133 {
00134 double u1=vQ1(0);
00135 double u2=vQ2(0);
00136 if (u1>u2)
00137 std::swap(u1,u2);
00138
00139 double v=m_Vn(face.index);
00140
00141
00142
00143 if (face.normal != Z)
00144 return v*m_DfMobW.getMaxNorm(u1,u2);
00145 else
00146 {
00147 double term1 = v*m_DfMobW.getMaxNorm(u1,u2);
00148
00149
00150 double K = fmax(getPermeability()(face.cell1), getPermeability()(face.cell2));
00151
00152
00153
00154 double dMax,dMin;
00155 m_DfMobGrav.getMinMaxValues(u1,u2,dMin,dMax);
00156 double dMaxAbs = std::max(fabs(dMin),fabs(dMax));
00157
00158 return fabs(term1) + fabs(K*dMaxAbs*m_gc);
00159 }
00160 }
00161
00162
00163
00164
00165
00166 void FaceFluxWithGravity::updateDynamicData(DynamicBase &dynMod)
00167 {
00168 dynMod.getNormalVelocityAtFaces(m_Vn);
00169 }
00170
00171