예제 #1
0
파일: BodyRigid.cpp 프로젝트: kollmanj/omd
	BodyRigid::BodyRigid(const char* name, double const &mass, Mat3x3 const &inertia,
		Vect3 const &pos, Quat const &q, Vect3 const &vel, Vect3 const &wl, bool const &fixed) :
	Body(name,pos,q,vel,wl), m_mass(mass), m_inertia(inertia), m_fixed(fixed)
	{
		m_appliedForce = Vect3(0,0,0);
		m_appliedTorque = Vect3(0,0,0);

		/// initialize kanes method .... TODO site the page number this this shows up on
		m_sAhat << 0.,0.,0.,0.,0.,0.;
		m_sFhat <<  0.,0.,0.,0.,0.,0.;
		m_sIhat <<  0,0,0,0,0,0,
					0,0,0,0,0,0,
					0,0,0,0,0,0,
					0,0,0,0,0,0,
					0,0,0,0,0,0,
					0,0,0,0,0,0;

		m_n_alpha_t_k << 0,0,0;
		m_n_a_t_k << 0,0,0;

		// contact stuff
		m_stiff = 0;
		m_damp = 0;
		m_frict = 0;
		m_thresh = 0;
	}
예제 #2
0
vec3_t *G2Exporter_Surface_GetVertNormal(int iSurfaceIndex, int iVertIndex, int iLODIndex)
{
	static vec3_t v3={0};
	memset(v3,0,sizeof(v3));

	if (iLODIndex == giNumLODs-1)
	{
		// q3data surface...
		//
		if (iSurfaceIndex < giNumSurfaces)
		{
			// standard surface...
			//
			md3SurfaceData_t *pSurfaceData = GetMD3SurfaceData(iSurfaceIndex);
			if (pSurfaceData)
			{
				// this logic is kinda gay, not sure why the *6 etc, but that's how other q3data code works, so...
				//
				float **ppVerts = pSurfaceData->verts;
				memcpy(v3,(vec3_t*) &ppVerts[0][iVertIndex*6+3], sizeof(v3));

				{		
					Matrix4 Swap;
							Swap.Identity();
					
					if (1)
					{
						Swap.SetRow(0,Vect3(0.0f,-1.0f,0.0f));
						Swap.SetRow(1,Vect3(1.0f,0.0f,0.0f));
					}
					Swap.CalcFlags();

					Vect3 v3In((const float *)v3);
					static Vect3 v3Out;
					Swap.XFormVect(v3Out,v3In);
					return (vec3_t*) &v3Out;
				}
			}
		}
		else
		{
			// tag surface...
			//
			// I don't think tag-surfaces normals have any meaning for ghoul2, so...
			//		
			return &v3;
		}
	}
	else
	{
		// imported surface...
		//
		vec3_t &v3Src = ImportedModel.ImportedLODs[iLODIndex].ImportedSurfaces[ImportedModel.SurfaceIndexRemaps[iSurfaceIndex]].ImportedVerts[iVertIndex].normal;
		memcpy(v3,v3Src,sizeof(v3));
		return &v3;
	}

	assert(0);	
	return &v3;
}
예제 #3
0
파일: panel.hpp 프로젝트: tommo97/Combined
    PANEL(Vect3 P1, Vect3 P2, Vect3 P3, Vect3 P4) {
        C1 = P1;
        C2 = P2;
        C3 = P3;
        C4 = P4;
        C1o = C1;
        C2o = C2;
        C3o = C3;
        C4o = C4;
        edgeX1 = edgeX2 = dF = Vect3(0.0);
        Sigma = Mu = PhiWakePrev = 0.0;
        Gamma = Phi = Sigma = Mu = 0.0;
        Area = MaxDiagonal = Gamma = Vn = MuPrev = GammaPrev = 0.0;
        Centroid = Vect3(.25 * (C1 + C2 + C3 + C4));
        Owner = NULL;
        OtherBoundarySurface = AttachedProtoWake = SheddingSurface = NULL;
        Neighb = NULL;
        Theta = 0.0;
        isBound = isTop = isWake = false;
        BoundBC = ID = -1;
        TRANS.assign(3, Vect3(0.));

        PhiPrev = Array <REAL> (4, 0.0);
        Cloc = Rloc = 0.0;
        Vfmm = dVFMM_dt = VWakePrev = Vect3(0.);
        DoubletValidRange2 = ValidRange = 1e32;
        GetNormal();
    }
