⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flash.cpp

📁 这是本人两年前兼职为某个公司做的石油钻进设计软件
💻 CPP
📖 第 1 页 / 共 3 页
字号:
					 for( i=0; i<m_iNum+1; i++ )
							X1[i] = m_pfXi[i];
					 fP1 = m_fPress;
				}
				else if( DS <= 2 )
				{
					 for( i=0; i<m_iNum+1; i++ )
							X2[i] = m_pfXi[i];
					 fP2 = m_fPress;
				}
				else if( DS < 4 )
				{
					 for( i=0; i<m_iNum+1; i++ )
							X3[i] = m_pfXi[i];
					 fP3 = m_fPress;
				}
				else
				{
					 for( i=0; i<m_iNum+1; i++ )
					 {
							X1[i] = X2[i];
							X2[i] = X3[i];
							X3[i] = m_pfXi[i];
					 }
					 fP1 = fP2;
					 fP2 = fP3;
					 fP3 = m_fPress;
				}
				iRes = 0;
				break;     //成功
		  }
	 }
	 if( IC == 1000 && iRes != 0 )
		  iResFlag = 10;

	 delete PP;
	 delete U;
	 delete Y1;
	 for( i=0; i<m_iNum+1; i++ )
			free( H[i] );
	 free( H );

	 return iResFlag;	    //不成功
}*/
//------------------------------------------------------------------------------
//处理下一步的闪蒸数据
int EOSFlashClass::InitNextFlashSpot(  )
{
	 int             i;
	 float           L;

	 DS++;
	 if( DS > 100 )
		  DS = 5;

	 m_fV = m_pfXi[m_iNum];
	 L = 1 - m_fV;
	 if( L < 0.4 )
		  m_fPress = m_fPress - m_fPStep;
	 else if( L < 0.6 )
		  m_fPress = m_fPress - 1;
	 else
		  m_fPress = float(m_fPress-0.1);

	 if( DS > 4 )
		  for( i=0; i<m_iNum+1; i++ )
		  {
				 m_pfXi[i] =  ( (m_fPress-fP2)*(m_fPress-fP3)*X1[i] ) / ( (fP1-fP2)*(fP1-fP3) );
				 m_pfXi[i] += ( (m_fPress-fP1)*(m_fPress-fP3)*X2[i] ) / ( (fP2-fP1)*(fP2-fP3) );
				 m_pfXi[i] += ( (m_fPress-fP1)*(m_fPress-fP2)*X3[i] ) / ( (fP3-fP1)*(fP3-fP2) );
		  }
	 m_fV = m_pfXi[m_iNum];
	 for( i=0; i<m_iNum; i++ )
			m_pfYi[i] = ( m_pfZi[i] - (1-m_fV)*m_pfXi[i] ) / m_fV;
	 return 0;
}

