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 }
//컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴 //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); }