예제 #4
0
파일: BodyRigid.cpp 프로젝트: kollmanj/omd
	BodyRigid::BodyRigid(	std::string const &name,
				double const &mass,
				vector<double> const &inertia,
				vector<double> const &pos,
				vector<double> const &q,
				vector<double> const &vel,
				vector<double> const &wl,
				bool const &fixed ): Body(name), m_mass(mass), m_fixed(fixed)
	{
		m_inertia <<inertia[0],	inertia[1],	inertia[2],
					inertia[3],	inertia[4],	inertia[5],
					inertia[6],	inertia[7],	inertia[8];
		Vect3 pos_;
		pos_	<<	pos[0],	pos[1],	pos[2];

		Quat q_(q[0],	q[1],	q[2],	q[3]);

		Vect3 vel_;
		vel_	<<	vel[0],	vel[1],	vel[2];

		Vect3 wl_;
		wl_		<<	wl[0],	wl[1],	wl[2];

		m_pos = pos_;
		m_q = q_;
		m_vel =vel_;
		m_wl = wl_;

		m_wldot = Vect3(0,0,0);
		m_accel = Vect3(0,0,0);

		m_appliedForce = Vect3(0,0,0);
		m_appliedTorque = Vect3(0,0,0);

		/// initialize kanes method .... TODO site the page number this this shows up on
		m_sAhat << 0.,0.,0.,0.,0.,0.;
		m_sFhat <<  0.,0.,0.,0.,0.,0.;
		m_sIhat <<  0,0,0,0,0,0,
					0,0,0,0,0,0,
					0,0,0,0,0,0,
					0,0,0,0,0,0,
					0,0,0,0,0,0,
					0,0,0,0,0,0;

		m_n_alpha_t_k << 0,0,0;
		m_n_a_t_k << 0,0,0;

		// contact stuff
		m_stiff = 0;
		m_damp = 0;
		m_frict = 0;
		m_thresh = 0;
	}
예제 #5
0
void trig_cone(Vect3 centre, Array <Vect3> &X, Array <Vect3> &Omega, REAL magnitude, REAL radius) {
    for (int x = 1; x <= NX; ++x) {
        for (int y = 1; y <= NY; ++y) {
            REAL r = sqrt((centre.x - x)*(centre.x - x)+ (centre.y - y)*(centre.y - y));
            if (r / radius < 1) {
                Omega.push_back(Vect3(0., 0., magnitude * sin((pi * 0.5 * (1 + (r / radius))))));
                X.push_back(Vect3(x, y, 0.));
            }

        }
    }
}
예제 #6
0
void TIME_STEPPER::Euler(FVMCell * cell) {

    for (int q = 0; q < SYSTEM::NumTransVars; ++q) {
        cell->TransVars[q] += dt * cell->TransDerivs[q];
        cell->TransDerivs[q] = Vect3(0.);
    }
}
예제 #7
0
void cylinder_dipole(Vect3 centre, Array <Vect3> &X, Array <Vect3> &Omega, REAL offset, REAL amplitude, REAL radius) {
    REAL c_cone[3] = {centre.x + offset, centre.x - offset, centre.y};
    REAL r1 = 0, r2 = 0;

    for (int x = 1; x <= 300; ++x) {
        for (int y = 1; y <= 300; ++y) {
            r1 = sqrt((c_cone[0] - x)*(c_cone[0] - x) + (c_cone[2] - y)*(c_cone[2] - y));
            r2 = sqrt((c_cone[1] - x)*(c_cone[1] - x) + (c_cone[2] - y)*(c_cone[2] - y));
            if (r1 <= radius) {
                Omega.push_back(Vect3(0., 0., (0. * amplitude) - amplitude));
                X.push_back(Vect3(x, y, 0.));
            }
            if (r2 <= radius) {
                Omega.push_back(Vect3(0., 0., (0. * amplitude) + amplitude));
                X.push_back(Vect3(x, y, 0.));
            }
        }
    }
}
예제 #8
0
파일: panel.hpp 프로젝트: tommo97/Combined
 PANEL()
 {
     C1 = C2 = C3 = C4 = C1o = C2o = C3o = C4o = NC1 = NC2 = NC3 = NC4 = edgeX1 = edgeX2 = dF = Vect3(0.0);
     Sigma = Mu = 0.0;
     Gamma = Phi = PhiWakePrev = 0.0;
     Area = MaxDiagonal = Sigma = Mu = Gamma = Vn = MuPrev = GammaPrev = 0.0;
     Centroid = CollocationPoint = Vect3(.25 * (C1 + C2 + C3 + C4));
     Owner = NULL;
     OtherBoundarySurface = AttachedProtoWake = SheddingSurface = NULL;
     Neighb = NULL;
     Theta = 0.0;
     isBound = isTop = isWake = false;
     BoundBC = ID = -1;
     TRANS.assign(3,Vect3(0.));
     PhiPrev = Array <REAL> (4,0.0);
     Cloc = Rloc = 0.0;
     Vfmm = dVFMM_dt = VWakePrev = Vect3(0.);
     DoubletValidRange2 = ValidRange = 1e32;
 }