//------------------------------------------------------------------------------
int EOSFlashClass::BroyDen(  )
{
	 int      LB,     iResFlag, iIterNum, iMaxIterNum=100;
	 int      i,      j,        K,        iRes;
	 double   SA = 0, SB = 0,   EPS=0.0000001;
	 float    *F;

	 float    *PP, *U, *Y1, **H;

	 PP = new float[m_iNum+1];
	 U  = new float[m_iNum+1];
	 Y1 = new float[m_iNum+1];
	 H  = (float **)calloc( m_iNum+1, sizeof( float* ) );
	 for( i=0; i<m_iNum+1; i++ )
			H[i] = (float*)calloc( m_iNum+1, sizeof( float ) );

	 for( i=0; i<m_iNum+1; i++ )
	 {
			PP[i] = 0;
			for( j=0; j<m_iNum+1; j++ )
				  H[i][j] = 0;
	 }
	 for( i=0; i<m_iNum+1; i++ )
			H[i][i] = 1;

	 iResFlag =  ObjectEquation(  );
	 F        =  m_pffi;

	 K        = 0;
	 iIterNum = 0;
	 while( iIterNum < iMaxIterNum && iResFlag == 0 )
	 {   if( K < m_iNum+1 )
		  {   //3460
				PP[K] = float(0.001);
				LB    = -3;
				//goto 3860
		  }
		  else
		  {   //3520
				for( i=0; i<m_iNum+1; i++ )
				{    SA = 0;
					  for( j=0; j<m_iNum+1; j++ )
							 SA = SA - H[i][j]*F[j];
					  PP[i] = float(SA);
				}
				LB = -2;
				//goto 38600
		  }

		  //3860  program
		  for( i=0; i<m_iNum+1; i++ )
		  {    m_pfXi[i] = m_pfXi[i] + PP[i];
				 U[i] = F[i];
		  }

		  m_fV = m_pfXi[m_iNum];
		  for( i=0; i<m_iNum; i++ )
				 m_pfYi[i] = ( m_pfZi[i] - m_pfXi[i]*(1-m_fV) ) / m_fV;

		  iResFlag = ObjectEquation(  );
		  if( iResFlag )
				break;  //不成功

		  iIterNum++;
		  for( i=0; i<m_iNum+1; i++ )
				 Y1[i] = F[i] - U[i];
		  SA = 0;
		  for( i=0; i<m_iNum+1; i++ )
		  {
				 SB = 0;
				 for( j=0; j<m_iNum+1; j++ )
						SB = SB + H[i][j] * Y1[j];
				 U[i] = float(SB-PP[i]);
				 SA = SA + SB * PP[i];
		  }

		  if( fabs(SA) < 1e-17 )
		  {
				m_fV = m_pfXi[m_iNum];
				iRes = 10;
				continue;
				//break;    //?不成功
		  }

		  for( j=0; j<m_iNum+1; j++ )
		  {
				 SB = 0;
				 for( i=0; i<m_iNum+1; i++ )
						SB = SB + PP[i] * H[i][j];
				 SB = SB /SA;
				 for( i=0; i<m_iNum+1; i++ )
						H[i][j] = float(H[i][j]-SB*U[i]);
		  }

		  if( LB == -3 )
		  {   //3490
				PP[K] = 0;
				K++;
				//goto 3450
		  }
		  else
		  {    //3610
				 SA = 0;
				 for( i=0; i<m_iNum+1; i++ )
						SA = SA + F[i] * F[i];
				 if( SA > EPS )
				 {
					  if( iIterNum > iMaxIterNum )
					  {   //3840
							iResFlag = 10;
							break;   //不成功
					  }
					  else
					  {
						  //3520
					  }
				 }
				 else
				 {
					  m_fV  = m_pfXi[m_iNum];
					  for( i=0; i<m_iNum; i++ )
							 m_pfYi[i] = ( m_pfZi[i] - (1-m_fV)*m_pfXi[i] ) / m_fV;
					  if( DS <= 1 )
					  {
							for( i=0; i<m_iNum+1; i++ )
								  X1[i] = m_pfXi[i];
							fP1 = m_fPress;
					  }
					  else if( DS <= 2 )
					  {
							for( i=0; i<m_iNum+1; i++ )
								  X2[i] = m_pfXi[i];
							fP2 = m_fPress;
					  }
					 else if( DS < 4 )
					 {
							for( i=0; i<m_iNum+1; i++ )
								  X3[i] = m_pfXi[i];
							fP3 = m_fPress;
					 }
					 else
					 {
							for( i=0; i<m_iNum+1; i++ )
							{
								  X1[i] = X2[i];
								  X2[i] = X3[i];
								  X3[i] = m_pfXi[i];
							}
							fP1 = fP2;
							fP2 = fP3;
							fP3 = m_fPress;
					 }
					 m_fV = m_pfXi[m_iNum];
					 for( i=0; i<m_iNum; i++ )
							m_pfYi[i] = ( m_pfZi[i] - m_pfXi[i]*(1-m_fV) ) / m_fV;
					 iResFlag = 0;
					 break;     //成功
				}
		  }
	 }
	 if( iIterNum == iMaxIterNum && iResFlag != 0 )
		  iResFlag = 10;

	 delete PP;
	 delete U;
	 delete Y1;
	 for( i=0; i<m_iNum+1; i++ )
			free( H[i] );
	 free( H );

	 return iResFlag;	    //不成功
}

//==========================设置拟压力计算的压力段数据=========================
void EOSFlashClass::SetPMP_Pressure( )
{
	float   fPressure=(float)0.05, fStep;
	double  fDewPressure = m_fDewPressure * 0.101325;
	
	m_pfPMP_Press[0] = fPressure;

	for( int i=1; i<m_iPMP_Num; i++)
	{
		if( fPressure < 0.8 )
			 fStep = (float)0.2;
		else if( fPressure < 14.5 )
			 fStep=(float)0.5;
		else if( fPressure < 35 )
			fStep = (float)1.0;
		else  fStep = (float)2.0;

		fPressure += fStep;
		if( fPressure >= fDewPressure && m_pfPMP_Press[i-1] < fDewPressure-0.05 )
			m_pfPMP_Press[i] = float(fDewPressure);
		else
			m_pfPMP_Press[i] = fPressure;
	}
}



