void ClothoidPath::SetOffset( const CarModel& cm, double k, double t, PathPt* l3, const PathPt* l2, const PathPt* l4 ) { double marg = cm.WIDTH / 2 + 0.02;//1.0;//1.1 double wl = -MN(m_maxL, l3->Wl()) + marg; double wr = MN(m_maxR, l3->Wr()) - marg; double buf = MN(1.5, 100 * fabs(k)); // a = v*v/r; if( k >= 0 )// 0.00001 ) { if( t < wl ) t = wl; else if( t > wr - l3->rBuf - buf ) { if( l3->offs > wr - l3->rBuf - buf ) t = MN(t, l3->offs); else t = wr - l3->rBuf - buf; t = MN(t, wr); } } else //if( k < -0.00001 ) { if( t > wr ) t = wr; else if( t < wl + l3->lBuf + buf ) { if( l3->offs < wl + l3->lBuf + buf ) t = MX(t, l3->offs); else t = wl + l3->lBuf + buf; t = MX(t, wl); } } l3->offs = t; l3->pt = l3->CalcPt(); l3->k = Utils::CalcCurvatureXY(l2->pt, l3->pt, l4->pt); }
int tester() { //description std::vector<std::string> neutrals; std::vector<std::string> ions; neutrals.push_back("N2"); neutrals.push_back("CH4"); neutrals.push_back("C2H"); //ionic system contains neutral system ions = neutrals; ions.push_back("N2+"); Scalar MN(14.008L), MC(12.011), MH(1.008L); Scalar MN2 = 2.L*MN , MCH4 = MC + 4.L*MH, MC2H = 2.L * MC + MH; std::vector<Scalar> Mm; Mm.push_back(MN2); Mm.push_back(MCH4); Mm.push_back(MC2H); //densities std::vector<Scalar> molar_frac; molar_frac.push_back(0.95999L); molar_frac.push_back(0.04000L); molar_frac.push_back(0.00001L); molar_frac.push_back(0.L); Scalar dens_tot(1e12L); //hard sphere radius std::vector<Scalar> hard_sphere_radius; hard_sphere_radius.push_back(2.0675e-8L * 1e-2L); //N2 in cm -> m hard_sphere_radius.push_back(2.3482e-8L * 1e-2L); //CH4 in cm -> m hard_sphere_radius.push_back(0.L); //C2H //zenith angle //not necessary //photon flux //not necessary ////cross-section //not necessary //altitudes Scalar zmin(600.),zmax(1400.),zstep(10.); //binary diffusion Scalar bCN1(1.04e-5 * 1e-4),bCN2(1.76); //cm2 -> m2 Planet::DiffusionType CN_model(Planet::DiffusionType::Wakeham); Scalar bCC1(5.73e16 * 1e-4),bCC2(0.5); //cm2 -> m2 Planet::DiffusionType CC_model(Planet::DiffusionType::Wilson); Scalar bNN1(0.1783 * 1e-4),bNN2(1.81); //cm2 -> m2 Planet::DiffusionType NN_model(Planet::DiffusionType::Massman); /************************ * first level ************************/ //altitude Planet::Altitude<Scalar,std::vector<Scalar> > altitude(zmin,zmax,zstep); //neutrals Antioch::ChemicalMixture<Scalar> neutral_species(neutrals); //ions Antioch::ChemicalMixture<Scalar> ionic_species(ions); //chapman //not needed //binary diffusion Planet::BinaryDiffusion<Scalar> N2N2( Antioch::Species::N2, Antioch::Species::N2 , bNN1, bNN2, NN_model); Planet::BinaryDiffusion<Scalar> N2CH4( Antioch::Species::N2, Antioch::Species::CH4, bCN1, bCN2, CN_model); Planet::BinaryDiffusion<Scalar> CH4CH4( Antioch::Species::CH4, Antioch::Species::CH4, bCC1, bCC2, CC_model); Planet::BinaryDiffusion<Scalar> N2C2H( Antioch::Species::N2, Antioch::Species::C2H); Planet::BinaryDiffusion<Scalar> CH4C2H( Antioch::Species::CH4, Antioch::Species::C2H); std::vector<std::vector<Planet::BinaryDiffusion<Scalar> > > bin_diff_coeff; bin_diff_coeff.resize(2); bin_diff_coeff[0].push_back(N2N2); bin_diff_coeff[0].push_back(N2CH4); bin_diff_coeff[0].push_back(N2C2H); bin_diff_coeff[1].push_back(N2CH4); bin_diff_coeff[1].push_back(CH4CH4); bin_diff_coeff[1].push_back(CH4C2H); /************************ * second level ************************/ //temperature std::vector<Scalar> T0,Tz; read_temperature<Scalar>(T0,Tz,"input/temperature.dat"); std::vector<Scalar> neutral_temperature; linear_interpolation(T0,Tz,altitude.altitudes(),neutral_temperature); Planet::AtmosphericTemperature<Scalar, std::vector<Scalar> > temperature(neutral_temperature, neutral_temperature, altitude); //photon opacity //not needed //reaction sets //not needed /************************ * third level ************************/ //atmospheric mixture Planet::AtmosphericMixture<Scalar,std::vector<Scalar>, std::vector<std::vector<Scalar> > > composition(neutral_species, ionic_species, altitude, temperature); composition.init_composition(molar_frac,dens_tot); composition.set_hard_sphere_radius(hard_sphere_radius); composition.initialize(); //kinetics evaluators //not needed /************************ * fourth level ************************/ //photon evaluator //not needed //molecular diffusion Planet::MolecularDiffusionEvaluator<Scalar,std::vector<Scalar>, std::vector<std::vector<Scalar> > > molecular_diffusion(bin_diff_coeff, composition, altitude, temperature); molecular_diffusion.make_molecular_diffusion(); //eddy diffusion //not needed /************************ * checks ************************/ molar_frac.pop_back();//get the ion outta here Scalar Matm(0.L); for(unsigned int s = 0; s < molar_frac.size(); s++) { Matm += molar_frac[s] * composition.neutral_composition().M(s); } Matm *= 1e-3L; //to kg std::vector<std::vector<Scalar> > densities; calculate_densities(densities, dens_tot, molar_frac, zmin,zmax,zstep, temperature.neutral_temperature(), Mm); //N2, CH4, C2H std::vector<std::vector<Scalar> > Dij; Dij.resize(2); Dij[0].resize(3,0.L); Dij[1].resize(3,0.L); int return_flag(0); for(unsigned int iz = 0; iz < altitude.altitudes().size(); iz++) { Scalar P = pressure(composition.total_density()[iz],temperature.neutral_temperature()[iz]); Scalar T = temperature.neutral_temperature()[iz]; Dij[0][0] = binary_coefficient(T,P,bNN1,bNN2); //N2 N2 Dij[1][1] = binary_coefficient(T,P,bCC1 * Antioch::ant_pow(Planet::Constants::Convention::T_standard<Scalar>(),bCC2 + Scalar(1.L)) * Planet::Constants::Universal::kb<Scalar>() / Planet::Constants::Convention::P_normal<Scalar>(),bCC2 + Scalar(1.L)); //CH4 CH4 Dij[0][1] = binary_coefficient(T,P,bCN1 * Antioch::ant_pow(Planet::Constants::Convention::T_standard<Scalar>(),bCN2),bCN2); //N2 CH4 Dij[0][2] = binary_coefficient(Dij[0][0],Mm[0],Mm[2]); //N2 C2H Dij[1][2] = binary_coefficient(Dij[1][1],Mm[1],Mm[2]); //CH4 C2H Dij[1][0] = Dij[0][1]; //CH4 N2 for(unsigned int s = 0; s < molar_frac.size(); s++) { Scalar tmp(0.L); Scalar M_diff(0.L); for(unsigned int medium = 0; medium < 2; medium++) { if(s == medium)continue; tmp += densities[medium][iz]/Dij[medium][s]; } Scalar Ds = (barometry(zmin,altitude.altitudes()[iz],neutral_temperature[iz],Matm,dens_tot) - densities[s][iz]) / tmp; for(unsigned int j = 0; j < molar_frac.size(); j++) { if(s == j)continue; M_diff += composition.total_density()[iz] * composition.neutral_molar_fraction()[j][iz] * composition.neutral_composition().M(j); } M_diff /= Scalar(molar_frac.size() - 1); Scalar Dtilde = Ds / (Scalar(1.L) - composition.neutral_molar_fraction()[s][iz] * (Scalar(1.L) - composition.neutral_composition().M(s)/M_diff)); return_flag = return_flag || check_test(Dtilde,molecular_diffusion.Dtilde()[s][iz],"D tilde of species at altitude"); } return_flag = return_flag || check_test(Dij[0][0],molecular_diffusion.binary_coefficient(0,0,T,P),"binary molecular coefficient N2 N2 at altitude") || check_test(Dij[0][1],molecular_diffusion.binary_coefficient(0,1,T,P),"binary molecular coefficient N2 CH4 at altitude") || check_test(Dij[0][2],molecular_diffusion.binary_coefficient(0,2,T,P),"binary molecular coefficient N2 C2H at altitude") || check_test(Dij[1][1],molecular_diffusion.binary_coefficient(1,1,T,P),"binary molecular coefficient CH4 CH4 at altitude") || check_test(Dij[1][2],molecular_diffusion.binary_coefficient(1,2,T,P),"binary molecular coefficient CH4 C2H at altitude"); } return return_flag; }
void MyTrack::NewTrack( tTrack* pNewTrack, bool pit, SideMod* pSideMod ) { if( m_pCurTrack != pNewTrack ) { delete [] m_pSegs; m_pSegs = 0; NSEG = 0; } m_pCurTrack = pNewTrack; if( pSideMod ) m_sideMod = *pSideMod; if( m_pSegs == 0 ) { // make new segs ... roughly every NOMINAL_SEG_LEN metres apart. const double NOMINAL_SEG_LEN = 3;//10; NSEG = int(floor(pNewTrack->length / NOMINAL_SEG_LEN)); m_pSegs = new Seg[NSEG]; m_delta = pNewTrack->length / NSEG; // GfOut( " ### NSEG %d\n", NSEG ); tTrackSeg* pseg = pNewTrack->seg; while( pseg->lgfromstart > pNewTrack->length / 2 ) pseg = pseg->next; double tsend = pseg->lgfromstart + pseg->length; // GfOut( " ### tsend %g len %g fromstart %g\n", // tsend, pseg->length, pseg->lgfromstart ); int pitEntry = -1; int pitExit = -1; int pitSide = pNewTrack->pits.side == TR_LFT ? TR_SIDE_LFT : TR_SIDE_RGT; for( int i = 0; i < NSEG; i++ ) { double segDist = i * m_delta; while( segDist >= tsend ) { pseg = pseg->next; // GfOut( " ### segDist %g tsend %g len %g fromstart %g\n", // segDist, tsend, pseg->length, pseg->lgfromstart ); // tsend += pseg->length; tsend = pseg->lgfromstart + pseg->length; } // const double MIN_MU = pseg->surface->kFriction * 0.8; // const double MAX_ROUGH = MX(0.005, pseg->surface->kRoughness * 1.2); // const double MAX_RESIST = MX(0.02, pseg->surface->kRollRes * 1.2); // GfOut( " ### segDist %g tsend %g\n", // segDist, tsend ); // double t = (segDist - pseg->lgfromstart) / pseg->length; // double width = pseg->startWidth + (pseg->endWidth - pseg->startWidth) * t; m_pSegs[i].segDist = segDist; m_pSegs[i].pSeg = pseg; m_pSegs[i].wl = pseg->width / 2; m_pSegs[i].wr = pseg->width / 2; m_pSegs[i].midOffs = 0; if( pitEntry < 0 && (pseg->raceInfo & TR_PITENTRY) ) pitEntry = i; if( (pseg->raceInfo & TR_PITEXIT) ) pitExit = i; } // GfOut( "pit entry %d pit exit %d \n", pitEntry, pitExit ); /* if( pNewTrack->pits.pitStart ) { GfOut( "pit entry %d pit exit %d \n", pNewTrack->pits.pitEntry->id, pNewTrack->pits.pitExit->id ); GfOut( "pit start %d pit end %d \n", pNewTrack->pits.pitStart->id, pNewTrack->pits.pitEnd->id ); GfOut( "pit side %d pit len %g\n", pitSide, pNewTrack->pits.len ); pseg = pNewTrack->pits.pitEntry->prev; do { pseg = pseg->next; GfOut( " %7.2fm %4d %5.1fm %4.1fm..%4.1fm", pseg->lgfromstart, pseg->id, pseg->length, pseg->startWidth, pseg->endWidth ); tTrackSeg* pSide = pseg->side[pitSide]; while( pSide ) { GfOut( " %4.1f-%4.1fm %d %d %3x", pSide->startWidth, pSide->endWidth, pSide->type2, pSide->style, pSide->raceInfo ); pSide = pSide->side[pitSide]; } GfOut( "\n" ); } while( pseg != pNewTrack->pits.pitExit ); } */ {for( int i = 0; i < NSEG; i++ ) { pseg = m_pSegs[i].pSeg; // GfOut( " ### segDist %g tsend %g\n", // segDist, tsend ); double segDist = m_pSegs[i].segDist; double t = (segDist - pseg->lgfromstart) / pseg->length; bool inPit = ((pitEntry < pitExit && pitEntry <= i && i <= pitExit) || (pitEntry > pitExit && (i <= pitExit || i >= pitEntry))); const double MIN_MU = pseg->surface->kFriction * 0.8; const double MAX_ROUGH = MX(0.005, pseg->surface->kRoughness * 1.2); const double MAX_RESIST = MX(0.02, pseg->surface->kRollRes * 1.2); const double SLOPE = pseg->Kzw; if (0) // Disabled using the sides for now {for( int s = 0; s < 2; s++ ) { tTrackSeg* pSide = pseg->side[s]; if( pSide == 0 ) continue; double extraW = 0; bool done = false; while( !done && pSide ) { double w = pSide->startWidth + (pSide->endWidth - pSide->startWidth) * t; // w = MX(0, w - 0.5); // w = MN(w, 1.0); if( pSide->style == TR_CURB ) { if( s == m_sideMod.side && i >= m_sideMod.start && i <= m_sideMod.end ) ; else { // always keep 1 wheel on main track. w = MN(w, 1.5); done = true; if( ((s == TR_SIDE_LFT && pseg->type == TR_RGT) || (s == TR_SIDE_RGT && pseg->type == TR_LFT)) && pSide->surface->kFriction < pseg->surface->kFriction ) // keep a wheel on the good stuff. w = 0;//MN(w, 1.5); // don't go too far up raised curbs (max 2cm). if( pSide->height > 0 ) w = MN(w, 0.6); // w = MN(0.05 * pSide->width / pSide->height, 1.5); // if( pSide->surface->kFriction < MIN_MU ) // w = 0; } } else if( pSide->style == TR_PLAN ) { if( (inPit && pitSide == s) || (pSide->raceInfo & (TR_SPEEDLIMIT | TR_PITLANE)) ) { w = 0; done = true; } if( s == m_sideMod.side && i >= m_sideMod.start && i <= m_sideMod.end ) { if( w > 0.5 ) { w = 0.5; done = true; } } else if( pSide->surface->kFriction < MIN_MU || pSide->surface->kRoughness > MAX_ROUGH || pSide->surface->kRollRes > MAX_RESIST || fabs(pSide->Kzw - SLOPE) > 0.005 ) { // bool inner = // (s == TR_SIDE_LFT && pseg->type == TR_LFT) || // (s == TR_SIDE_RGT && pseg->type == TR_RGT); w = 0;//inner ? MN(w, 0.5) : 0; done = true; } if( ((s == TR_SIDE_LFT && pseg->type == TR_RGT) || (s == TR_SIDE_RGT && pseg->type == TR_LFT)) && pSide->surface->kFriction < pseg->surface->kFriction ) { // keep a wheel on the good stuff. w = 0;//MN(w, 1.5); done = true; } } else { // wall of some sort. // w = 0; w = pSide->style == TR_WALL ? -0.5 : 0; // pSide->style == TR_FENCE ? -0.1 : 0; done = true; } extraW += w; // if( pSide->style != TR_PLAN || w <= 0 ) // done = true; pSide = pSide->side[s]; } // extraW = MX(0, extraW - 0.1); if( s == TR_SIDE_LFT ) m_pSegs[i].wl += extraW; else m_pSegs[i].wr += extraW; }} // GfOut( "\n" ); // m_pSegs[i].wl = 1; // m_pSegs[i].wr = 1; // m_pSegs[i].wl *= 0.6; // m_pSegs[i].wr *= 0.6; CalcPtAndNormal( pseg, segDist - pseg->lgfromstart, // m_pSegs[i].wl + m_pSegs[i].wr, m_pSegs[i].t, m_pSegs[i].pt, m_pSegs[i].norm ); // GfOut( "%4d p(%7.2f, %7.2f, %7.2f) n(%7.4f, %7.4f, %7.4f)\n", // i, m_pSegs[i].pt.x, m_pSegs[i].pt.y, m_pSegs[i].pt.z, // m_pSegs[i].norm.x, m_pSegs[i].norm.y, m_pSegs[i].norm.z ); }} /* {for( int i = 0; i < NSEG; i++ ) { int in = (i + 1) % NSEG; if( m_pSegs[i].wl > m_pSegs[in].wl ) { if( m_pSegs[i].wl > m_pSegs[in].wl - 0.25 ) m_pSegs[i].wl = m_pSegs[in].wl - 1; else m_pSegs[i].wl = m_pSegs[in].wl; } if( m_pSegs[i].wr > m_pSegs[in].wr ) { if( m_pSegs[i].wr > m_pSegs[in].wr - 0.25 ) m_pSegs[i].wr = m_pSegs[in].wr - 1; else m_pSegs[i].wr = m_pSegs[in].wr; } }} {for( int i = NSEG - 1; i >= 0; i-- ) { int ip = (i - 1 + NSEG) % NSEG; if( m_pSegs[i].wl > m_pSegs[ip].wl ) m_pSegs[i].wl = m_pSegs[ip].wl; if( m_pSegs[i].wr > m_pSegs[ip].wr ) m_pSegs[i].wr = m_pSegs[ip].wr; }} */ } }
void Opponent::ProcessMyCar(const Situation* s, const TeamInfo* pTeamInfo, const CarElt* myCar, const Sit& mySit, const TDriver& me, double myMaxAccX, int idx) { CarElt* oCar = m_path.GetCar(); m_info.flags = 0; if( oCar == myCar || (oCar->_state & RM_CAR_STATE_NO_SIMU)) { return; } const Sit& oSit = m_info.sit; m_info.flags |= oSit.rdPY < 0 ? F_LEFT : F_RIGHT; m_info.flags |= oSit.offs < 0 ? F_TRK_LEFT : F_TRK_RIGHT; if( fabs(oSit.tYaw) > 45 * PI / 180 || oSit.spd < 15 ) { m_info.flags |= F_DANGEROUS; m_info.dangerousLatchTime = 2.0; } else { m_info.dangerousLatchTime -= s->deltaTime; if( m_info.dangerousLatchTime <= 0 ) { m_info.flags &= ~F_DANGEROUS; m_info.dangerousLatchTime = 0; } } double distAhead = MX(20, mySit.spd * mySit.spd / 30); if( (m_info.flags & F_DANGEROUS) == 0 ) distAhead = MN(MX(40, distAhead), 80); if( pTeamInfo->IsTeamMate(myCar, oCar) ) { m_info.flags |= F_TEAMMATE; m_info.tmDamage = oCar->_dammage; } if( oSit.relPos < distAhead && oSit.relPos > -25 ) { double oVX = mySit.spd + oSit.rdVX; m_info.flags |= F_TRAFFIC; if( oSit.rdPX > oSit.minDX ) { m_info.flags |= F_AHEAD | F_FRONT; Quadratic myPar(0, 0, 0, mySit.ragAY); Quadratic oPar(0, oSit.rdPY, oSit.rdVY, oSit.ragAY); Quadratic relPar = oPar - myPar; { // time to catch up at present speeds... double acc = oSit.ragAX;// - (myCar->_accel_x + 3); Quadratic q(acc / 2, oSit.rdVX, oSit.rdPX - oSit.minDX); double t; if( q.SmallestNonNegativeRoot(t) ) { double catchY = relPar.CalcY(t); m_info.flags |= F_CATCHING; m_info.catchTime = t; m_info.catchY = catchY; m_info.catchSpd = oSit.rdPX < 15 ? oVX : oSit.tVX; double hisSpd = oSit.ragVX + oSit.ragAX * t; double decel = (mySit.ragVX - hisSpd) / t; m_info.catchDecel = MX(0, decel); if( fabs(catchY) < oSit.minDY ) { m_info.flags |= F_COLLIDE; if( oSit.rdPX < oSit.minDX + 0.15 ) m_info.catchDecel = 999; } else { // see if we hit on the side while passing. q.Setup( acc / 2, oSit.rdVX, oSit.rdPX + oSit.minDX );// + m_info.minDX ); if( q.SmallestNonNegativeRoot(t) ) { catchY = relPar.CalcY(t); if( fabs(catchY) < oSit.minDY || catchY * oSit.rdPY < 0 ) { m_info.flags |= F_COLLIDE; m_info.catchY = SGN(m_info.catchY) * (oSit.minDY - 0.1); } } } } q.Setup( oSit.ragAX - myMaxAccX, oSit.ragVX - mySit.ragVX, oSit.rdPX - oSit.minDX - 0.2 ); if( q.SmallestNonNegativeRoot(t)) { double catchY = relPar.CalcY(t); m_info.flags |= F_CATCHING_ACC; m_info.catchAccTime = t; m_info.catchAccY = catchY; m_info.catchAccSpd = oVX; } } if( myCar->_laps > oCar->_laps ) { m_info.flags |= F_BEING_LAPPED; } } else { if( oSit.rdPX < -oSit.minDX ) // behind { m_info.flags |= F_BEHIND | F_REAR; if( oSit.rdVX < 0 ) { m_info.flags |= F_CATCHING; m_info.catchTime = (oSit.rdPX + oSit.minDX) / oSit.rdVX; m_info.catchY = oSit.rdPY; m_info.catchSpd = oVX; } } else // to side { m_info.flags |= F_TO_SIDE; m_info.flags |= oSit.rdPX > 0 ? F_FRONT : F_REAR; double aheadDist = oSit.minDX * 0.5;//0.33; if( fabs(oSit.rdPY) < oSit.minDY ) { // colliding now. m_info.flags |= F_COLLIDE; m_info.catchTime = 0; m_info.catchY = oSit.rdPY; m_info.catchSpd = oSit.rdPX > aheadDist ? oVX - 3 : 200; m_info.catchDecel = 999; } else if( oSit.rdPX > 0 && oSit.rdPY * oSit.rdVY < 0 ) { // side collision in t seconds? double t = (fabs(oSit.rdPY) - oSit.minDY) / fabs(oSit.rdVY); double collX = oSit.rdPX + oSit.rdVX * t; if( collX > aheadDist && collX < oSit.minDX ) { double relSpd = (oSit.minDX - oSit.rdPX) / t; m_info.flags |= F_COLLIDE; m_info.catchTime = t; m_info.catchY = SGN(oSit.rdPY) * (oSit.minDY - 0.1); m_info.catchSpd = oVX - 3; m_info.catchDecel = (mySit.spd - (oVX - relSpd)) / t; } } } if( (m_info.flags & (F_REAR | F_TO_SIDE)) && myCar->_laps < oCar->_laps ) { m_info.flags |= F_LAPPER; } } if( 0 < oSit.rdPX && oSit.rdPX < oSit.minDX + 2 && fabs(oSit.rdPY) < oSit.minDY + 2 ) { m_info.flags |= F_CLOSE; } } else if( oSit.relPos < 0 ) { m_info.flags |= F_BEHIND | F_REAR; } const double timeLimit = 4; const double closeDist = 10; m_info.newCatchSpd = oSit.tVX - mySit.tVX; m_info.newCatching = false; if( oSit.relPos > oSit.minDX ) { bool oDangerous = (m_info.flags & F_DANGEROUS) != 0; if( m_info.newCatchSpd < 0 ) { double t1 = -(oSit.relPos - oSit.minDX) / m_info.newCatchSpd; double t2 = -(oSit.relPos + oSit.minDX) / m_info.newCatchSpd; m_info.newCatching = t1 <= timeLimit || oDangerous || oSit.relPos - oSit.minDX < closeDist; m_info.newCatchTime = t1; m_info.newAheadTime = t2; } } else if( oSit.relPos >= -oSit.minDX ) { m_info.newCatching = true; m_info.newCatchTime = 0; m_info.newAheadTime = 0; } if( m_info.newCatching ) { double pos = oCar->_distFromStartLine; double myPos = myCar->_distFromStartLine; double offs = -oCar->_trkPos.toMiddle; double w = m_path.GetTrack()->GetWidth() * 0.5 - 1; double catPos = pos + oSit.tVX * m_info.newCatchTime; double catOffs = offs + oSit.tVY * m_info.newCatchTime; catOffs = MX(-w, MN(catOffs, w)); double ahdPos = pos + oSit.tVX * m_info.newAheadTime; double ahdOffs = offs + oSit.tVY * m_info.newAheadTime; ahdOffs = MX(-w, MN(ahdOffs, w)); double midPos = (catPos + ahdPos) * 0.5; m_info.newMidPos = midPos; PtInfo pi; me.GetPtInfo( TDriver::PATH_NORMAL, midPos * 0.5, pi ); m_info.newBestOffset = pi.offs; double L = catOffs - oSit.minDY - 1.0; double R = catOffs + oSit.minDY + 1.0; // TODO: change this to be the predicted position... double toL, toR; me.GetPathToLeftAndRight( oCar, toL, toR ); m_info.newPiL.isSpace = L > offs - toL; m_info.newPiL.goodPath = false; m_info.newPiL.myOffset = 0; if( m_info.newPiL.isSpace ) { m_info.newPiL.offset = L; m_info.newPiL.mySpeed = me.CalcBestSpeed(midPos, MN(L, pi.offs)); m_info.newPiL.goodPath = m_info.newPiL.mySpeed > oSit.spd; { double u, v; me.CalcBestPathUV(midPos, L, u, v); m_info.newPiL.bestU = u; m_info.newPiL.bestV = v; m_info.newPiL.myOffset = me.CalcPathOffset(myPos, u, v); } } m_info.newPiR.isSpace = R < offs + toR; m_info.newPiR.goodPath = false; m_info.newPiR.myOffset = 0; if( m_info.newPiR.isSpace ) { m_info.newPiR.offset = R; m_info.newPiR.mySpeed = me.CalcBestSpeed(midPos, MX(R, pi.offs)); m_info.newPiR.goodPath = m_info.newPiR.mySpeed > oSit.spd; { double u, v; me.CalcBestPathUV(midPos, R, u, v); m_info.newPiR.bestU = u; m_info.newPiR.bestV = v; m_info.newPiR.myOffset = me.CalcPathOffset(myPos, u, v); } } } }
int test() { std::vector<std::string> neutrals; std::vector<std::string> ions; neutrals.push_back("N2"); neutrals.push_back("CH4"); ions.push_back("N2+"); ions.push_back("e"); Scalar chi(100.L); std::vector<Scalar> lambda_ref,phy1AU,phy_on_top; std::ifstream flux_1AU("./input/hv_SSI.dat"); std::string line; getline(flux_1AU,line); while(!flux_1AU.eof()) { Scalar wv,ir,dirr; flux_1AU >> wv >> ir >> dirr; if(!lambda_ref.empty() && wv == lambda_ref.back())continue; lambda_ref.push_back(wv);//nm phy1AU.push_back(ir);//W/m2/nm phy_on_top.push_back(ir/std::pow(Planet::Constants::Saturn::d_Sun<Scalar>(),2)); } flux_1AU.close(); Planet::Chapman<Scalar> chapman(chi); Planet::PhotonFlux<Scalar,std::vector<Scalar>, std::vector<std::vector<Scalar> > > photon(chapman); photon.set_photon_flux_top_atmosphere(lambda_ref,phy1AU,Planet::Constants::Saturn::d_Sun<Scalar>()); std::vector<Scalar> molar_frac = {0.96,0.04,0.,0.}; Scalar dens_tot(1e12); Planet::Atmosphere<Scalar, std::vector<Scalar>, std::vector<std::vector<Scalar> > > atm(neutrals,ions,photon); atm.make_altitude_grid(600.,1400.,10.); std::ifstream temp("input/temperature.dat"); std::vector<Scalar> T0,Tz; getline(temp,line); while(!temp.eof()) { Scalar t,tz,dt,dtz; temp >> t >> tz >> dt >> dtz; T0.push_back(t); Tz.push_back(tz); } temp.close(); atm.set_temperature(T0,Tz); std::vector<Scalar> T = atm.temperature_top_to_bottom(); std::vector<std::vector<Scalar> > MatrixTotalDensity; std::vector<Scalar> tot_dens = atm.total_density_top_to_bottom(); std::vector<Scalar> lambda_N2,sigma_N2; std::vector<std::vector<Scalar> > sigma_rate_N2; sigma_rate_N2.resize(3); std::ifstream sig_N2("./input/N2_hv_cross-sections.dat"); std::ifstream sig_CH4("./input/CH4_hv_cross-sections.dat"); getline(sig_N2,line); getline(sig_CH4,line); while(!sig_N2.eof()) { Scalar wv,sigt,sig1,sig2,sig3; sig_N2 >> wv >> sigt >> sig1 >> sig2 >> sig3; lambda_N2.push_back(wv/10.);//A -> nm sigma_N2.push_back(sigt*10.);//cm-2/A -> cm-2/nm sigma_rate_N2[0].push_back(sig1*10.); sigma_rate_N2[1].push_back(sig2*10.); sigma_rate_N2[2].push_back(sig3*10.); } sig_N2.close(); atm.add_photoabsorption("N2",lambda_N2,sigma_N2); std::vector<Scalar> lambda_CH4,sigma_CH4; std::vector<std::vector<Scalar> > sigma_rate_CH4; sigma_rate_CH4.resize(9); while(!sig_CH4.eof()) { Scalar wv,sigt,sig1,sig2,sig3,sig4,sig5,sig6,sig7,sig8,sig9; sig_CH4 >> wv >> sigt >> sig1 >> sig2 >> sig3 >> sig4 >> sig5 >> sig6 >> sig7 >> sig8 >> sig9; lambda_CH4.push_back(wv/10.);//A -> nm sigma_CH4.push_back(sigt*10.);//cm-2/A -> cm-2/nm sigma_rate_CH4[0].push_back(sig1*10.); sigma_rate_CH4[1].push_back(sig2*10.); sigma_rate_CH4[2].push_back(sig3*10.); sigma_rate_CH4[3].push_back(sig4*10.); sigma_rate_CH4[4].push_back(sig5*10.); sigma_rate_CH4[5].push_back(sig6*10.); sigma_rate_CH4[6].push_back(sig7*10.); sigma_rate_CH4[7].push_back(sig8*10.); sigma_rate_CH4[8].push_back(sig9*10.); } sig_CH4.close(); atm.add_photoabsorption("CH4",lambda_CH4,sigma_CH4); atm.init_composition(molar_frac,dens_tot); int return_flag(0); //Phy at top std::vector<Scalar> phy_top; phy_top.resize(lambda_ref.size(),0.L); for(unsigned int il = 0; il < lambda_ref.size(); il++) { phy_top[il] = phy1AU[il]/(Planet::Constants::Saturn::d_Sun<Scalar>() * Planet::Constants::Saturn::d_Sun<Scalar>()); if(check_test(phy_top[il],photon.phy_at_top()[il],"Photon flux at top"))return_flag = 1; } std::ofstream out("phy_z.dat"); std::ofstream out_the("phy_z_the.dat"); out_the << "z N_N N+_N N2+ sCH2_H2 CH3_H CH2_H_H CH4+ CH3+_H CH2+_H2 CH+_H2_H H+_CH3 CH_H2_H" << std::endl; std::vector<Scalar> lamb = atm.hv_flux().lambda(); std::vector<Scalar> sum_over_neutral; sum_over_neutral.resize(2,0.L); std::vector<Scalar> tau_theo; std::vector<Scalar> rate_N2,rate_CH4; rate_N2.resize(3); rate_CH4.resize(9); Scalar MN(14.008L), MC(12.011), MH(1.008L); Scalar MN2 = 2.L*MN , MCH4 = MC + 4.L*MH; unsigned int ialt(0); for(Scalar z = 1400.; z >= 600.; z -= 10.) { Scalar M_the = molar_frac[0] * MN2 + molar_frac[1] * MCH4; Scalar n_tot_the = dens_tot * std::exp(-(z - 600.) / ( (z + Planet::Constants::Titan::radius<Scalar>()) * (600. + Planet::Constants::Titan::radius<Scalar>()) * 1e3L * //to m ( (Planet::Constants::Universal::kb<Scalar>() * Antioch::Constants::Avogadro<Scalar>() * T[ialt]) / (Planet::Constants::Universal::G<Scalar>() * Planet::Constants::Titan::mass<Scalar>() * M_the * 1e-3L) //to kg/mol ) )); tau_theo.clear(); tau_theo.resize(lambda_ref.size(),0.L); for(unsigned int i = 0; i < 2; i++) { sum_over_neutral[i] += molar_frac[i] * n_tot_the; for(unsigned int il = 0; il < lambda_ref.size(); il++) { tau_theo[il] += sum_over_neutral[i] * atm.photon_sigma(i).y_on_custom()[il]; //filtering } } std::vector<Scalar> tau_cal = photon.tau(z,sum_over_neutral); for(unsigned int il = 0; il < lambda_ref.size(); il++) { tau_theo[il] *= chapman.chapman(atm.a(z)); if(check_test(tau_theo[il],tau_cal[il],"tau at altitude z"))return_flag = 1; } for(unsigned int ir = 0; ir < 3; ir++) { rate_N2[ir] = 0.L; for(unsigned int il = 0; il < lamb.size(); il++) { rate_N2[ir] += sigma_rate_N2[ir][il] * phy_on_top[il] * std::exp(-tau_theo[il]); } } for(unsigned int ir = 0; ir < 9; ir++) { rate_CH4[ir] = 0.L; for(unsigned int il = 0; il < lamb.size(); il++) { rate_CH4[ir] += sigma_rate_CH4[ir][il] * phy_on_top[il] * std::exp(-tau_theo[il]); } } std::vector<Scalar> phy_flux = atm.hv_flux().phy(z); for(unsigned int il = 0; il < phy_flux.size(); il++) { if(check_test(phy_on_top[il] * std::exp(-tau_theo[il]),phy_flux[il],"phy at altitude z and lambda"))return_flag = 1; out << lamb[il] << " " << phy_flux[il] << std::endl; } out_the << z << " "; for(unsigned int ir = 0; ir < 3; ir++) { out_the << rate_N2[ir] << " "; } for(unsigned int ir = 0; ir < 9; ir++) { out_the << rate_CH4[ir] << " "; } out_the << std::endl; out << std::endl; ialt++; } out.close(); out_the.close(); return return_flag; }
//deep node string and pattern should parsed void run_deep_lv(LV_ENTITY *lv, DI *di, char *pattern, size_t pattern_len, int max_error) { int mark_no_vis = -1; //lp should inside [INT] range if (pattern_len > INT_MAX) { fprintf(stderr, "len of pattern [%lu] out of range try small len\n", pattern_len); return; } int lp = (int)pattern_len; if (init_lv(lv, (di->n_l), max_error, lp, (di->the_deep), mark_no_vis) == -1) { fprintf(stderr, "run lv error\n"); return; } int find_d = 0; int global_reach = -2; int the_b = 0, the_e = 0, the_d = 0; int the_ek = the_e + 1, the_dk = the_d+lp+1; // init the LV[0][0][0] = 0 // (lv->LV)[the_b][the_ek][the_dk] = 0; //tmp var deep_node *bn; int ek, dk, best, last_best; //len of text , text begin in deep code int lt; size_t tbegin; char *p, *pb, *t, *pend; int extend_len = 0; int the_deep = 0, base_deep, cur_deep, action, next_action; for (int e = 0; e<=max_error && find_d==0; ++e) { //mark_bit mean if lv == no vis //mark_bit = 1 lv can succeed from d+1 or == -d then extend 0 error //mark_bit = 2 lv can succeed then extend 1 error for (int dp = 0; dp <= the_deep; ++dp) { for (int i=0; i<lp; ++i) { if (dp==0) if (i<=e) (lv->mark_bit)[dp][i] = e-i+1; else (lv->mark_bit)[dp][i] = 0; else (lv->mark_bit)[dp][i] = 0; } } base_deep = -1; debug_print("\ne: %d\n", e); if ((di->n_l) > 0) // for (int b = 0; b<(di->n_l) && ((di->all_node[b]).deep <= the_deep); ++b) for (int b = 0; b<(di->n_l) && ((di->all_node[b]).deep <= the_deep) && find_d==0; ++b) { // if ((di->all_node[b]).deep == cur_deep) continue; bn = &(di->all_node[b]); lt = (int)MN(bn->len, INT_MAX); tbegin = bn->begin; cur_deep = bn->deep; debug_print("$ deep: %d the node : %d len: %d \n", cur_deep, b, lt); // printf("$ deep: %d the node : %d len: %d \n", cur_deep, b, lt); for (size_t i=0; i<lp; ++i) debug_print((i==lp-1) ? "%d\n":"%d-", (lv->mark_bit)[cur_deep][i]); //if the block have no element,just succeed the mark value // if (lt == 0 && cur_deep+1 < (di->the_deep)) // { // if (the_deep < cur_deep+1) // { // the_deep = cur_deep+1; // for (size_t i=0; i<lp; ++i) (lv->mark_bit)[cur_deep+1][i] = 0; // debug_print(" ** undate deep: cur %d the_deep %d\n", cur_deep, the_deep); // } // for (size_t i=0; i<lp; ++i) // (lv->mark_bit)[cur_deep+1][i] = MX((lv->mark_bit)[cur_deep+1][i], (lv->mark_bit)[cur_deep][i]); // // if ((lv->mark_bit)[cur_deep+1][best] > 1) // // { // // if (best+1 > 0 && best+1<lp) (lv->mark_bit)[cur_deep+1][best+1] = MX((lv->mark_bit)[cur_deep+1][best+1], 1); // // if (best-1 > 0 && best-1<lp) (lv->mark_bit)[cur_deep+1][best-1] = MX((lv->mark_bit)[cur_deep+1][best-1], 1); // // } // for (size_t i=0; i<lp; ++i) debug_print((i==lp-1) ? "%d\n":"%d-", (lv->mark_bit)[cur_deep+1][i]); // } for (int d = -lp+1, ek; d<(int)(MN( e+1, MN(lt+1, lp))); ++d) { ek = e + 1; dk = d + lp + 1; // if ((lv->Far_reach)[b][dk]==1) continue; if ((lv->Far_reach)[cur_deep][lt-d]==1) continue; best = MX((lv->LV)[b][ek-1][dk], (lv->LV)[b][ek][dk]); // debug_print("d: %d : best %d\n", d, best); // best =(lv->LV)[b][e ][dk]; if (best != mark_no_vis) action = 2; else if (d <= 0) { action = (lv->mark_bit)[cur_deep][-d]; if (action > 0) { // printf("-- %d %d %d\n", (lv->LV)[b][ek-1][dk+1], (lv->LV)[b][ek-1][dk-1], best); if ((lv->LV)[b][ek-1][dk+1] != mark_no_vis) best = MX(best, (lv->LV)[b][ek-1][dk+1] + 1); if ((lv->LV)[b][ek-1][dk-1] != mark_no_vis) best = MX(best, (lv->LV)[b][ek-1][dk-1]); best = MX(-d, best); } } else if ((lv->LV)[b][ek-1][dk-1] != mark_no_vis) action = 2; else action = 0; if (best == mark_no_vis && action == 0) continue; debug_print("action: %d\n", action); debug_print("d: %d : best %d\n", d, best); next_action = 0; //error 0 extend //only can extend from left side if (action >= 1 && (lv->LV)[b][ek-1][dk] == mark_no_vis && d<=0) { pb = pattern + best; p = pattern + best; t = di->deep_s + tbegin + best + d; last_best = best; extend_len = MN(lt-MX(0, d), lp-MX(0, -d)); pend = pattern + MX(0, -d) + extend_len; // debug_print("extend_len, %d\n", extend_len); // printf("1t: "); // print_bit4((*p)); // printf("-"); // print_bit4((*t)); if ( p < pend && ((*p) & (*t))) { while (p < pend) { uint64_t x = (~ *((uint64_t*) t) ) & *((uint64_t*) p); if (x) { unsigned long zeroes; CountTrailingZeroes(x, zeroes); zeroes >>= 3; debug_print("* %lu: ", zeroes); best = MN((int)(p - pb) + (int)zeroes + last_best, MX(0, -d) + extend_len); break; } p += 8; t += 8; if (p >= pend) { debug_print("@ %d: ", extend_len); best = MX(0, -d) + extend_len; break; } } } if (best != last_best) { (lv->LV)[b][ek][dk] = best; } // else // { // if (d <= 0 && best == -d) // best = mark_no_vis; // } if (best + d >= lt) { next_action = action; } } debug_print("--d: %d : best %d\n", d, best); //error 1 extend if (action >= 2 && next_action == 0) { if (best != mark_no_vis) best = best + 1; if ((lv->LV)[b][ek-1][dk] != mark_no_vis) best = MX(best, (lv->LV)[b][ek-1][dk] + 1); if ((lv->LV)[b][ek-1][dk+1] != mark_no_vis) best = MX(best, (lv->LV)[b][ek-1][dk+1] + 1); if ((lv->LV)[b][ek-1][dk-1] != mark_no_vis) best = MX(best, (lv->LV)[b][ek-1][dk-1]); if (best == (lv->LV)[b][ek-1][dk] + 1 && best + d > lt) { next_action = 2; } if (next_action == 0 && best == (lv->LV)[b][ek-1][dk+1] + 1 && best + d > lt) { next_action = 1; } if (next_action == 0 && best == (lv->LV)[b][ek-1][dk-1] && best + d > lt) { next_action = 1; } debug_print("d: %d : best %d\n", d, best); pb = pattern + best; p = pattern + best; t = di->deep_s + tbegin + best + d; last_best = best; extend_len = MN(lt-MX(0, d), lp-MX(0, -d)); // debug_print("extend_len, %d\n", extend_len); pend = pattern + MX(0, -d) + extend_len; // printf("t: "); // print_bit4((*p)); // printf("-"); // print_bit4((*t)); if ( p < pend && ((*p) & (*t))) { // printf("try match"); // print_bit4((*p)); // printf("-"); // print_bit4((*t)); // printf("\n"); while (p < pend) { uint64_t x = (~ *((uint64_t*) t) ) & *((uint64_t*) p); if (x) { unsigned long zeroes; CountTrailingZeroes(x, zeroes); zeroes >>= 3; best = MN((int)(p - pb) + (int)zeroes + last_best, MX(0, -d) + extend_len); break; } p += 8; t += 8; if (p >= pend) { best = MX(0, -d) + extend_len; break; } } } if (best != last_best) { (lv->LV)[b][ek][dk] = best; } if (next_action == 0 && best + d == lt) { next_action = 1; } if (next_action == 0 && best + d > lt) { next_action = 2; } } if (best == mark_no_vis) continue; best = MN(best, lt - d); debug_print("d: %d : best %d\n", d, best); // if (best <= (lv->LV)[b][ek-1][dk]) if (best+d >= lt) { // (lv->Far_reach)[b][dk] = 1; (lv->Far_reach)[cur_deep][lt-d] = 1; debug_print("Far reach at b: %d deep: %d d: %d lv: %d\n", b, cur_deep, d, best); } // if (best > global_reach || (best == global_reach && d > the_d) ) if (best > global_reach) { global_reach = best; the_b = b; the_e = e; the_d = d; } (lv->LV)[b][ek][dk] = best; debug_print("-> b: %d e:%d d:%d lV:%d\n", b, e, d, best); if (best + d >= lt && cur_deep+1 < (di->the_deep)) { if (the_deep < cur_deep+1) { the_deep = cur_deep+1; for (size_t i=0; i<lp; ++i) (lv->mark_bit)[cur_deep+1][i] = 0; debug_print(" ** undate deep: cur %d the_deep %d\n", cur_deep, the_deep); } (lv->mark_bit)[cur_deep+1][best] = MX((lv->mark_bit)[cur_deep+1][best], next_action); // if ((lv->mark_bit)[cur_deep+1][best] > 1) // { // if (best+1 > 0 && best+1<lp) (lv->mark_bit)[cur_deep+1][best+1] = MX((lv->mark_bit)[cur_deep+1][best+1], 1); // if (best-1 > 0 && best-1<lp) (lv->mark_bit)[cur_deep+1][best-1] = MX((lv->mark_bit)[cur_deep+1][best-1], 1); // } for (size_t i=0; i<lp; ++i) debug_print((i==lp-1) ? "%d\n":"%d-", (lv->mark_bit)[cur_deep+1][i]); } if (best == lp) { the_b = b; the_e = e; the_d = d; if (find_d==1) break; find_d = 1; // printf(" *** find lv: in error: %d b: %d deep: %d d: %d\n", e, b, cur_deep, d); // break; } } } }