예제 #9
0
ParticleEmitter::ParticleEmitter( ParticleEmitterDesc p_particleDesc )
{
	m_particleDesc		= p_particleDesc;
	m_nrOfDeadParticles	= 0;

	for (int i = 0; i < m_particleDesc.nrOfParticles; i++)
	{
		m_particleList.push_back(new Particle());

		//l_lifeTime is between m_particleDesc.lifeTimeMin and m_particleDesc.lifeTimeMax
		float l_lifeTime = m_particleDesc.lifeTimeMin + (float)rand()/((float)RAND_MAX/(m_particleDesc.lifeTimeMax-m_particleDesc.lifeTimeMin));
		//l_speed is between m_particleDesc.speedMin and m_particleDesc.speedMax
		float l_speed = m_particleDesc.speedMin + (float)rand()/((float)RAND_MAX/(m_particleDesc.speedMax-m_particleDesc.speedMin));

		//Random x,y,z between -1 and 1
		double xx = (double)rand()/((double)RAND_MAX*.5) - 1;
		double yy = (double)rand()/((double)RAND_MAX*.5) - 1;
		double zz = (double)rand()/((double)RAND_MAX*.5) - 1;

		//Calculate magnitude of x,y,z
		double vmag = sqrt((xx*xx)+(yy*yy)+(zz*zz));

		//Normalize x,y,z
		xx = xx/vmag;
		yy = yy/vmag;
		zz = zz/vmag;

		//Voila! Random unit vector!
		Vect3 l_direction = Vect3((float)xx, (float)yy, (float)zz);

		//TODO calculate direction depending on what angles are set
		m_particleList.at(i)->Init(m_particleDesc.position, m_particleDesc.scale, l_direction, m_particleDesc.acceleration, m_particleDesc.startColor, m_particleDesc.endColor, l_lifeTime, l_speed, 0.0f);
	}
	m_particleDataList.resize( m_particleList.size()*3 );
  
  glGenVertexArrays( 1, &m_vao );
  glBindVertexArray( m_vao );
  
  glGenBuffers( 1, &m_dataBuffer );
  glBindBuffer( GL_ARRAY_BUFFER, m_dataBuffer );
  glBufferData( GL_ARRAY_BUFFER, m_particleDataList.size() * 3 * sizeof( float ), 0, GL_DYNAMIC_DRAW );
  
  glEnableVertexAttribArray( 0 );
  glEnableVertexAttribArray( 1 );
  glEnableVertexAttribArray( 2 );
#define BUFFER_OFFSET( i ) ( ( char * )NULL + ( i ) )
  glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 9 * sizeof( float ), BUFFER_OFFSET( 0 ) );
  glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, 9 * sizeof( float ), BUFFER_OFFSET( 3 * sizeof( float ) ) );
  glVertexAttribPointer( 2, 3, GL_FLOAT, GL_FALSE, 9 * sizeof( float ), BUFFER_OFFSET( 6 * sizeof( float ) ) );

  glBindVertexArray( 0 );
}
예제 #10
0
void lamb_dipole(Vect3 centre, Array <Vect3> &X, Array <Vect3> &Omega, REAL amplitude, REAL theta_dipole, REAL radius, REAL a, REAL k) {
    //  Produce a Lamb Dipole, eg
    //        lamb_dipole(Vect3(100, 50, 0), X, OMEGA, 30, pi / 2, 30, 30, 3.81 / 30);


    REAL U;
    for (int x = 1; x <= NX; ++x) {
        for (int y = 1; y <= NY; ++y) {
            U = 0.;
            if (x < centre.x) U = -amplitude;
            if (x > centre.x) U = amplitude;

            REAL r = sqrt((centre[0] - x)*(centre[0] - x) + (centre[1] - y)*(centre[1] - y));
            if (r < radius) {
                REAL theta = atan2((centre[1] - y)*(centre[1] - y) + 1e-16, (centre[0] - x)*(centre[0] - x) + 1e-16);
                REAL numerator = gsl_sf_bessel_J1(k * r);
                REAL denominator = gsl_sf_bessel_J0(k * a);
                Omega.push_back(Vect3(0.0, 0.0, -U * 2 * k * sin(theta - theta_dipole) * numerator / denominator));
                X.push_back(Vect3((REAL) x, (REAL) y, 0.0));
            }
        }
    }
}
예제 #11
0
    Surf2VolMat::Surf2VolMat(const Geometry& geo, const Matrix& points) 
    {
        std::map<const Domain, Vertices> m_points;

        unsigned index = 0;
        // Find the points per domain and generate the indices for the m_points
        for ( unsigned i = 0; i < points.nlin(); ++i) {
            const Domain domain = geo.domain(Vect3(points(i, 0), points(i, 1), points(i, 2)));
            if ( domain.name() == "Air" ) {
                std::cerr << " Surf2Vol: Point [ " << points.getlin(i);
                std::cerr << "] is outside the head. Point is dropped." << std::endl;
            } else {
                m_points[domain].push_back(Vertex(points(i, 0), points(i, 1), points(i, 2), index++));
            }
        }

        assemble_Surf2Vol(geo, *this, m_points);
    }