int EOSFlashClass::FlashCalculate( float* pfComposition, float fTemp, float fPress )
{   //摩尔组分
	/*pfComposition[0] = float(0.807);     //C1
	pfComposition[1] = (float)0.091;     //C2
	pfComposition[2] = (float)0.0179;    //C3
	pfComposition[3] = (float)0.0078;    //iC4
	pfComposition[4] = (float)0.005;     //nC4
	pfComposition[5] = (float)0.0008;    //iC5
	pfComposition[6] = 0;                //nC5
	pfComposition[7] = (float)0.0555;    //C6
	pfComposition[8] = (float)0.005;     //C7+
	pfComposition[9] = (float)0.005;     //H2
	pfComposition[10] = (float)0.005;    //H2O
	pfComposition[11] = 0;               //H2S
	pfComposition[12] = 0;               //N2
	pfComposition[13] = 0;               //O2
	pfComposition[14] = 0;               //CO
	pfComposition[15] = 0;               //CO2
	pfComposition[16] = 0;               //He
	pfComposition[17] = 0;               //Air*/



	//设置初值
	m_fTemp  = fTemp;
	m_fPress = fPress;
	m_fPStep = 5;
	m_fV     = (float)0.999;
	SetComposition( pfComposition );
	InputCompFixData( pfComposition );

	//计算露点压力
	char pMsg[128];
	int  iRes = CalDewPressure(  );
	sprintf( pMsg, "露点压力 = %f  iRes=%d", m_fDewPressure, iRes );
	//AfxMessageBox( pMsg );
	if( iRes )
	{
		AfxMessageBox( "计算露点压力错误" );
		return 1;
	}

	SetPMP_Pressure( );


	//高于露点压力------------单相区
	//根据总组分计算临界压力、临界温度、分子量
	float fTc = 0, fPc = 0, fMg = 0;
	for( int i=0; i<m_iNum; i++ )
	{
		m_pfYi[i] = m_pfZi[i];
		m_pfXi[i] = 0;
		fTc = fTc + m_pfYi[i]*m_pfTci[i];
		fPc = fPc + m_pfYi[i]*m_pfPci[i];
		fMg = fMg + m_pfYi[i]*m_pfMi[i];
	}
	sprintf( pMsg, "单相期 Pc=%f  Tc=%f  rg=%f", fPc, fTc, fMg/29.8 );
	//AfxMessageBox( pMsg );

	
	float  fU  = 0, fDewPressure = float(m_fDewPressure*0.101325);
	i = m_iPMP_Num - 1;
	while( m_pfPMP_Press[i] >= fDewPressure )
	{
		m_fPress = float(m_pfPMP_Press[i]*9.86923);
	    //单相计算气体物性参数,忽略油相

		m_pfMg[i] = fMg;            //气相分子量
		m_pfZg[i] = Zg_Calculate( fTc, float(fPc/9.86923), 
		                                    m_fTemp,
										    float(m_pfPMP_Press[i]),
										    ZG_DEFAULT );
		m_pfDg[i] = float(m_pfPMP_Press[i]*fMg / (m_pfZg[i]*0.008314*m_fTemp));
		m_pfUg[i] = Ug_Lee_Gonzalez_Eakin( float(m_pfPMP_Press[i]), m_fTemp, float(fMg/28.96), m_pfZg[i] );
		m_pfUg[i] = Ug_Calculate( fTc, float(fPc/9.86923), 
		                                    m_fTemp,
										    float(m_pfPMP_Press[i]),
										    m_pfZg[i],
										    float(fMg/28.96),
										    0,//pWellResFluidParm->GetN2()/100,
										    0,//pWellResFluidParm->GetCO2()/100,
										    0,//pWellResFluidParm->GetH2S()/100,
										    UG_DEFAULT );

		
		m_pfV[i]  = 1;             //气相摩尔分数
		m_pfSg[i] = 1;            //气相饱和度
		m_pfDo[i] = m_pfDg[i];            //油相密度
		m_pfZo[i] = m_pfZg[i];            //油相偏差因子
		m_pfUo[i] = m_pfUg[i];            //油相粘度
		m_pfMo[i] = m_pfMg[i];            //油相分子量
		i--;
	}

	//低于露点压力------------两相区
	if( i >= 0 )
		m_fPress = float(m_pfPMP_Press[i]*9.86923);
	if( m_fPress < m_fDewPressure )
	{
		m_fV = (float)0.9999;
		iRes = 1;
		while( iRes )
		{
			iRes = CalZV(  );
			m_fPress -= 0.5;
			if( m_fPress < 5 )
				break;
		}
		if( iRes )
		{
			AfxMessageBox( "计算气相Mol分数错误" );
			return 1;
		}
		while( m_fPress > 5 )
		{
		    iRes = BroyDen(  );
			if( iRes )
			{
			    sprintf( pMsg,"拟牛顿迭代错误  iRes=%d", iRes );
				AfxMessageBox( pMsg );
				break;
			}


			/*
			//将气相和液相分别按单相气体处理,计算物性参数
			fTc = 0;
			fPc = 0;
			fMg = 0;
			for( i=0; i<pCoeffData->iNum; i++ )
			{
				fTc = fTc + pFlashData->m_pfYi[i]*pCoeffData->m_pfTci[i];
				fPc = fPc + pFlashData->m_pfYi[i]*pCoeffData->m_pfPci[i];
				fMg = fMg + pFlashData->m_pfYi[i]*pCoeffData->m_pfMi[i];
			}
			pFlashData->fZg = Zg_Calculate( fTc, fPc/9.86923, 
		                                    pFlashData->fTemp,
										    pFlashData->fPress/9.86923,
											ZG_DEFAULT );
			pFlashData->fUg = Ug_Calculate( fTc, fPc/9.86923, 
		                                  pFlashData->fTemp,
										  pFlashData->fPress/9.86923,
										  pFlashData->fZg,
										  fMg/28.96,
										  pFlashData->m_pfZi[COMP_H2S],
										  pFlashData->m_pfZi[COMP_CO2],
										  pFlashData->m_pfZi[COMP_N2],
										  UG_DEFAULT );
			fCg = Cg_Calculate( fTc, fPc/9.86, pFlashData->fTemp, pFlashData->fPress/9.86, pFlashData->fZg, CG_DEFAULT );
			fBg = Bg_Calculate( pFlashData->fTemp, pFlashData->fPress/9.86923, pFlashData->fZg );


			fTc = 0;
			fPc = 0;
			fMg = 0;
			for( i=0; i<pCoeffData->iNum; i++ )
			{
				fTc = fTc + pFlashData->m_pfXi[i]*pCoeffData->m_pfTci[i];
				fPc = fPc + pFlashData->m_pfXi[i]*pCoeffData->m_pfPci[i];
				fMg = fMg + pFlashData->m_pfXi[i]*pCoeffData->m_pfMi[i];
			}
			pFlashData->fUo = Ug_Calculate( fTc, fPc/9.86923, 
		                                  pFlashData->fTemp,
										  pFlashData->fPress/9.86923,
										  pFlashData->fZo,
										  fMg/28.96,
										  pFlashData->m_pfZi[COMP_H2S],
										  pFlashData->m_pfZi[COMP_CO2],
										  pFlashData->m_pfZi[COMP_N2],
										  UG_DEFAULT );
			fCo = Cg_Calculate( fTc, fPc/9.86, pFlashData->fTemp, pFlashData->fPress/9.86, pFlashData->fZo, CG_DEFAULT );
			*/

			CalMoleDensity(  );
			CalViscosity( m_pfXi, m_fDo, fU );
			m_fUo = fU;
			CalViscosity( m_pfYi, m_fDg, fU );
			m_fUg = fU;
			m_pfUo[i] = m_fUo;            //油相粘度
			m_pfUg[i] = m_fUg;            //气相粘度
			m_pfZo[i] = m_fZo;            //油相偏差因子
			m_pfZg[i] = m_fZg;            //气相偏差因子


			CalMolecularWeight(  );
			m_pfMo[i] = m_fMo*1000;            //油相分子量
			m_pfMg[i] = m_fMg*1000;            //气相分子量

			CalQualityDensity( );
			m_pfDo[i] = m_fDo;            //油相密度
			m_pfDg[i] = m_fDg;            //气相密度

			CalVolumeFraction( );
			m_pfSg[i] = m_fSg;            //气相饱和度

			if( m_fV > 1 )
				m_fV = 1;
			m_pfV[i]  = m_fV;             //气相摩尔分数

			i--;
			m_fPStep = float((m_pfPMP_Press[i+1]-m_pfPMP_Press[i])*9.86923);
			InitNextFlashSpot(  );
			//AfxMessageBox( "下一次拟牛顿迭代" );
		}
	}
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -