Exemple #1
0
void bicgstab_euclid(Mat_dh A, Euclid_dh ctx, double *x, double *b, HYPRE_Int *itsOUT)
{
  START_FUNC_DH
  HYPRE_Int its, m = ctx->m;
  bool monitor;
  HYPRE_Int maxIts = ctx->maxIts;
  double atol = ctx->atol, rtol = ctx->rtol;

  /* scalars */
  double alpha, alpha_1,
         beta_1,
         widget, widget_1,
         rho_1, rho_2,
         s_norm, eps,
         exit_a, b_iprod, r_iprod;

  /* vectors */
  double *t, *s, *s_hat, *v, *p, *p_hat, *r, *r_hat;

  monitor = Parser_dhHasSwitch(parser_dh, "-monitor");

  /* allocate working space */
  t = (double*)MALLOC_DH(m*sizeof(double));
  s = (double*)MALLOC_DH(m*sizeof(double));
  s_hat = (double*)MALLOC_DH(m*sizeof(double));
  v = (double*)MALLOC_DH(m*sizeof(double));
  p = (double*)MALLOC_DH(m*sizeof(double));
  p_hat = (double*)MALLOC_DH(m*sizeof(double));
  r = (double*)MALLOC_DH(m*sizeof(double));
  r_hat = (double*)MALLOC_DH(m*sizeof(double));

  /* r = b - Ax */
  Mat_dhMatVec(A, x, s); /* s = Ax */
  CopyVec(m, b, r);      /* r = b */
  Axpy(m, -1.0, s, r);   /* r = b-Ax */
  CopyVec(m, r, r_hat); /* r_hat = r */

  /* compute stopping criteria */
  b_iprod = InnerProd(m, b, b); CHECK_V_ERROR;
  exit_a = atol*atol*b_iprod;  CHECK_V_ERROR; /* absolute stopping criteria */
  eps = rtol*rtol*b_iprod;       /* relative stoping criteria (residual reduction) */

  its = 0;
  while(1) {
    ++its;  
    rho_1 = InnerProd(m, r_hat, r);
    if (rho_1 == 0) {
      SET_V_ERROR("(r_hat . r) = 0; method fails");
    }

    if (its == 1) {
      CopyVec(m, r, p);   /* p = r_0 */ CHECK_V_ERROR;
    } else {
      beta_1 = (rho_1/rho_2)*(alpha_1/widget_1);
      
      /* p_i = r_(i-1) + beta_(i-1)*( p_(i-1) - w_(i-1)*v_(i-1) ) */
      Axpy(m, -widget_1, v, p); CHECK_V_ERROR;
      ScaleVec(m, beta_1, p); CHECK_V_ERROR;
      Axpy(m, 1.0, r, p); CHECK_V_ERROR;
    }

    /* solve M*p_hat = p_i */
    Euclid_dhApply(ctx, p, p_hat); CHECK_V_ERROR;

    /* v_i = A*p_hat */
    Mat_dhMatVec(A, p_hat, v); CHECK_V_ERROR;

    /* alpha_i = rho_(i-1) / (r_hat^T . v_i ) */
    { double tmp = InnerProd(m, r_hat, v); CHECK_V_ERROR;
      alpha = rho_1/tmp;
    }

    /* s = r_(i-1) - alpha_i*v_i */
    CopyVec(m, r, s); CHECK_V_ERROR;
    Axpy(m, -alpha, v, s); CHECK_V_ERROR;

    /* check norm of s; if small enough:
     * set x_i = x_(i-1) + alpha_i*p_i and stop.
     * (Actually, we use the square of the norm)
     */
    s_norm = InnerProd(m, s, s);
    if (s_norm < exit_a) {
      SET_INFO("reached absolute stopping criteria");
      break;
    }

    /* solve M*s_hat = s */
    Euclid_dhApply(ctx, s, s_hat); CHECK_V_ERROR;

    /* t = A*s_hat */
    Mat_dhMatVec(A, s_hat, t); CHECK_V_ERROR;

    /* w_i = (t . s)/(t . t) */
    { double tmp1, tmp2;
      tmp1 = InnerProd(m, t, s); CHECK_V_ERROR;
      tmp2 = InnerProd(m, t, t); CHECK_V_ERROR;
      widget = tmp1/tmp2;
    }

    /* x_i = x_(i-1) + alpha_i*p_hat + w_i*s_hat */
    Axpy(m, alpha, p_hat, x); CHECK_V_ERROR;
    Axpy(m, widget, s_hat, x); CHECK_V_ERROR;

    /* r_i = s - w_i*t */
    CopyVec(m, s, r); CHECK_V_ERROR;
    Axpy(m, -widget, t, r); CHECK_V_ERROR;

    /* check convergence; continue if necessary;
     * for continuation it is necessary thea w != 0.
     */
    r_iprod = InnerProd(m, r, r); CHECK_V_ERROR;
    if (r_iprod < eps) {
      SET_INFO("stipulated residual reduction achieved");
      break;
    }

    /* monitor convergence */
    if (monitor && myid_dh == 0) {
      hypre_fprintf(stderr, "[it = %i] %e\n", its, sqrt(r_iprod/b_iprod));
    }

    /* prepare for next iteration */
    rho_2 = rho_1;
    widget_1 = widget;
    alpha_1 = alpha;

    if (its >= maxIts) {
      its = -its;
      break;
    }
  }

  *itsOUT = its;

  FREE_DH(t);
  FREE_DH(s);
  FREE_DH(s_hat);
  FREE_DH(v);
  FREE_DH(p);
  FREE_DH(p_hat);
  FREE_DH(r);
  FREE_DH(r_hat);
  END_FUNC_DH
}
Exemple #2
0
//컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴
//Procedure		ProcessPistonEngine
//Author		Craig Beeston
//Date			Tue 11 Aug 98
//
//Description	Processes a piston engine
//					Calculates Thrust, Torque, Engine power and Engine speed
//
//Inputs		
//
//Returns	
//
//------------------------------------------------------------------------------
void Engine::ProcessPistonEngine (AirStrucPtr const ControlledAC)
{
	AircraftAnimData* adptr = (AircraftAnimData *)ControlledAC->Anim;
	SWord iDamage = 255 - (255 - UWord(adptr->ENGINELEFT)) * (255 - UWord(adptr->FRONT)) / 255;
	if(pThrustPoint->Pos.x > 0)
		iDamage = adptr->ENGINERIGHT;
	
	FP MaxSpeed = 2 * Rpm100 * 0.001047197;	//RPM 2 Rads/cs
	if(iDamage == 254)
		MaxSpeed = 0;
	FP fDamage = 1.0 - FP(iDamage) * (1.0 / 255.0);
		
//DEADCODE CB 04/11/99 	FP MinSpeed =     Rpm0   * 0.001047197;	//RPM 2 Rads/cs

//DEADCODE CB 04/11/99 	if (Speed < MinSpeed) Speed = MinSpeed;	
	if (Speed > MaxSpeed) Speed = MaxSpeed;	

	FP EngRPM    = Speed * 954.9296586;
	FP PropSpeed = Speed * GearRatio;
	FP PropSwirl = SlipRot * 0.5;

	const FP BladeFract = 0.60;

	FCRD Vel;
	CPrd(Vel, pThrustPoint->Pos, pModel->RotVel);
	Vel.z -= pModel->AirVel.z;				//Velocity of air ahead of prop
	
	FP PropAirVel = BladeFract * (PropSpeed - PropSwirl) * BladeRadius;
	FP InflowAng = CalcAngle (PropAirVel, PropVel);

//Automatic prop control for AI aircraft
	if((!Save_Data.flightdifficulty [FD_PROPPITCH]) || (ControlledAC != Persons2::PlayerSeenAC))
	{
		switch(PropType)
		{
			case PT_FIXED:
				break;

			case PT_2PITCH:
				if(EngRPM > 1.15 * Rpm100)
					PropSetting = 0;
				if(EngRPM < 0.7 * Rpm100)
					PropSetting = 1;
				break;

			case PT_VARIABLE:
				PropSetting = 1.0 - 1.15 * ControlledAC->vel_ / ControlledAC->classtype->maxvel;
				MODMAXMIN(PropSetting, 0.01, 1);
				break;

			case PT_CONSTSPEED:
				if(ThrottleSetting <= 75)
					PropSetting = 0;
				else
					PropSetting = (ThrottleSetting - 75.0) / 25.0;
//DEADCODE CSB 31/01/00 				PropSetting = FP(ThrottleSetting) * 0.01;
//DEADCODE CSB 31/01/00 				PropSetting = PropSetting * PropSetting * PropSetting;
				break;
		}
	}

	switch(PropType)
	{
		case PT_FIXED:
		{
			PropInc = PropMaxPitch;
			break;
		}
		case PT_2PITCH:
		{
			FP DesiredInc = PropMaxPitch;
			if(PropSetting > 0.5)
				DesiredInc = PropMinPitch;
			if(DesiredInc > PropInc)
			{
				PropInc += 0.002 * MODEL_ENGINE_DT;					//AMM 24Nov99
				if(PropInc > DesiredInc) PropInc = DesiredInc;
			}
			if(DesiredInc < PropInc)
			{
				PropInc -= 0.002 * MODEL_ENGINE_DT;					//AMM 24Nov99
				if(PropInc < DesiredInc) PropInc = DesiredInc;
			}
			break;
		}
		case PT_VARIABLE:
		{
			FP DesiredInc = PropMaxPitch;
			if(PropSetting > 0)
			{
				FP Ratio = 0.5 * (PropSetting + 1.0);
				DesiredInc = PropMinPitch * Ratio + PropMaxPitch * (1 - Ratio);
			}

			if(DesiredInc > PropInc)
			{
				PropInc += 0.002 * MODEL_ENGINE_DT;					//AMM 24Nov99
				if(PropInc > DesiredInc) PropInc = DesiredInc;
			}
			if(DesiredInc < PropInc)
			{
				PropInc -= 0.002 * MODEL_ENGINE_DT;					//AMM 24Nov99
				if(PropInc < DesiredInc) PropInc = DesiredInc;
			}
			break;
		}
		case PT_CONSTSPEED:
		{
			FP DesiredRpm = Rpm100 * (0.7 + 0.45 * PropSetting);
			FP PropPitchRate = (EngRPM - DesiredRpm) * 0.00001;
			PropInc += PropPitchRate * MODEL_ENGINE_DT;				//AMM 24Nov99
			break;
		}
	}	

	MODMAXMIN(PropInc, PropMinPitch, PropMaxPitch);

	FP BladeSpeed = FSqrt(PropAirVel * PropAirVel + PropVel * PropVel);
	FP BladeQS  =  0.5 * pModel->AmbDensity * BladeSpeed * BladeArea;
	
//DeadCode AMM 29Jun99 	J = PropVel / ((PropSpeed - PropSwirl) * 0.75 * BladeRadius);	//Only Used for Text Screen

	FP BladeL = 4.53 * (PropInc - InflowAng);
	FP BladeD = 0.005 + (0.071 * BladeL * BladeL);	
	MODMAXMIN(BladeL, -1.0, 1.5);

	BladeL *= BladeQS;
	BladeD *= BladeQS;

	Thrust = BladeL * PropAirVel - BladeD * PropVel;
	Torque = BladeD * PropAirVel + BladeL * PropVel;
	Torque *= BladeRadius * 0.5;	//effective overall moment


//Engine Power Output
	Power100 = pPower100->GetValue (EngRPM / Rpm100);
	Power0   = pPower0->GetValue (EngRPM / Rpm100);

	FP fPower  = 0;
	FP dTorque = 0;

	ComplexEngineProcess(ControlledAC, fDamage, fPower, dTorque);

	const FP MinThrottle = 0.125;
	FP PowerFract = MinThrottle + ThrottleSetting * (1 - MinThrottle) * 0.01;

	PowerFract *= fPower;

	FP oldpower = Power;
	Power = Power0 + ((Power100 - Power0) * PowerFract);
	
	if((oldpower <= 0) && (Power > 0))
		Trans_Obj.LaunchEngineStartup((mobileitem*)ControlledAC, *ControlledAC->currworld);

	if((oldpower > 0) && (Power <= 0) && (ControlledAC == Persons2::PlayerSeenAC))
		_Miles.PlayOnce(FIL_SFX_ENGINE_COUGH,Save_Data.vol.engine);		//RJS 27Sep00

	Power *= pPowerAlt->GetValue(pModel->Pos.y * 0.01);
	Power *= p0;


//#define ENGINE_DATA
#ifdef ENGINE_DATA
//DeadCode CSB 27/10/99	/* TEST CODE CSB 27/10/99 */if(pModel->bACM)
/* TEST CODE CSB 27/10/99 */{
//DEADCODE CSB 11/01/00 /* TEST CODE CSB 29/09/99 */	PrintVar(40, 15, "Gravity  %.3f ", FP(pModel->Inst.I_NormalAcc));
//DEADCODE CSB 11/01/00 /* TEST CODE CSB 29/09/99 */	PrintVar(40, 16, "IAS      %.2f ", FP(pModel->Speed * FSqrt (pModel->AmbDensity / 0.0001225)));
//DEADCODE CSB 11/01/00 /* TEST CODE CSB 29/09/99 */	PrintVar(40, 17, "Vel      %.2f ", FP(ControlledAC->vel_ * 0.0001));
//DEADCODE CSB 11/01/00 /* TEST CODE CSB 29/09/99 */	PrintVar(40, 18, "DesRpm   %.2f ", FP(pModel->ModelPropSetting));
/* TEST CODE CSB 29/09/99 */	PrintVar(20, 15, "Power    %.0f ", FP(Power / 745.7));
/* TEST CODE CSB 29/09/99 */	PrintVar(20, 16, "RPM      %.0f ", FP(EngRPM));
/* TEST CODE CSB 29/09/99 */	PrintVar(20, 17, "Prop Inc %.2f ", FP(Rads2Degs(PropInc)));
/* TEST CODE CSB 29/09/99 */	PrintVar(20, 18, "Vel      %.2f ", FP(-pModel->AirVel.z));
/* TEST CODE CSB 29/09/99 */	PrintVar(20, 19, "PropVel  %.2f ", FP(PropVel));
/* TEST CODE CSB 29/09/99 */	PrintVar(20, 20, "SlipVel  %.2f ", FP(SlipVel));
/* TEST CODE CSB 29/09/99 */	PrintVar(20, 21, "Alpha    %.2f ", FP(Rads2Degs(PropInc - InflowAng)));
/* TEST CODE CSB 29/09/99 */	PrintVar(20, 24, "ROC fpm  %.0f ", FP(pModel->Vel.y * 3.2808 * 60.0));
/* TEST CODE CSB 29/09/99 */	PrintVar(20, 22, "Thrust   %.1f ", FP(Thrust));
/* TEST CODE CSB 29/09/99 */	PrintVar(20, 23, "Eff      %.3f ", FP(Thrust * -pModel->AirVel.z / Power));
/* TEST CODE CSB 27/10/99 */}
#endif


	FP EngTorque = 0;
	if(Speed > 0) 
		EngTorque = Power / Speed;
	
	EngTorque += dTorque;

//Slipstream Conditions
	FP OldSlipRot = SlipRot;
	FP SlipInertia = BladeRadius * BladeRadius * BladeRadius * BladeRadius 
		              * 0.5 * FPIE * PropVel * pModel->AmbDensity;
	if(SlipInertia > 0)
		SlipRot	   = (Torque / SlipInertia + OldSlipRot) * 0.5;
	else
		SlipRot = 0;
	if(SlipRot > PropSpeed) SlipRot = PropSpeed;

	FP OldSlipVel = SlipVel;
	FP PropArea = FPIE * BladeRadius * BladeRadius;
	FP TempSlip = 2 * Thrust / (pModel->AmbDensity * PropArea) + Vel.z * Vel.z;
	if (TempSlip < 0) SlipVel = -Vel.z;
	else 
		SlipVel = sqrt(TempSlip);
	SlipVel = (SlipVel + OldSlipVel) * 0.5;
	PropVel = 0.5 * (0.5 * (Vel.z + SlipVel) + PropVel);

// calc engine speed
	FP EngRotAcc = (EngTorque - Torque * GearRatio) / MoI;

//DeadCode CSB 27/10/99		if (!Save_Data.flightdifficulty [FD_THRUSTPOWERCONTROL])
//DeadCode CSB 27/10/99			EngRotAcc *= 2;												//Fast Spooling

//DEADCODE AMM 24/11/99 	Speed += pModel->MODEL_DT * EngRotAcc;
	Speed += MODEL_ENGINE_DT * EngRotAcc; //AMM 24/11/99


	if(Speed < 0) Speed = 0;
	
//DEADCODE CB 04/11/99 	if (Speed < MinSpeed) Speed = MinSpeed;		
	if (Speed > MaxSpeed) Speed = MaxSpeed;		
				

	Torque	= -Torque * RotateDirection;//(EngTorque - Torque / GearRatio);				//Reacted into Airframe

	if (Save_Data.flightdifficulty [FD_SLIPSTREAMEFFECTS])
	{
		FCRD TempRot;
		CopyVec(pModel->RotVel, TempRot);
		TempRot.z += Speed * RotateDirection;

		moment.x = TempRot.x * PropInertia.x;
		moment.y = TempRot.y * PropInertia.y;
		moment.z = TempRot.z * PropInertia.z;
		
		CPrd(moment, moment, TempRot);
		moment.x *= -1;
		moment.y *= -1;
		moment.z *= -1;
	}
	else 
		NullVec(moment);
}