예제 #12
0
파일: Paddle.cpp 프로젝트: Meraz/thorbear
void Paddle::Render()
{
	m_renderComp->RenderObject(GetBoundingBox(), PADDLE, Vect3(1.0f, 1.0f, 0.0f)); //PADDLE == enum OH REALLY?!
}
예제 #13
0
vec3_t *G2Exporter_Surface_GetVertCoords(int iSurfaceIndex, int iVertIndex, int iLODIndex)
{
	static vec3_t v3={0};
	memset(&v3,0,sizeof(v3));

	if (iLODIndex == giNumLODs-1)
	{
		// q3data surface...
		//
		if (iSurfaceIndex < giNumSurfaces)
		{
			// standard surface...
			//
			md3SurfaceData_t *pSurfaceData = GetMD3SurfaceData(iSurfaceIndex);
			if (pSurfaceData)
			{
				// this logic is kinda gay, not sure why the *6 etc, but that's how other q3data code works, so...
				//
				float **ppVerts = pSurfaceData->verts;
				static vec3_t v3;
				for (int i=0; i<3; i++)
				{
					v3[i] = ppVerts[0][iVertIndex*6+i];// /MD3_XYZ_SCALE;
				}
				// return &v3;
					
				Matrix4 Swap;
						Swap.Identity();
				
				if (1)
				{
					Swap.SetRow(0,Vect3(0.0f,-1.0f,0.0f));
					Swap.SetRow(1,Vect3(1.0f,0.0f,0.0f));
				}
				Swap.CalcFlags();

				Vect3 v3In((const float *)v3);
				static Vect3 v3Out;
				Swap.XFormVect(v3Out,v3In);
				return (vec3_t*) &v3Out;
			}
		}
		else
		{
			// tag surface...
			//
			assert(iVertIndex<3);

			md3Tag_t *pTag = &g_data.tags[0][iSurfaceIndex - giNumSurfaces];			
			vec3_t v3New;

	//#ifdef PERFECT_CONVERSION
			
			v3New[0] = pTag->axis[0][iVertIndex] ;
			v3New[1] = pTag->axis[1][iVertIndex] ;
			v3New[2] = pTag->axis[2][iVertIndex] ;

			// don't worry about how this crap works, it just does (arrived at by empirical methods... :-)
			//
			//  (mega-thanks to Gil as usual)
			//
			if (iVertIndex==2)
			{
				VectorCopy(pTag->origin,v3);
			}
			else
			if (iVertIndex==1)
			{
				v3New[0] =   2.0f * pTag->axis[1][iG2_TRISIDE_MIDDLE];
				v3New[1] = -(2.0f * pTag->axis[0][iG2_TRISIDE_MIDDLE]);
				v3New[2] =   2.0f * pTag->axis[2][iG2_TRISIDE_MIDDLE];
				
				VectorSubtract(pTag->origin,v3New,v3);
			}
			else
			{					
				v3New[0] =  pTag->axis[1][iG2_TRISIDE_LONGEST];
				v3New[1] = -pTag->axis[0][iG2_TRISIDE_LONGEST];
				v3New[2] =  pTag->axis[2][iG2_TRISIDE_LONGEST];
				
				VectorSubtract(pTag->origin,v3New,v3);
			}

	//		return (vec3_t*) &v3;

			Matrix4 Swap;
					Swap.Identity();
			
			if (1)
			{
				Swap.SetRow(0,Vect3(0.0f,-1.0f,0.0f));
				Swap.SetRow(1,Vect3(1.0f,0.0f,0.0f));
			}
			Swap.CalcFlags();

			Vect3 v3In((const float *)v3);
			static Vect3 v3Out;
			Swap.XFormVect(v3Out,v3In);

			return (vec3_t*) &v3Out;
		}
	}
	else
	{
		// imported surface...
		//
		vec3_t &v3Src = ImportedModel.ImportedLODs[iLODIndex].ImportedSurfaces[ImportedModel.SurfaceIndexRemaps[iSurfaceIndex]].ImportedVerts[iVertIndex].vertCoords;
		memcpy(v3,v3Src,sizeof(v3));
		return &v3;
	}

	assert(0);
	return &v3;
}
예제 #14
0
파일: BodyRigid.cpp 프로젝트: kollmanj/omd
	void BodyRigid::forceAccumReset()
	{
        m_appliedForce = Vect3(0,0,0);
		m_appliedTorque = Vect3(0,0,0);
	}
예제 #15
0
파일: xsiimp.cpp 프로젝트: DT85/Assimilate
int ProcNKeys(TxtNode *t,int& foundkeys)
{
	if (t->child)
	{
		TxtNode *sib=t->child;
		if (!sib->text)
			return 207;
		int tp=myatoi(sib->text,sib->length);
		sib=sib->sibling;
		if (!sib||!sib->text)
			return 208;
		int num=myatoi(sib->text,sib->length);
		sib=sib->sibling;
		int i;
		int lastframe=startframe-1;
		TxtNode *s=sib;
		for (i=0;i<num;i++)
		{
			if (!s||!s->text)
				return 110;
			int frame=myatoi(s->text,s->length);
			if (frame>33000)
				frame=frame-65536;
			if (frame<startframe)
			{
				assert(!i);
				lastframe=frame-1;
				startframe=frame;
			}
			if (frame>endframe)
				endframe=frame;
			if (frame-startframe>maxmatframe)
				maxmatframe=frame-startframe;
			s=s->sibling;
			if (!s||!s->text)
				return 212;
			int junk=myatoi(s->text,s->length);
			if (junk!=3)
				return 213;
			s=s->sibling;
			if (!s||!s->text)
				return 216;
			float x=(float)myatof(s->text,s->length);
			s=s->sibling;
			if (!s||!s->text)
				return 216;
			float y=(float)myatof(s->text,s->length);
			s=s->sibling;
			if (!s||!s->text)
				return 216;
			float z=(float)myatof(s->text,s->length);
			s=s->sibling;
			int k;
			if (tp==1) //scale
			{
				Vect3 v=Vect3(x,z,y);
				for (k=lastframe+1;k<=frame;k++)
					scales[k-startframe]=v;
				foundkeys|=4;
			}
			else if (tp==2) //translation
			{
				Vect3 v(x,-z,y);
				for (k=lastframe+1;k<=frame;k++)
				{
					mats[k-startframe].SetRow(3,v);
					mats[k-startframe].CalcFlags();
				}
				foundkeys|=1;
			}
			else if (tp==3) //rotation
			{
				Matrix4 tmp;
				tmp.Rotate(-x*M_PI/180.0f,-y*M_PI/180.0f,-z*M_PI/180.0f);
				Vect3 t,tt;
				tmp.GetRow(2,t);
				t*=-1.0f;
				tmp.GetRow(1,tt);
				tmp.SetRow(2,tt);
				tmp.SetRow(1,t);
				for (k=0;k<3;k++)
				{
					float tt=-tmp[k][2];
					tmp[k][2]=tmp[k][1];
					tmp[k][1]=tt;
				}
				for (k=lastframe+1;k<=frame;k++)
				{
					int l;
					for (l=0;l<3;l++)
					{
						tmp.GetRow(l,t);
						mats[k-startframe].SetRow(l,t);
						mats[k-startframe].CalcFlags();
					}
				}
				foundkeys|=2;
			}
			lastframe=frame;
		}
	}
	return 0;
}
예제 #16
0
void TIME_STEPPER::DoFMM() {

    int nt = 100;
    for (int I = 0; I < BODY::Bodies.size(); ++I) {

        Array <REAL> times = UTIL::globalLinspace(BODY::Time, BODY::Time + 1.1*dt, nt); //      max timestep change permitted is +- 5%
        Array <Vect3> EulerHist;
        Vect3 EulerAnglesTplusDT = UTIL::ODE4(BODY::EulerDot, times, EulerHist, BODY::Bodies[I]->EulerAngles, BODY::Bodies[I]->BodyRates);

        for (int i = 0; i < BODY::Bodies[I]->Faces.size(); ++i) {
            BODY::Bodies[I]->Faces[i].XP1 = BODY::Bodies[I]->Faces[i].CollocationPoint;
            Vect3 MinX = BODY::Bodies[I]->Faces[i].CollocationPoint, MaxX = BODY::Bodies[I]->Faces[i].CollocationPoint;
            for (int t = 0; t < nt; ++t) {
                Vect3 CGTplusDT = BODY::Bodies[I]->CG0 + times[t] * BODY::Bodies[I]->Velocity;
                Array <Vect3> TRANS = BODY::ReturnTrans(EulerHist[t]);
                Vect3 C1 = CGTplusDT + VectMultMatrix(TRANS, BODY::Bodies[I]->Faces[i].C1o - BODY::Bodies[I]->CG0);
                Vect3 C2 = CGTplusDT + VectMultMatrix(TRANS, BODY::Bodies[I]->Faces[i].C2o - BODY::Bodies[I]->CG0);
                Vect3 C3 = CGTplusDT + VectMultMatrix(TRANS, BODY::Bodies[I]->Faces[i].C3o - BODY::Bodies[I]->CG0);
                Vect3 C4 = CGTplusDT + VectMultMatrix(TRANS, BODY::Bodies[I]->Faces[i].C4o - BODY::Bodies[I]->CG0);
                Vect3 Xp = 0.25 * (C1 + C2 + C3 + C4);
                BODY::Bodies[I]->Faces[i].XP2 = Xp;
                MinX = min(MinX, Xp);
                MaxX = max(MaxX, Xp);
            }
            REAL Buffer = 1.0;
            MaxX += Vect3(Buffer, Buffer, Buffer);
            MinX -= Vect3(Buffer, Buffer, Buffer);

            MinX = floor(MinX) - 0.5;
            MaxX = ceil(MaxX) + 0.5;

            int DX = int((MaxX.x) - (MinX.x));
            int DY = int((MaxX.y) - (MinX.y));
            int DZ = int((MaxX.z) - (MinX.z));

            BODY::Bodies[I]->Faces[i].Xp = Array < Array < Array <Vect3*> > > (DX, Array < Array < Vect3*> > (DY, Array <Vect3*> (DZ, NULL)));
            BODY::Bodies[I]->Faces[i].Vp = Array < Array < Array <Vect3*> > > (DX, Array < Array < Vect3*> > (DY, Array <Vect3*> (DZ, NULL)));

            for (int a = 0; a < DX; ++a)
                for (int b = 0; b < DY; ++b)
                    for (int c = 0; c < DZ; ++c) {
                        OctreeCapsule C(MinX + Vect3(1.0 * a, 1.0 * b, 1.0 * c), Vect3(0, 0, 0), false);
                        C.toMonitor = true;
                        globalOctree->Root->EvalCapsule(C);
                        //  Any nodes which are created in this step are NOT included in the FVM calculation, and can safely be removed after the FMM/Panel vel calcs...
                        BODY::Bodies[I]->Faces[i].Vp[a][b][c] = C.Ptr2CellVelocity;
                        BODY::Bodies[I]->Faces[i].Xp[a][b][c] = C.Ptr2CellPosition;
                    }
        }
    }
    
//    
//    for (int i = 0; i < BODY::AllBodyFaces.size(); ++i) {
//        Vect3 Xp = BODY::AllBodyFaces[i]->CollocationPoint;
//        {
//            Vect3 OwnerCG = BODY::AllBodyFaces[i]->Owner->CG;
//            Vect3 OwnerVel = BODY::AllBodyFaces[i]->Owner->Velocity;
//            Vect3 OwnerRates = BODY::AllBodyFaces[i]->Owner->BodyRates;
//
//            Vect3 MinX = Xp, MaxX = Xp;
//
//            for (int nt = 1; nt < 100; ++nt) {
//                Vect3 PanelVel = OwnerVel + OwnerRates.Cross(Xp - OwnerCG);
//
//                OwnerCG += OwnerVel * dt / 100;
//
//                Xp += dt * PanelVel / 100;
//
//                MinX = min(MinX, Xp);
//                MaxX = max(MaxX, Xp);
//            }
//
//
//
//
//            REAL Buffer = 1.0;
//            MaxX += Vect3(Buffer, Buffer, Buffer);
//            MinX -= Vect3(Buffer, Buffer, Buffer);
//
//            MinX = floor(MinX) - 0.5;
//            MaxX = ceil(MaxX) + 0.5;
//
//            int DX = int((MaxX.x) - (MinX.x));
//            int DY = int((MaxX.y) - (MinX.y));
//            int DZ = int((MaxX.z) - (MinX.z));
//
//            BODY::AllBodyFaces[i]->Xp = Array < Array < Array <Vect3*> > > (DX, Array < Array < Vect3*> > (DY, Array <Vect3*> (DZ, NULL)));
//            BODY::AllBodyFaces[i]->Vp = Array < Array < Array <Vect3*> > > (DX, Array < Array < Vect3*> > (DY, Array <Vect3*> (DZ, NULL)));
//
//            for (int a = 0; a < DX; ++a)
//                for (int b = 0; b < DY; ++b)
//                    for (int c = 0; c < DZ; ++c) {
//                        OctreeCapsule C(MinX + Vect3(1.0 * a, 1.0 * b, 1.0 * c), Vect3(0, 0, 0), false);
//                        C.toMonitor = true;
//                        globalOctree->Root->EvalCapsule(C);
//                        //  Any nodes which are created in this step are NOT included in the FVM calculation, and can safely be removed after the FMM/Panel vel calcs...
//                        BODY::AllBodyFaces[i]->Vp[a][b][c] = C.Ptr2CellVelocity;
//                        BODY::AllBodyFaces[i]->Xp[a][b][c] = C.Ptr2CellPosition;
//                    }
//
//
//
//        }
//    }



    globalOctree->ResetAllVelsAndFields();
    globalOctree->UpdateLists();
    globalOctree->GetVels();
}
예제 #17
0
void TIME_STEPPER::TimeAdvance() {

#ifdef USE_SWSS
    //  This is a SWSS
    
    //  First 
    TIME_STEPPER::RKStep = 0;
    //  t0: Calc FMM and get DT
#ifndef NOFMM
    
    
    if (globalSystem->useFMM)
        DoFMM();
    else {
        for (int i = 0; i < FVMCell::AllCells.size(); ++i) {
            FVMCell::AllCells[i]->Velocity = globalSystem->unscaledVinf * SYSTEM::GambitScale;
        }
    }
        
#else
#pragma omp parallel for
    for (int i = 0; i < FVMCell::AllCells.size(); ++i) {
        FVMCell::AllCells[i]->Velocity = 0.0;
        FVMCell::AllCells[i]->VelGrads[0] = FVMCell::AllCells[i]->VelGrads[1] = FVMCell::AllCells[i]->VelGrads[2] = Vect3(0.0);
        for (int j = 0; j < FVMCell::AllCells.size(); ++j) {
            Vect3 D = FVMCell::AllCells[j]->Position - FVMCell::AllCells[i]->Position;
            FVMCell::AllCells[i]->Velocity += UTIL::globalDirectVel(D, FVMCell::AllCells[j]->Omega);
            directGradMethod(D, FVMCell::AllCells[j]->Omega, FVMCell::AllCells[i]->VelGrads);
        }

    }
#endif
    //  t0: calculate face velocities due to body
    globalSystem->GetFaceVels();
    //  t0: calculate face velocities due to body
    time_step();
    //  t0: get panel FMM Vels
#ifndef NOFMM
    if (globalSystem->useBodies) {
        globalSystem->GetPanelFMMVelocities(dt);

        //  t0: get time derivatives at t0

        //  t0: advance innter (body) timestep

        if (TIME_STEPPER::RK2Mode)
            BODY::BodySubStep(dt / 2.0, globalSystem->NumSubSteps);
        else
            BODY::BodySubStep(dt, globalSystem->NumSubSteps);

    }
#endif
    
    /* Order of integrations is as follows:
     * 0) Panel  
     * 1) stretch
     * 2) diffuse
     * 3) O2x
     * 4) O2y
     * 5) O2z
     * 
     * 
     * Other sweep is reverse
     */
    
    //  Record initial vals
    for (int i = 0; i < FVMCell::AllCells.size(); ++i) {
        FVMCell::AllCells[i]->VelHold = FVMCell::AllCells[i]->Velocity; //      this is done in vCollapseVelField
        FVMCell::AllCells[i]->VelGradsHold = FVMCell::AllCells[i]->VelGrads; //      this is done in vCollapseVelField
        for (int q = 0; q < SYSTEM::NumTransVars; ++q)
            FVMCell::AllCells[i]->TransVarsHold[q] = FVMCell::AllCells[i]->TransVars[q];
        FVMCell::AllCells[i]->OmegaHold = FVMCell::AllCells[i]->Omega;
    }
    if (globalSystem->useFMM) {
        globalOctree->DiffuseZAndAdvance(dt);
        globalOctree->StretchAndAdvance(dt);
        globalOctree->DiffuseYAndAdvance(dt);
    }
    globalOctree->O2UWxAndAdvance(dt);
    globalOctree->O2UWyAndAdvance(dt);
    globalOctree->O2UWzAndAdvance(dt);
    if (globalSystem->useFMM)
        globalOctree->DiffuseXAndAdvance(dt);

    //  Second sweep
    //  Reset initial values -- VelHold is still unchanged - can be reused; same with its gradients
#ifdef _OPENMP
#pragma omp parallel for
#endif
    for (int i = 0; i < FVMCell::AllCells.size(); ++i) {
        for (int q = 0; q < SYSTEM::NumTransVars; ++q) {
            FVMCell::AllCells[i]->TransVars0[q] = FVMCell::AllCells[i]->TransVars[q];
            FVMCell::AllCells[i]->TransVars[q] = FVMCell::AllCells[i]->TransVarsHold[q];
        }
        FVMCell::AllCells[i]->Velocity = FVMCell::AllCells[i]->VelHold;
        FVMCell::AllCells[i]->VelGrads = FVMCell::AllCells[i]->VelGradsHold;
        FVMCell::AllCells[i]->Omega = FVMCell::AllCells[i]->OmegaHold;


    }
    if (globalSystem->useFMM)
        globalOctree->DiffuseXAndAdvance(dt);

    globalOctree->O2UWzAndAdvance(dt);
    globalOctree->O2UWyAndAdvance(dt);
    globalOctree->O2UWxAndAdvance(dt);
    if (globalSystem->useFMM) {
        globalOctree->DiffuseYAndAdvance(dt);
        globalOctree->StretchAndAdvance(dt);
        globalOctree->DiffuseZAndAdvance(dt);
    }


    for (int i = 0; i < FVMCell::AllCells.size(); ++i) {
        FVMCell::AllCells[i]->Omega = Vect3(0.0);
        for (int q = 0; q < SYSTEM::NumTransVars; ++q) {
            Vect3 VarTmp = FVMCell::AllCells[i]->TransVars[q];
            FVMCell::AllCells[i]->TransVars [q] = 0.5 * (FVMCell::AllCells[i]->TransVars0[q] + VarTmp);
            FVMCell::AllCells[i]->Omega += FVMCell::AllCells[i]->TransVars[q];
        }
    }
    
#else
    
    //  t0: get cell velocities/gradients etc.
    DoFMM();


    //  t0: calculate face velocities due to body

    
    globalSystem->GetFaceVels();

    //  t0: calculate timestep length (use last values of panel singularity strengths for body influence)
    time_step();
    //  t0: get panel FMM Vels
//    if (globalSystem->useBodies)
//        globalSystem->GetPanelFMMVelocities(0.0);

    //  


    globalSystem->GetFaceVels();

 
    FVMCell::CellDerivs.allocate(SYSTEM::NumTransVars);
    for (int q = 0; q < SYSTEM::NumTransVars; ++q) {
        FVMCell::CellDerivs[q] = Array <Vect3> (FVMCell::AllCells.size());
#ifdef _OPENMP
#pragma omp parallel for
#endif
        for (int i = 0; i < FVMCell::AllCells.size(); ++i) {
            FVMCell::CellDerivs[q][i] = FVMCell::AllCells[i]->O2UW(q);
            FVMCell::CellDerivs[q][i] += FVMCell::AllCells[i]->Stretch(q);
//            FVMCell::CellDerivs[q][i] += FVMCell::AllCells[i]->Diffuse(q);
        }
#ifdef _OPENMP
#pragma omp parallel for
#endif
        for (int i = 0; i < FVMCell::AllCells.size(); ++i)
            FVMCell::AllCells[i]->TransVars[q] += dt * FVMCell::CellDerivs[q][i];
    }
#ifdef _OPENMP
#pragma omp parallel for
#endif
    for (int i = 0; i < FVMCell::AllCells.size(); ++i)
        FVMCell::AllCells[i]->NormaliseObliterate();

    //      Update cell velocities to reflect new cell omegas
#ifdef _OPENMP
#pragma omp parallel for
#endif   
    for (int i = 0; i < FVMCell::AllCells.size(); ++i)
        FVMCell::AllCells[i]->GetISAVels();
    
    
    //      Now update Panel FMM Vels to reflect new velocities then advance over timestep
    if (globalSystem->useBodies) {
        globalSystem->GetPanelFMMVelocities(dt);
        BODY::BodySubStep(dt, globalSystem->NumSubSteps);
    }


    
    
    
    //    if (TIME_STEPPER::RK2Mode) {
//        TIME_STEPPER::RKStep = 1;
//        //  t*: Do the FMM again
//        DoFMM();
//        if (globalSystem->useBodies) {
//            globalSystem->GetPanelFMMVelocities(dt / 2);
//            BODY::BodySubStep(dt / 2.0, globalSystem->NumSubSteps); //  t = t0 -> t*
//            //  t*: calculate face velocities due to body
//        }
//        globalSystem->GetFaceVels();
//        //  t*: calculate gradients at t*
//        globalOctree->FVM(); //  dom_dt(t*)
//        //  t*: advance to t1
//        globalOctree->Integrate(); //  t = t0 -> t1
//    }

#endif
    //  Put the wake in the tree from the bodytimestep
    if (globalSystem->useBodies) {
        globalSystem->PutWakesInTree();
    } else
        TIME_STEPPER::SimTime += dt;
    //  Clean up
    if (!fmod((REAL) n, 25.0))
        PruneNow = true;
    

    
    globalOctree->Reset();




}