Exemplo n.º 1
0
/************************************************************
Step

This is where knowledge of physical systems comes in handy.
For every vertex the surface tension is computed as the
cumulative sum of the difference between the vertex height and its
neighbors.  This data is fed into the change in velocity.  The
other values added are for damped oscillation (one is a proportional
control and the other is differential) and so the three physical
quantities accounted for are elasticity, viscosity, and surface tension.

Height is just incremented by time*velocity.
************************************************************/
void WaterField::Step(float time)
{
	int i, j, k, l, mi, ni, mj, nj;
	float cumulativeTension = 0;
	int calRadius = 1;

  for(i=0; i<myXdivs; i++)
		for(j=0; j<myYdivs; j++)
		{
			cumulativeTension = 0;
      myPoints[i][j].avecolor = 0;
      ni = i-calRadius > 0 ? i-calRadius : 0;//
      ni = iMax(0,i-calRadius);
      mi = iMin(myXdivs-1, i+calRadius);
      nj = iMax(0,j-calRadius);
      mj = iMin(myYdivs-1, j+calRadius);
      /*int numCount = ((mi-ni+1)*(mj-nj+1));
      //numCount = 1.0f;
      int rcum = (numCount/2) << 16, gcum = (numCount/2) << 8, bcum = numCount/2;*/
			for(k=ni; k<=mi; k++)
        for(l=nj; l<=mj; l++)
				{
					cumulativeTension += myPoints[k][l].height- myPoints[i][j].height;
          /*rcum += myPoints[k][l].color & 0xFF0000;
          gcum += myPoints[k][l].color & 0x00FF00;
          bcum += myPoints[k][l].color & 0x0000FF;*/
        //  myPoints[i][j].avecolor = AddColor(myPoints[i][j].avecolor, myPoints[k][l].color, numCount);//1.0f/numCount++);
				}
      /*myPoints[i][j].avecolor = (rcum/numCount) && 0xFF0000 + (gcum/numCount) && 0xFF00 + (bcum/numCount) && 0xFF;
      //myPoints[i][j].avecolor = *((DWORD*)&(LerpColor2(*((Color*)&(myPoints[i][j].avecolor)), black, 0.75f)));//1.0f/numCount++);
      //myPoints[i][j].avecolor = LerpColor(myPoints[i][j].avecolor, black, 0.75f);//1.0f/numCount++);
      for(k=ni; k<=mi; k++)
      {
				cumulativeTension += myPoints[k][j].height- myPoints[i][j].height;
        myPoints[i][j].avecolor = AddColor(myPoints[i][j].avecolor, myPoints[k][j].color, numCount +0.5f);//1.0f/numCount++);
        //AddColor2(*((Color*)&(myPoints[i][j].avecolor)), *((Color*)&(myPoints[k][j].color)), numCount);//1.0f/numCount++);
			}
      for(l=nj; l<=mj; l++)
			{
				cumulativeTension += myPoints[i][l].height- myPoints[i][j].height;
        myPoints[i][j].avecolor = AddColor(myPoints[i][j].avecolor, myPoints[i][l].color, numCount+0.5f);//1.0f/numCount++);
        //AddColor2(*((Color*)&(myPoints[i][j].avecolor)), *((Color*)&(myPoints[i][l].color)), numCount);//1.0f/numCount++);
			}*/

			myPoints[i][j].velocity +=m_elasticity*(myHeight-myPoints[i][j].height)
				- m_viscosity * myPoints[i][j].velocity
				+ m_tension*cumulativeTension;
		}

    for(i=0; i<myXdivs; i++)
    for(j=0; j<myYdivs; j++)
    {
      myPoints[i][j].height += myPoints[i][j].velocity*time;
      //myPoints[i][j].color = LerpColor3(myPoints[i][j].color, myPoints[i][j].color, m_blendability);
      SetNormalForPoint(i,j);
    }

}
Exemplo n.º 2
0
void* System::alignedMalloc(size_t bytes, size_t alignment) {
    alwaysAssertM(isPow2(alignment), "alignment must be a power of 2");

    // We must align to at least a word boundary.
    alignment = iMax((int)alignment, sizeof(void *));

    // Pad the allocation size with the alignment size and the
    // size of the redirect pointer.
    size_t totalBytes = bytes + alignment + sizeof(intptr_t);

    void* truePtr = System::malloc(totalBytes);

    if (!truePtr) {
        // malloc returned NULL
        return NULL;
    }

    debugAssert(isValidHeapPointer(truePtr));
    #ifdef G3D_WIN32
    // The blocks we return will not be valid Win32 debug heap
    // pointers because they are offset 
    //  debugAssert(_CrtIsValidPointer(truePtr, totalBytes, TRUE) );
    #endif

    // The return pointer will be the next aligned location (we must at least
    // leave space for the redirect pointer, however).
    char* alignedPtr = ((char*)truePtr)+ sizeof(intptr_t);

#if 0
    // 2^n - 1 has the form 1111... in binary.
    uint32 bitMask = (alignment - 1);

    // Advance forward until we reach an aligned location.
    while ((((intptr_t)alignedPtr) & bitMask) != 0) {
        alignedPtr += sizeof(void*);
    }
#else
    alignedPtr += alignment - (((intptr_t)alignedPtr) & (alignment - 1));
    // assert((alignedPtr - truePtr) + bytes <= totalBytes);
#endif

    debugAssert((alignedPtr - truePtr) + bytes <= totalBytes);

    // Immediately before the aligned location, write the true array location
    // so that we can free it correctly.
    intptr_t* redirectPtr = (intptr_t*)(alignedPtr - sizeof(intptr_t));
    redirectPtr[0] = (intptr_t)truePtr;

    debugAssert(isValidHeapPointer(truePtr));

    #ifdef G3D_WIN32
        debugAssert( _CrtIsValidPointer(alignedPtr, bytes, TRUE) );
    #endif
    return (void*)alignedPtr;
}
Exemplo n.º 3
0
void GuiDropDownList::render(RenderDevice* rd, const GuiSkinRef& skin) const {
    if (m_visible) {

        if (m_useStringList) {
            // If there are no elements in the list, display the empty string
            const std::string& str = (m_stringListValue->size() > 0) ? 
                    (*m_stringListValue)[iMax(0, iMin(m_stringListValue->size() - 1, *m_indexValue))] : 
                    "";

            skin->renderDropDownList(m_rect, m_enabled, focused() || mouseOver(), m_selecting, str, m_caption);
        } else {
            // If there are no elements in the list, display the empty string
            const GuiCaption& str = (m_captionListValue->size() > 0) ? 
                    (*m_captionListValue)[iMax(0, iMin(m_captionListValue->size() - 1, *m_indexValue))] : 
                    "";

            skin->renderDropDownList(m_rect, m_enabled, focused() || mouseOver(), m_selecting, str, m_caption);
        }
    }
}
Exemplo n.º 4
0
BumpMap::Settings::Settings(const Any& any) {
    *this = Settings();
    any.verifyName("BumpMap::Settings");
    for (Any::AnyTable::Iterator it = any.table().begin(); it.hasMore(); ++it) {
        const std::string& key = toLower(it->key);
        if (key == "iterations") {
            iterations = iMax(0, iRound(it->value.number()));
        } else if (key == "scale") {
            scale = it->value;
        } else if (key == "bias") {
            bias = it->value;
        } else {
            any.verify(false, "Illegal key: " + it->key);
        }
    }
}
void L2Project_interface(int mopt, int run,int istart, int iend,
	       const dTensor2& node,
	       const dTensorBC3& qin, 
	       const dTensorBC3& auxin,
               const dTensor4 qI,
               const dTensor4 auxI,dTensor4& Implicit,double dt,  
               const dTensor1 interf2global,
               const dTensorBC1 global2interf,
               const dTensor2 dxi,
	       dTensorBC3& Fout,
               dTensor4& FI,
	       void (*Func)(const dTensor1&, const dTensor2&, const dTensor2&, dTensor2&))
{    
  const int kmax = dogParams.get_space_order();
  const int meqn = qin.getsize(2);
  const int maux = auxin.getsize(2);
  const int mlength = Fout.getsize(2);
  const int mpoints = Fout.getsize(3);  

  int mtmp = iMax(1,6-mopt);//iMax(1,mpoints-mopt);
  dTensor1 wgt(mtmp), spts(mtmp),rspts(mtmp),lspts(mtmp);
  dTensor2 phi(mtmp,kmax), phi_x(mtmp,kmax), rIphi_x(mtmp,kmax), lIphi_x(mtmp,kmax);

  // -----------------
  // Quick error check
  // -----------------
  if (meqn<1 || maux <0 || mpoints<1 || mpoints>6 || mlength<1 
      || mopt < 0 || mopt > 1)
    {
      printf(" Error in L2project.cpp ... \n");
      printf("         meqn = %i\n",meqn);
      printf("         maux = %i\n",maux);
      printf("      mpoints = %i\n",mpoints);
      printf("      mlength = %i\n",mlength);
      printf("       istart = %i\n",istart);
      printf("         iend = %i\n",iend);
      printf("        mopts = %i\n",mopt);
      printf("\n");
      exit(1);
    }

  // ---------------------------------------------
  // Check for trivial case in the case of mopt==1
  // ---------------------------------------------
  if ( mpoints == mopt )
    { Fout.setall(0.); }
  else
    {
      // Set quadrature weights and points
      void SetQuadPts(dTensor1&,dTensor1&);
      SetQuadPts(wgt,spts);

      // Sample basis function at quadrature points
      void SampleBasis(const dTensor1&,dTensor2&);
      SampleBasis(spts,phi);

      // Sample gradient of basis function at quadrature points
      void SampleBasisGrad(const dTensor1&,dTensor2&);
      void SampleBasisGrad_variable(const dTensor1&,dTensor2&,double);
      SampleBasisGrad(spts,phi_x);

      // ----------------------------------
      // Loop over all elements of interest
      // ----------------------------------    
      const double xlow = dogParamsCart1.get_xlow();
      const double dx = dogParamsCart1.get_dx();

#pragma omp parallel for
      for (int i=istart; i<=iend; i++)
        {
          if(abs(global2interf.get(i))<1.0e-1)
          {
	  double xc = xlow + (double(i)-0.5)*dx;

	  // Each of these three items needs to be private to each thread ..
	  dTensor1 xpts(mtmp);
	  dTensor2 qvals(mtmp,meqn);
	  dTensor2 auxvals(mtmp,maux);
	  dTensor2 fvals(mtmp,mlength);

	  // Loop over each quadrature point
	  for (int m=1; m<=mtmp; m++)
            {
	      // grid point x
	      xpts.set( m, xc + 0.5*dx*spts.get(m) );

	      // Solution values (q) at each grid point
	      for (int me=1; me<=meqn; me++)
                {
		  qvals.set(m,me, 0.0 );

		  for (int k=1; k<=mpoints; k++)
                    {
		      qvals.set(m,me, qvals.get(m,me) 
                                + phi.get(m,k) * qin.get(i,me,k) );
                    }
                }

	      // Auxiliary values (aux) at each grid point
	      for (int ma=1; ma<=maux; ma++)
                {
		  auxvals.set(m,ma, 0.0 );

		  for (int k=1; k<=mpoints; k++)
                    {
		      auxvals.set(m,ma, auxvals.get(m,ma) 
				  + phi.get(m,k) * auxin.get(i,ma,k) );
                    }
                }
            }


	  // Call user-supplied function to set fvals
	  Func(xpts,qvals,auxvals,fvals);

	  // Evaluate integrals
	  if (mopt==0) // project onto Legendre basis
            {
	      for (int m1=1; m1<=mlength; m1++)
		for (int m2=1; m2<=mpoints; m2++)
		  {
		    double tmp = 0.0;
		    for (int k=1; k<=mtmp; k++)
		      {
			tmp += wgt.get(k)*fvals.get(k,m1)*phi.get(k,m2);
		      }
		    Fout.set(i,m1,m2, 0.5*tmp );
		  }

            }
	  else // project onto derivatives of Legendre basis
            {
	      for (int m1=1; m1<=mlength; m1++)             
		for (int m2=1; m2<=mpoints; m2++)
		  {
		    double tmp = 0.0;
		    for (int k=1; k<=mtmp; k++)
		      {
			tmp += wgt.get(k)*fvals.get(k,m1)*phi_x.get(k,m2);
		      }
		    Fout.set(i,m1,m2, 0.5*tmp );
		  }
            }
        }
          else if(run==1)
          {


          int iint=int(global2interf.get(i));

	  double xc1 = xlow + (double(i)-1.0)*dx+0.5*dxi.get(iint,1);
          double xc2 = xlow + (double(i)-1.0)*dx+dxi.get(iint,1)+0.5*dxi.get(iint,2);

          double dxl=dxi.get(iint,1);
          double dxr=dxi.get(iint,2);

        
	  // Each of these three items needs to be private to each thread ..
	  dTensor1 xptsl(mtmp);
	  dTensor2 qvalsl(mtmp,meqn);
	  dTensor2 auxvalsl(mtmp,maux);
	  dTensor2 fvalsl(mtmp,mlength);


	  dTensor1 xptsr(mtmp);
	  dTensor2 qvalsr(mtmp,meqn);
	  dTensor2 auxvalsr(mtmp,maux);
	  dTensor2 fvalsr(mtmp,mlength);

          //SampleBasisGrad_variable(lspts,lIphi_x,dxl);
          //SampleBasisGrad_variable(rspts,rIphi_x,dxr);           
          //SampleBasisGrad_variable(lspts,lIphi_x,1.0);
          //SampleBasisGrad_variable(rspts,rIphi_x,1.0);           

          SampleBasisGrad_variable(spts,lIphi_x,1.0);
          SampleBasisGrad_variable(spts,rIphi_x,1.0);



	  // Loop over each quadrature point
	  for (int m=1; m<=mtmp; m++)
            {
	      // grid point x
	      xptsl.set( m, xc1 + 0.5*dxl*spts.get(m) );
              xptsr.set( m, xc2 + 0.5*dxr*spts.get(m) );

              
	      // Solution values (q) at each grid point
	      for (int me=1; me<=meqn; me++)
                {
		  qvalsl.set(m,me, 0.0 );
                  qvalsr.set(m,me, 0.0 );

		  for (int k=1; k<=mpoints; k++)
                    {
		      qvalsl.set(m,me, qvalsl.get(m,me) 
                                + phi.get(m,k) * qI.get(1,iint,me,k) );
                      qvalsr.set(m,me, qvalsr.get(m,me) 
                                + phi.get(m,k) * qI.get(2,iint,me,k) );
                    }
                }

	      // Auxiliary values (aux) at each grid point
	      for (int ma=1; ma<=maux; ma++)
                {
		  auxvalsl.set(m,ma, 0.0 );

		  auxvalsr.set(m,ma, 0.0 );

		  for (int k=1; k<=mpoints; k++)
                    {
		      auxvalsl.set(m,ma, auxvalsl.get(m,ma) 
				  + phi.get(m,k) * auxI.get(1,iint,ma,k) );

		      auxvalsr.set(m,ma, auxvalsr.get(m,ma) 
				  + phi.get(m,k) * auxI.get(2,iint,ma,k) );
                    }
                }
            //printf("xcl=%e xtryl= %e \n",xc1,dxl);
            //printf("xcr=%e xtryr= %e \n",xc2,dxr);
            }

	  // Call user-supplied function to set fvals
          
	  Func(xptsl,qvalsl,auxvalsl,fvalsl);
          Func(xptsr,qvalsr,auxvalsr,fvalsr);
          /*
          for (int m=1; m<=mtmp; m++)
            {
               printf("xtryl= %e \n",xptsl.get(m));
               printf("xtryr= %e \n",xptsr.get(m));
               printf("qtryl= %e \n",qvalsl.get(m,1));
               printf("qtryr= %e \n",qvalsr.get(m,1));
            }*/


          //printf("i=%d iint=%d q= %e %e \n",i,iint,qI.get(1,iint,1,1),qI.get(1,iint,1,2)); 
          //printf("2i=%d iint=%d q= %e %e \n",i,iint,Iq.qget(2,iint,1,1),qI.get(2,iint,1,2)); 

          /*
	  for (inti m=1; m<=mtmp; m++)
            {
                printf("Points HERE! %d %e %e %e %e \n",m,xptsl.get(m),fvalsl.get(m,1),xptsr.get(m),fvalsl.get(m,1));
              
             }*/
 

	  // Evaluate integrals
	  if (mopt==0) // project onto Legendre basis
            {
	      for (int m1=1; m1<=mlength; m1++)
		for (int m2=1; m2<=mpoints; m2++)
		  {
		    double tmpl = 0.0;
                    double tmpr = 0.0;
		    for (int k=1; k<=mtmp; k++)
		      {
			tmpl += wgt.get(k)*fvalsl.get(k,m1)*phi.get(k,m2);
			tmpr += wgt.get(k)*fvalsr.get(k,m1)*phi.get(k,m2);
		      }
		    FI.set(1,iint,m1,m2, 0.5*tmpl );
                    FI.set(2,iint,m1,m2, 0.5*tmpr );
		  }
            }
	  else // project onto derivatives of Legendre basis
            {

              double Ul=auxI.get(1,iint,1,1);
              double Ur=auxI.get(2,iint,1,1);
              /*
	      for (int m1=1; m1<=mlength; m1++)             
		for (int m2=1; m2<=mpoints; m2++)
		  {
		    double tmpl = 0.0;
		    double tmpr = 0.0;
		    for (int k=1; k<=mtmp; k++)
		      {
			tmpl += wgt.get(k)*fvalsl.get(k,m1)*lIphi_x.get(k,m2);
			tmpr += wgt.get(k)*fvalsr.get(k,m1)*rIphi_x.get(k,m2);
		      }
		    FI.set(1,iint,m1,m2, 0.5*tmpl );
		    FI.set(2,iint,m1,m2, 0.5*tmpr );  
		  }*/

                for (int m2=1; m2<=mpoints; m2++)
                  for (int m3=1; m3<=mpoints; m3++)
                  {

                    double tmponl = 0.0;
                    double tmponr = 0.0;

                    double tmpIl = 0.0;
                    double tmpIr = 0.0;
                    for (int k=1; k<=mtmp; k++)
                      {
                        tmpIl += wgt.get(k)*Ul*phi.get(k,m3)*lIphi_x.get(k,m2);
                        tmpIr += wgt.get(k)*Ur*phi.get(k,m3)*rIphi_x.get(k,m2);
                        tmponl += wgt.get(k)*Ul*phi.get(k,m3)*phi_x.get(k,m2);
                        tmponr += wgt.get(k)*Ur*phi.get(k,m3)*phi_x.get(k,m2);
                      }
                    // Implicit.set(iint,m1,m2,m3, Implicit.get(iint,m1,m2,m3)-0.5*tmpIl );
                    //Implicit.set(iint,m1,kmax+m2,kmax+m3, Implicit.get(iint,m1,kmax+m2,kmax+m3)-0.5*tmpIr );
                    //Implicit.set(iint,m1,m2,m3, Implicit.get(iint,m1,m2,m3)+0.5*tmpIl );
                    //Implicit.set(iint,m1,kmax+m2,kmax+m3, Implicit.get(iint,m1,kmax+m2,kmax+m3)+0.5*tmpIr );
                    Implicit.set(iint,1,m2,m3, Implicit.get(iint,1,m2,m3)-0.5*tmpIl );
                    Implicit.set(iint,1,kmax+m2,kmax+m3, Implicit.get(iint,1,kmax+m2,kmax+m3)-0.5*tmpIl );
                    Implicit.set(iint,1,2*kmax+m2,2*kmax+m3, Implicit.get(iint,1,2*kmax+m2,2*kmax+m3)-0.5*tmpIl );
                    Implicit.set(iint,1,3*kmax+m2,3*kmax+m3, Implicit.get(iint,1,3*kmax+m2,3*kmax+m3)-0.5*tmpIr );
                    Implicit.set(iint,1,4*kmax+m2,4*kmax+m3, Implicit.get(iint,1,4*kmax+m2,4*kmax+m3)-0.5*tmpIr );
                    Implicit.set(iint,1,5*kmax+m2,5*kmax+m3, Implicit.get(iint,1,5*kmax+m2,5*kmax+m3)-0.5*tmpIr );
                    //if(abs(tmpIl)>1.0e-12 || abs(tmpIr)>1.0e-12)
                    //{printf("HERE2!!!! %e %e \n",0.5*tmpIl,0.5*tmpIr);}
                  }
                 /*
                 for(int m2=1;m2<=mpoints;m2++)
                 {
                  double tmp1=0.0;
                  double tmp2=0.0;
                  for (int m3=1;m3<=mpoints;m3++)
                  {
                    double tmpIl = 0.0;
                    double tmpIr = 0.0;
                    for (int k=1; k<=mtmp; k++)
                    {
                        tmpIl += wgt.get(k)*Ul*phi.get(k,m3)*lIphi_x.get(k,m2);
                        tmpIr += wgt.get(k)*Ur*phi.get(k,m3)*rIphi_x.get(k,m2);
                    }
                   tmp1=tmp1+0.5*tmpIl*qI.get(1,iint,1,m3);
                   tmp2=tmp2+0.5*tmpIr*qI.get(2,iint,1,m3);
                  }
                  //printf("HERE left! %e \n",tmp1-FI.get(1,1,1,m2));
                  //printf("HERE right! %e \n",tmp2-FI.get(2,1,1,m2));
                  }*/ 
            }
        }

      }
    }

}
Exemplo n.º 6
0
// All-purpose routine for computing the L2-projection
// of various functions onto the gradient of the Legendre basis
//     (Unstructured grid version)
//
void L2ProjectGrad_Unst(
    const dTensor2* vel_vec,
    const int istart, 
    const int iend, 
    const int QuadOrder, 
    const int BasisOrder_qin,
    const int BasisOrder_auxin,
    const int BasisOrder_fout,
    const mesh& Mesh, 
    const dTensor3* qin, 
    const dTensor3* auxin, 
    dTensor3* fout, 
    void (*Func)(const dTensor2* vel_vec,
        const dTensor2&,const dTensor2&,
        const dTensor2&,dTensor3&))
{
    // starting and ending indeces
    const int   NumElems = Mesh.get_NumElems();
    assert_ge(istart,1);
    assert_le(iend,NumElems);

    // qin variable
    assert_eq(NumElems,qin->getsize(1));
    const int     meqn = qin->getsize(2);
    const int kmax_qin = qin->getsize(3);
    assert_eq(kmax_qin,(BasisOrder_qin*(BasisOrder_qin+1))/2);

    // auxin variable
    assert_eq(NumElems,auxin->getsize(1));
    const int       maux = auxin->getsize(2);
    const int kmax_auxin = auxin->getsize(3);
    assert_eq(kmax_auxin,(BasisOrder_auxin*(BasisOrder_auxin+1))/2);

    // fout variables
    assert_eq(NumElems,fout->getsize(1));
    const int mcomps_out = fout->getsize(2);
    const int  kmax_fout = fout->getsize(3);
    assert_eq(kmax_fout,(BasisOrder_fout*(BasisOrder_fout+1))/2);

    // number of quadrature points
    assert_ge(QuadOrder,1);
    assert_le(QuadOrder,5);
    int mpoints;
    switch ( QuadOrder )
    {
        case 1:
            mpoints = 0;
            break;

        case 2:
            mpoints = 1;
            break;

        case 3:
            mpoints = 6;
            break;

        case 4:
            mpoints = 7;
            break;

        case 5:	     
            mpoints = 16;
            break;
    }

    // trivial case
    if ( QuadOrder==1 )
    {
        for (int i=istart; i<=iend; i++)
        for (int m=1; m<=mcomps_out; m++) 
        for (int k=1; k<=kmax_fout; k++) 
        {  fout->set(i,m,k, 0.0 );  }
    }
    else
    {
        const int kmax = iMax(iMax(kmax_qin,kmax_auxin),kmax_fout);
        dTensor2    spts(mpoints,2);
        dTensor1    wgts(mpoints);
        dTensor2    xpts(mpoints,2);
        dTensor2   qvals(mpoints,meqn);
        dTensor2 auxvals(mpoints,maux);
        dTensor3   fvals(mpoints,mcomps_out,2);
        dTensor2      mu(mpoints,kmax); // monomial basis (non-orthogonal)
        dTensor2     phi(mpoints,kmax); // Legendre basis (orthogonal)
        dTensor2   mu_xi(mpoints,kmax_fout);   //  xi-derivative of monomial basis (non-orthogonal)
        dTensor2  mu_eta(mpoints,kmax_fout);   // eta-derivative of monomial basis (non-orthogonal)
        dTensor2  phi_xi(mpoints,kmax_fout);   //  xi-derivative of Legendre basis (orthogonal)
        dTensor2 phi_eta(mpoints,kmax_fout);   // eta-derivative of Legendre basis (orthogonal)
        dTensor2   phi_x(mpoints,kmax_fout);   //   x-derivative of Legendre basis (orthogonal)
        dTensor2   phi_y(mpoints,kmax_fout);   //   y-derivative of Legendre basis (orthogonal)

        switch ( QuadOrder )
        {
            case 2:
                spts.set(1,1, 0.0 );
                spts.set(1,2, 0.0 );

                wgts.set(1, 0.5 );
                break;

            case 3:
                spts.set(1,1,  0.112615157582632 );
                spts.set(1,2,  0.112615157582632 );

                spts.set(2,1, -0.225230315165263 );
                spts.set(2,2,  0.112615157582632 );

                spts.set(3,1,  0.112615157582632 );
                spts.set(3,2, -0.225230315165263 );

                spts.set(4,1, -0.241757119823562 );
                spts.set(4,2, -0.241757119823562 );

                spts.set(5,1,  0.483514239647126 );
                spts.set(5,2, -0.241757119823562 );

                spts.set(6,1, -0.241757119823562 );
                spts.set(6,2,  0.483514239647126 );

                wgts.set(1, 0.1116907948390055 );
                wgts.set(2, 0.1116907948390055 );
                wgts.set(3, 0.1116907948390055 );
                wgts.set(4, 0.0549758718276610 );
                wgts.set(5, 0.0549758718276610 );
                wgts.set(6, 0.0549758718276610 );
                break;

            case 4:
                spts.set(1,1,   0.000000000000000 );
                spts.set(1,2,   0.000000000000000 );

                spts.set(2,1,   0.136808730771782 );
                spts.set(2,2,   0.136808730771782 );

                spts.set(3,1,  -0.273617461543563 );
                spts.set(3,2,   0.136808730771782 );

                spts.set(4,1,   0.136808730771782 );
                spts.set(4,2,  -0.273617461543563 );

                spts.set(5,1,  -0.232046826009877 );
                spts.set(5,2,  -0.232046826009877 );

                spts.set(6,1,   0.464093652019754 );
                spts.set(6,2,  -0.232046826009877 );

                spts.set(7,1,  -0.232046826009877 );
                spts.set(7,2,   0.464093652019754 );	 

                wgts.set(1,  0.1125000000000000 );
                wgts.set(2,  0.0661970763942530 );
                wgts.set(3,  0.0661970763942530 );
                wgts.set(4,  0.0661970763942530 );
                wgts.set(5,  0.0629695902724135 );
                wgts.set(6,  0.0629695902724135 );
                wgts.set(7,  0.0629695902724135 );
                break;

            case 5:
                spts.set(1,1,   0.000000000000000 );
                spts.set(1,2,   0.000000000000000 );

                spts.set(2,1,   0.125959254959390 );
                spts.set(2,2,   0.125959254959390 );

                spts.set(3,1,  -0.251918509918779 );
                spts.set(3,2,   0.125959254959390 );

                spts.set(4,1,   0.125959254959390 );
                spts.set(4,2,  -0.251918509918779 );

                spts.set(5,1,  -0.162764025581573 );
                spts.set(5,2,  -0.162764025581573 );

                spts.set(6,1,   0.325528051163147 );
                spts.set(6,2,  -0.162764025581573 );

                spts.set(7,1,  -0.162764025581573 );
                spts.set(7,2,   0.325528051163147 );

                spts.set(8,1,  -0.282786105016302 );
                spts.set(8,2,  -0.282786105016302 );

                spts.set(9,1,   0.565572210032605 );
                spts.set(9,2,  -0.282786105016302 );

                spts.set(10,1, -0.282786105016302 );
                spts.set(10,2,  0.565572210032605 );

                spts.set(11,1, -0.324938555923375 );
                spts.set(11,2, -0.070220503698695 );

                spts.set(12,1, -0.324938555923375 );
                spts.set(12,2,  0.395159059622071 );

                spts.set(13,1, -0.070220503698695 );
                spts.set(13,2, -0.324938555923375 );

                spts.set(14,1, -0.070220503698695 );
                spts.set(14,2,  0.395159059622071 );

                spts.set(15,1,  0.395159059622071 );
                spts.set(15,2, -0.324938555923375 );

                spts.set(16,1,  0.395159059622071 );
                spts.set(16,2, -0.070220503698695 );

                wgts.set(1,  0.0721578038388935 );
                wgts.set(2,  0.0475458171336425 );
                wgts.set(3,  0.0475458171336425 );
                wgts.set(4,  0.0475458171336425 );
                wgts.set(5,  0.0516086852673590 );
                wgts.set(6,  0.0516086852673590 );
                wgts.set(7,  0.0516086852673590 );
                wgts.set(8,  0.0162292488115990 );
                wgts.set(9,  0.0162292488115990 );
                wgts.set(10, 0.0162292488115990 );
                wgts.set(11, 0.0136151570872175 );
                wgts.set(12, 0.0136151570872175 );
                wgts.set(13, 0.0136151570872175 );
                wgts.set(14, 0.0136151570872175 );
                wgts.set(15, 0.0136151570872175 );
                wgts.set(16, 0.0136151570872175 );
                break;
        }

        // Loop over each quadrature point and construct monomial polys
        for (int m=1; m<=mpoints; m++)
        {
            // coordinates
            const double xi   = spts.get(m,1);      
            const double xi2  = xi*xi;
            const double xi3  = xi2*xi;
            const double xi4  = xi3*xi;
            const double eta  = spts.get(m,2);
            const double eta2 = eta*eta;
            const double eta3 = eta2*eta;
            const double eta4 = eta3*eta;      

            // monomial basis functions at each gaussian quadrature point
            switch( kmax )
            {
                case 15:  // fifth order		    		    
                    mu.set(m, 15, eta4     );
                    mu.set(m, 14, xi4      );
                    mu.set(m, 13, xi2*eta2 );
                    mu.set(m, 12, eta3*xi  );
                    mu.set(m, 11, xi3*eta  );

                case 10:  // fourth order
                    mu.set(m, 10, eta3     );
                    mu.set(m, 9,  xi3      );
                    mu.set(m, 8,  xi*eta2  );
                    mu.set(m, 7,  eta*xi2  );

                case 6:  // third order
                    mu.set(m, 6,  eta2     );
                    mu.set(m, 5,  xi2      );
                    mu.set(m, 4,  xi*eta   );		    

                case 3:  // second order		    
                    mu.set(m, 3, eta       );
                    mu.set(m, 2, xi        );

                case 1:  // first order
                    mu.set(m, 1, 1.0       );

                    break;		    
            }

            // Loop over each quadrature point and construct Legendre polys
            for (int i=1; i<=kmax; i++)
            {
                double tmp = 0.0;
                for (int j=1; j<=i; j++)
                {  tmp = tmp + Mmat[i-1][j-1]*mu.get(m,j);  }

                phi.set(m,i, tmp );
            }	

            // Gradient of monomial basis functions at each gaussian quadrature point
            switch( kmax_fout )
            {
                case 15:  // fifth order
                    mu_xi.set( m,15,  0.0         );
                    mu_xi.set( m,14,  4.0*xi3     );
                    mu_xi.set( m,13,  2.0*xi*eta2 );
                    mu_xi.set( m,12,  eta3        );
                    mu_xi.set( m,11,  3.0*xi2*eta );

                    mu_eta.set( m,15, 4.0*eta3    );
                    mu_eta.set( m,14, 0.0         );
                    mu_eta.set( m,13, 2.0*xi2*eta );
                    mu_eta.set( m,12, 3.0*eta2*xi );
                    mu_eta.set( m,11, xi3 );

                case 10:  // fourth order
                    mu_xi.set( m,10,  0.0        );
                    mu_xi.set( m,9,   3.0*xi2    );			
                    mu_xi.set( m,8,   eta2       );
                    mu_xi.set( m,7,   2.0*eta*xi );

                    mu_eta.set( m,10, 3.0*eta2   );
                    mu_eta.set( m,9,  0.0        );
                    mu_eta.set( m,8,  2.0*eta*xi );
                    mu_eta.set( m,7,  xi2        );

                case 6:  // third order
                    mu_xi.set( m,6,  0.0      );
                    mu_xi.set( m,5,  2.0*xi   );			
                    mu_xi.set( m,4,  eta      );

                    mu_eta.set( m,6,  2.0*eta );			
                    mu_eta.set( m,5,  0.0     );
                    mu_eta.set( m,4,  xi      );

                case 3:  // second order
                    mu_xi.set( m,3,  0.0 );
                    mu_xi.set( m,2,  1.0 );

                    mu_eta.set( m,3, 1.0 );
                    mu_eta.set( m,2, 0.0 );

                case 1:  // first order
                    mu_xi.set( m,1,  0.0 );

                    mu_eta.set( m,1, 0.0 );
                    break;
            }

            // Loop over each quadrature point and construct Legendre polys
            for (int i=1; i<=kmax_fout; i++)
            {
                double tmp1 = 0.0;
                double tmp2 = 0.0;
                for (int j=1; j<=i; j++)
                {  
                    tmp1 = tmp1 + Mmat[i-1][j-1]*mu_xi.get(m,j);  
                    tmp2 = tmp2 + Mmat[i-1][j-1]*mu_eta.get(m,j);
                }

                phi_xi.set(m,i,  tmp1 );
                phi_eta.set(m,i, tmp2 );
            }
        }

        // -------------------------------------------------------------
        // Loop over every grid cell indexed by user supplied parameters
        // described by istart...iend
        // -------------------------------------------------------------
#pragma omp parallel for
        for (int i=istart; i<=iend; i++)
        {	  
            // Find center of current cell
            const int i1 = Mesh.get_tnode(i,1);
            const int i2 = Mesh.get_tnode(i,2);
            const int i3 = Mesh.get_tnode(i,3);
            const double x1 = Mesh.get_node(i1,1);
            const double y1 = Mesh.get_node(i1,2);
            const double x2 = Mesh.get_node(i2,1);
            const double y2 = Mesh.get_node(i2,2);
            const double x3 = Mesh.get_node(i3,1);
            const double y3 = Mesh.get_node(i3,2);

            const double xc = (x1+x2+x3)/3.0;
            const double yc = (y1+y2+y3)/3.0;

            // Compute q, aux and fvals at each Gaussian Quadrature point
            // for this current cell indexed by (i,j)
            // Save results into dTensor2 qvals, auxvals and fvals.
            for (int m=1; m<=mpoints; m++)
            {
                // convert phi_xi and phi_eta derivatives
                // to phi_x and phi_y derivatives through Jacobian
                for (int k=1; k<=kmax_fout; k++)
                {
                    phi_x.set(m,k, Mesh.get_jmat(i,1,1)*phi_xi.get(m,k)
                            + Mesh.get_jmat(i,1,2)*phi_eta.get(m,k) );
                    phi_y.set(m,k, Mesh.get_jmat(i,2,1)*phi_xi.get(m,k)
                            + Mesh.get_jmat(i,2,2)*phi_eta.get(m,k) );
                }

                // point on the unit triangle
                const double s = spts.get(m,1);
                const double t = spts.get(m,2);

                // point on the physical triangle
                xpts.set(m,1, xc + (x2-x1)*s + (x3-x1)*t );
                xpts.set(m,2, yc + (y2-y1)*s + (y3-y1)*t );

                // Solution values (q) at each grid point
                for (int me=1; me<=meqn; me++)
                {
                    qvals.set(m,me, 0.0 );

                    for (int k=1; k<=kmax_qin; k++)
                    {
                        qvals.set(m,me, qvals.get(m,me) 
                                + phi.get(m,k) * qin->get(i,me,k) );
                    }
                }

                // Auxiliary values (aux) at each grid point
                for (int ma=1; ma<=maux; ma++)
                {
                    auxvals.set(m,ma, 0.0 );

                    for (int k=1; k<=kmax_auxin; k++)
                    {
                        auxvals.set(m,ma, auxvals.get(m,ma) 
                                + phi.get(m,k) * auxin->get(i,ma,k) );
                    }
                } 
            }

            // Call user-supplied function to set fvals
            Func(vel_vec, xpts, qvals, auxvals, fvals);

            // Evaluate integral on current cell (project onto Legendre basis) 
            // using Gaussian Quadrature for the integration
            for (int m1=1; m1<=mcomps_out; m1++)		
            for (int m2=1; m2<=kmax_fout; m2++)
            {
                double tmp = 0.0;
                for (int k=1; k<=mpoints; k++)
                {
                    tmp = tmp + wgts.get(k)*
                        ( fvals.get(k,m1,1)*phi_x.get(k,m2) +
                          fvals.get(k,m1,2)*phi_y.get(k,m2) );
                }
                fout->set(i, m1, m2,  2.0*tmp );
            }

        }
    }
}
Exemplo n.º 7
0
GlutWindow::GlutWindow(const GWindowSettings& s) {
    _mouseVisible = true;
    _windowTitle = "G3D";
    settings = s;

    currentGlutWindow = this;

    // Set window size and position
    glutInitWindowSize(settings.width, settings.height);
    glutInitWindowPosition(settings.x, settings.y);   
    glutInitDisplayMode(computeGlutFlags(settings));

    if (! glutInitialized) {
        glutInitDummy();
        glutInitialized = true;
    }

    glutWindowHandle = glutCreateWindow("G3D");

    if (settings.center) {
        glutPositionWindow(
            iMax(0,(glutGet(GLUT_SCREEN_WIDTH) - settings.width) / 2),
            iMax(0,(glutGet(GLUT_SCREEN_HEIGHT) - settings.height) / 2));            
    }

    if (settings.fullScreen) {
        glutFullScreen();
    }

    // See what settings we actually got
    settings.alphaBits = glutGet(GLUT_WINDOW_ALPHA_SIZE);
    settings.depthBits = glutGet(GLUT_WINDOW_DEPTH_SIZE);

    // No gamma ramp on Glut windows
    settings.lightSaturation = 1.0;
    settings.stencilBits = glutGet(GLUT_WINDOW_STENCIL_SIZE);
    settings.fsaaSamples = glutGet(GLUT_WINDOW_NUM_SAMPLES);

    settings.stereo = (glutGet(GLUT_WINDOW_STEREO) != 0);

    mouseButtons = 0;

	#ifdef G3D_LINUX
		if (glXGetCurrentDisplay != NULL) {
			G3D::_internal::x11Display = glXGetCurrentDisplay();
		}

		if (glXGetCurrentDrawable != NULL) {
			G3D::_internal::x11Window  = glXGetCurrentDrawable();
		}
	#endif

    glutReshapeFunc(g_reshape);
    glutKeyboardFunc(g_keyboard);
    glutKeyboardUpFunc(g_keyboardup);
    glutSpecialFunc(g_keyboardspecial);
    glutSpecialUpFunc(g_keyboardspecialup);
    glutMotionFunc(g_mousemotion);
    glutPassiveMotionFunc(g_mousemotion);
    glutMouseFunc(g_mousebtn);
    glutDisplayFunc(g_draw);
}
Exemplo n.º 8
0
void VideoOutput::initialize(const String& filename, const Settings& settings) {
    // helper for exiting VideoOutput construction (exceptions caught by static ref creator)
    #define throwException(exp, msg) if (!(exp)) { throw String(msg); }

    debugAssert(settings.width > 0);
    debugAssert(settings.height > 0);
    debugAssert(settings.fps > 0);
#ifndef G3D_NO_FFMPEG
    // initialize list of available muxers/demuxers and codecs in ffmpeg
    av_register_all();

    m_filename = filename;
    m_settings = settings;

    // see if ffmpeg can support this muxer and setup output format
    m_avOutputFormat = av_guess_format(NULL, filename.c_str(), NULL);
    throwException(m_avOutputFormat, ("Error initializing FFmpeg in guess_format."));

    // set the codec id
    m_avOutputFormat->video_codec = static_cast<AVCodecID>(m_settings.codec);

    // create format context which controls writing the file
    m_avFormatContext = avformat_alloc_context();
    throwException(m_avFormatContext, ("Error initializing FFmpeg in av_alloc_format_context."));

    // attach format to context
    m_avFormatContext->oformat = m_avOutputFormat;
    strncpy(m_avFormatContext->filename, filename.c_str(), sizeof(m_avFormatContext->filename));

    // add video stream 0
    m_avStream = avformat_new_stream(m_avFormatContext, 0);
    throwException(m_avStream, ("Error initializing FFmpeg in av_new_stream."));
    
    // setup video stream
    m_avStream->codec->codec_id     = m_avOutputFormat->video_codec;
    m_avStream->codec->codec_type   = AVMEDIA_TYPE_VIDEO;

    // find and open required codec
    AVCodec* codec = avcodec_find_encoder(m_avStream->codec->codec_id);
    throwException(codec, 
                   format("Could not find an %s (%d) encoder on this machine.",
                          toString(static_cast<InternalCodecID>(m_avStream->codec->codec_id)),
                          m_avStream->codec->codec_id));

    // finish setting codec parameters


    m_avStream->codec->bit_rate     = m_settings.bitrate * 10;
    m_avStream->time_base.den = 30;
    m_avStream->time_base.num = 1;
    m_avStream->codec->time_base.den = 30;
    m_avStream->codec->time_base.num = 1;
    m_avStream->codec->width        = m_settings.width;
    m_avStream->codec->height       = m_settings.height;
    // set codec input format
    if (m_settings.codec == CODEC_ID_RAWVIDEO) {
        m_avStream->codec->pix_fmt = ConvertImageFormatToPixelFormat(m_settings.raw.format);
        throwException(m_avStream->codec->pix_fmt != PIX_FMT_NONE, ("Error initializing FFmpeg setting raw video input format."));
    } else {
        m_avStream->codec->pix_fmt = codec->pix_fmts[0];
    }

    // set the fourcc
    if (m_settings.fourcc != 0) {
        m_avStream->codec->codec_tag  = m_settings.fourcc;
    }

    // some formats want stream headers to be separate
    if (m_avOutputFormat->flags & AVFMT_GLOBALHEADER) {
        m_avStream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
    }
 
    //set a bunch of obscure presets that stop ffmpeg from breaking
    m_avStream->codec->rc_max_rate = 0;
    m_avStream->codec->rc_buffer_size = 0;
    m_avStream->codec->gop_size = 40;
    m_avStream->codec->max_b_frames = 3;
    m_avStream->codec->b_frame_strategy = 1;
    m_avStream->codec->coder_type = 1;
    m_avStream->codec->me_cmp = 1;
    m_avStream->codec->me_range = 16;
    m_avStream->codec->qmin = 10;
    m_avStream->codec->qmax = 51;
    m_avStream->codec->scenechange_threshold = 40;
    m_avStream->codec->flags |= CODEC_FLAG_LOOP_FILTER;
    m_avStream->codec->me_method = ME_HEX;
    m_avStream->codec->me_subpel_quality = 5;
    m_avStream->codec->i_quant_factor = 0.71;
    m_avStream->codec->qcompress = 0.6;
    m_avStream->codec->max_qdiff = 4;
    m_avStream->codec->profile = FF_PROFILE_H264_BASELINE;

    int avRet = avcodec_open2(m_avStream->codec, codec, NULL);
    throwException(avRet >= 0, ("Error initializing FFmpeg in avcodec_open"));

   
    // create encoding buffer - just allocate largest possible for now (3 channels)
    m_avEncodingBufferSize = iMax(m_settings.width * m_settings.height * 3, 512 * 1024);
    m_avEncodingBuffer = static_cast<uint8*>(av_malloc(m_avEncodingBufferSize));

    // create buffer to hold converted input frame if the codec needs a conversion
    int inputBufferSize = avpicture_get_size(m_avStream->codec->pix_fmt, m_settings.width, m_settings.height);

    m_avInputBuffer = static_cast<uint8*>(av_malloc(inputBufferSize));
    throwException(m_avInputBuffer, ("Error initializing FFmpeg in av_malloc"));

    m_avInputFrame = avcodec_alloc_frame();
    throwException(m_avInputFrame, ("Error initializing FFmpeg in avcodec_alloc_frame"));
    avpicture_fill(reinterpret_cast<AVPicture*>(m_avInputFrame), m_avInputBuffer, m_avStream->codec->pix_fmt, m_settings.width, m_settings.height);

    // open output file for writing using ffmpeg
     avRet = avio_open(&m_avFormatContext->pb, filename.c_str(), AVIO_FLAG_WRITE);
    throwException(avRet >= 0, ("Error opening FFmpeg video file with url_fopen"));

    // start the stream
    avRet = avformat_write_header(m_avFormatContext, NULL);

    // make sure the file is closed on error
    if (avRet < 0) {
        // abort closes and removes the output file
        abort();
        throwException(false, ("Error initializing and writing FFmpeg video file."));
    }
#endif
    m_isInitialized = true;
}
Exemplo n.º 9
0
bool CameraControlWindow::onEvent(const GEvent& event) {

    // Allow super class to process the event
    if (GuiWindow::onEvent(event)) {
        return true;
    }
    
    // Accelerator key for toggling camera control.  Active even when the window is hidden.
    if ((event.type == GEventType::KEY_DOWN) && (event.key.keysym.sym == GKey::F2)) {
        manualOperation = ! manualOperation;
        sync();
        return true;
    }

    if (! visible()) {
        return false;
    }

    // Special buttons
    if (event.type == GEventType::GUI_ACTION) {
        GuiControl* control = event.gui.control;

        if (control == drawerButton) {

            // Change the window size
            m_expanded = ! m_expanded;
            morphTo(Rect2D::xywh(rect().x0y0(), m_expanded ? bigSize : smallSize));
            drawerButton->setCaption(m_expanded ? drawerCollapseCaption : drawerExpandCaption);

        } else if (control == trackList) {
            
            if (trackFileArray[trackFileIndex] != untitled) {
                // Load the new spline
                loadSpline(trackFileArray[trackFileIndex] + ".trk");

                // When we load, we lose our temporarily recorded spline,
                // so remove that display from the menu.
                if (trackFileArray.last() == untitled) {
                    trackFileArray.remove(trackFileArray.size() - 1);
                }
            }

        } else if (control == playButton) {

            // Take over manual operation
            manualOperation = true;
            // Restart at the beginning of the path
            trackManipulator->setTime(0);

        } else if ((control == recordButton) || (control == cameraLocationTextBox)) {

            // Take over manual operation and reset the recording
            manualOperation = true;
            trackManipulator->clear();
            trackManipulator->setTime(0);

            // Select the untitled path
            if ((trackFileArray.size() == 0) || (trackFileArray.last() != untitled)) {
                trackFileArray.append(untitled);
            }
            trackFileIndex = trackFileArray.size() - 1;

            saveButton->setEnabled(true);

        } else if (control == saveButton) {

            // Save
            std::string saveName;

            if (_internal::SaveDialog::getFilename(saveName, this)) {
                saveName = filenameBaseExt(trimWhitespace(saveName));

                if (saveName != "") {
                    saveName = saveName.substr(0, saveName.length() - filenameExt(saveName).length());

                    BinaryOutput b(saveName + ".trk", G3D_LITTLE_ENDIAN);
                    trackManipulator->spline().serialize(b);
                    b.commit();

                    updateTrackFiles();

                    // Select the one we just saved
                    trackFileIndex = iMax(0, trackFileArray.findIndex(saveName));
                    
                    saveButton->setEnabled(false);
                }
            }
        }
        sync();

    } else if (trackManipulator->mode() == UprightSplineManipulator::RECORD_KEY_MODE) {
        // Check if the user has added a point yet
        sync();
    }

    return false;
}
Exemplo n.º 10
0
void GuiFunctionBox::drawSpline(RenderDevice* rd, const GuiThemeRef& skin) const {
    (void)skin;
    int N = iMax((int)(m_bounds.width() / 4), 30);

#   if 0  // Debugging code for looking at the slope of the curve

    // Show desired tangents in green
    rd->beginPrimitive(PrimitiveType::LINES);
    rd->setColor(Color3::green() * 0.5);
    for (int j = 0; j < m_spline->control.size(); ++j) {
        float t, v, x, y;
        int i;

        i = j - 1;
        m_spline->getControl(i, t, v);
        x = m_bounds.x0() + m_bounds.width() * (t - m_minTime) / (m_maxTime - m_minTime);
        y = m_bounds.y1() - (v - m_minValue) / m_scale.y;

        Vector2 va(x, y);

        i = j;
        m_spline->getControl(i, t, v);
        x = m_bounds.x0() + m_bounds.width() * (t - m_minTime) / (m_maxTime - m_minTime);
        y = m_bounds.y1() - (v - m_minValue) / m_scale.y;

        Vector2 vb(x, y);

        i = j + 1;
        m_spline->getControl(i, t, v);
        x = m_bounds.x0() + m_bounds.width() * (t - m_minTime) / (m_maxTime - m_minTime);
        y = m_bounds.y1() - (v - m_minValue) / m_scale.y;

        Vector2 vc(x, y);

        Vector2 tangent = (vc - va).direction() * m_bounds.width() / (2 * m_spline->control.size());
        rd->sendVertex(vb - tangent);
        rd->sendVertex(vb + tangent);
    }
    rd->endPrimitive();

    // Show true tangents in blue
    rd->beginPrimitive(PrimitiveType::LINES);
    rd->setColor(Color3::blue());
    for (int i = 1; i < m_spline->control.size() - 1; ++i) {
        float t, v, x, y;

        float dt = (m_spline->time[i + 1] - m_spline->time[i - 1]) / 10;

        t = m_spline->time[i] - dt;
        v = m_spline->evaluate(t);
        x = m_bounds.x0() + m_bounds.width() * (t - m_minTime) / (m_maxTime - m_minTime);
        y = m_bounds.y1() - (v - m_minValue) / m_scale.y;

        Vector2 va(x, y);

        t = m_spline->time[i];
        v = m_spline->control[i];
        x = m_bounds.x0() + m_bounds.width() * (t - m_minTime) / (m_maxTime - m_minTime);
        y = m_bounds.y1() - (v - m_minValue) / m_scale.y;

        Vector2 vb(x, y);

        t = m_spline->time[i] + dt;
        v = m_spline->evaluate(t);
        x = m_bounds.x0() + m_bounds.width() * t - (m_minTime) / (m_maxTime - m_minTime);
        y = m_bounds.y1() - (v - m_minValue) / m_scale.y;

        Vector2 vc(x, y);

        Vector2 tangent = (vc - va).direction() * m_bounds.width() / (2 * m_spline->control.size());
        rd->sendVertex(vb - tangent);
        rd->sendVertex(vb + tangent);
    }
    rd->endPrimitive();
#   endif

    rd->beginPrimitive(PrimitiveType::LINE_STRIP);
        rd->setColor(m_splineColor);
        for (int i = -2; i < N + 2; ++i) {
            float t = (m_maxTime - m_minTime) * i / (N - 1.0f) + m_minTime;
            float v = m_spline->evaluate(t);
            
            float x = m_bounds.x0() + m_bounds.width() * i / (N - 1.0f);
            float y = m_bounds.y1() - (v - m_minValue) / m_scale.y;

            rd->sendVertex(Vector2(x, y));
        }
    rd->endPrimitive();

}
Exemplo n.º 11
0
// Modified version of the all purpose routine L2Project specifically written
// for projecting the "time-averaged" flux function onto the basis function.
//
// This routine also returns the coefficients of the Lax Wendroff Flux
// Function when expanded with legendre basis functions, and therefore the
// basis expansions produced by this routine can be used for all of the
// Riemann solves.
//
// ---------------------------------------------------------------------
// Inputs should have the following sizes:   
//           TODO - document the inputs here
// ---------------------------------------------------------------------
void L2ProjectLxW_Unst( const int mterms,
        const double alpha, const double beta_dt, const double charlie_dt,
        const int istart, const int iend,               // Start-stop indices
        const int QuadOrder,
        const int BasisOrder_qin,
        const int BasisOrder_auxin,
        const int BasisOrder_fout,
        const mesh& Mesh, 
        const dTensor3* qin, const dTensor3* auxin,     // state vector
        dTensor3* F, dTensor3* G,                       // time-averaged Flux function
        void FluxFunc (const dTensor2& xpts, 
            const dTensor2& Q, const dTensor2& Aux, dTensor3& flux),
        void DFluxFunc (const dTensor2& xpts, 
            const dTensor2& Q, const dTensor2& aux, dTensor4& Dflux),
        void D2FluxFunc (const dTensor2& xpts, 
            const dTensor2& Q, const dTensor2& aux, dTensor5& D2flux) )
{    

    if( fabs( alpha ) < 1e-14 && fabs( beta_dt ) < 1e-14 && fabs( charlie_dt ) < 1e-14 )
    {
        F->setall(0.);
        G->setall(0.);
        return;
    }

    // starting and ending indices 
    const int   NumElems = Mesh.get_NumElems();
    assert_ge(istart,1);
    assert_le(iend,NumElems);

    // qin variable
    assert_eq(NumElems,qin->getsize(1));
    const int     meqn = qin->getsize(2);
    const int kmax_qin = qin->getsize(3);
    assert_eq(kmax_qin,(BasisOrder_qin*(BasisOrder_qin+1))/2);

    // auxin variable
    assert_eq(NumElems,auxin->getsize(1));
    const int       maux = auxin->getsize(2);
    const int kmax_auxin = auxin->getsize(3);
    assert_eq(kmax_auxin,(BasisOrder_auxin*(BasisOrder_auxin+1))/2);

    // fout variables
    assert_eq(NumElems,    F->getsize(1));
    const int mcomps_out = F->getsize(2);
    const int  kmax_fout = F->getsize(3);
    assert_eq(kmax_fout, (BasisOrder_fout*(BasisOrder_fout+1))/2 );

    // number of quadrature points
    assert_ge(QuadOrder, 1);
    assert_le(QuadOrder, 5);

    // Number of quadrature points
    int mpoints;
    switch( QuadOrder )
    {
        case 1:
            mpoints = 1;
            break;

        case 2:
            mpoints = 3;
            break;

        case 3:
            mpoints = 6;
            break;

        case 4:
            mpoints = 12;
            break;

        case 5:	     
            mpoints = 16;
            break;
    }

    const int kmax = iMax(iMax(kmax_qin, kmax_auxin), kmax_fout);
    dTensor2  phi(mpoints, kmax); // Legendre basis (orthogonal)
    dTensor2 spts(mpoints, 2);    // List of quadrature points
    dTensor1 wgts(mpoints);       // List of quadrature weights

    setQuadPoints_Unst( QuadOrder, wgts, spts );

    // ---------------------------------------------------------------------- //
    // Evaluate the basis functions at each point
    SetLegendreAtPoints_Unst(spts, phi);
    // ---------------------------------------------------------------------- //

    // ---------------------------------------------------------------------- //
    // First-order derivatives
    dTensor2 phi_xi (mpoints, kmax );
    dTensor2 phi_eta(mpoints, kmax );
    SetLegendreGrad_Unst( spts, phi_xi, phi_eta );
    // ---------------------------------------------------------------------- //

    // ---------------------------------------------------------------------- //
    // Second-order derivatives
    dTensor2 phi_xi2  (mpoints, kmax );
    dTensor2 phi_xieta(mpoints, kmax );
    dTensor2 phi_eta2 (mpoints, kmax );
    LegendreDiff2_Unst(spts, &phi_xi2, &phi_xieta, &phi_eta2 );
    // ---------------------------------------------------------------------- //

    // ------------------------------------------------------------- //
    // Loop over every grid cell indexed by user supplied parameters //
    // described by istart...iend, jstart...jend                     // 
    // ------------------------------------------------------------- //
#pragma omp parallel for
    for (int i=istart; i<=iend; i++)
    {

        // These need to be defined locally.  Each mesh element carries its
        // own change of basis matrix, so these need to be recomputed for
        // each element.  The canonical derivatives, phi_xi, and phi_eta can
        // be computed and shared for each element.

        // First-order derivatives
        dTensor2   phi_x(mpoints, kmax_fout);   //   x-derivative of Legendre basis (orthogonal)
        dTensor2   phi_y(mpoints, kmax_fout);   //   y-derivative of Legendre basis (orthogonal)

        // Second-order derivatives
        dTensor2   phi_xx(mpoints, kmax_fout);   //   xx-derivative of Legendre basis (orthogonal)
        dTensor2   phi_xy(mpoints, kmax_fout);   //   xy-derivative of Legendre basis (orthogonal)
        dTensor2   phi_yy(mpoints, kmax_fout);   //   yy-derivative of Legendre basis (orthogonal)

        //find center of current cell
        const int    i1 = Mesh.get_tnode(i,1);
        const int    i2 = Mesh.get_tnode(i,2);
        const int    i3 = Mesh.get_tnode(i,3);

        // Corners:
        const double x1 = Mesh.get_node(i1,1);
        const double y1 = Mesh.get_node(i1,2);
        const double x2 = Mesh.get_node(i2,1);
        const double y2 = Mesh.get_node(i2,2);
        const double x3 = Mesh.get_node(i3,1);
        const double y3 = Mesh.get_node(i3,2);

        // Center of current cell:
        const double xc = (x1+x2+x3)/3.0;
        const double yc = (y1+y2+y3)/3.0;

        // Variables that need to be written to, and therefore are 
        // created for each thread
        dTensor2 xpts   (mpoints, 2);
        dTensor2 qvals  (mpoints, meqn);
        dTensor2 auxvals(mpoints, maux);

        // local storage for Flux function its Jacobian, and the Hessian:
        dTensor3    fvals(mpoints,             meqn, 2);  // flux function (vector)
        dTensor4        A(mpoints,       meqn, meqn, 2);  // Jacobian of flux
        dTensor5        H(mpoints, meqn, meqn, meqn, 2);  // Hessian of flux

        // Compute q, aux and fvals at each Gaussian Quadrature point
        // for this current cell indexed by (i,j)
        // Save results into dTensor2 qvals, auxvals and fvals.
        for (int m=1; m<= mpoints; m++)
        {

            // convert phi_xi and phi_eta derivatives
            // to phi_x and phi_y derivatives through Jacobian
            //
            // Note that: 
            //
            //     pd_x = J11 pd_xi + J12 pd_eta and
            //     pd_y = J21 pd_xi + J22 pd_eta.
            //
            // Squaring these operators yields the second derivatives.
            for (int k=1; k<=kmax_fout; k++)
            {
                phi_x.set(m,k, Mesh.get_jmat(i,1,1)*phi_xi.get(m,k)
                             + Mesh.get_jmat(i,1,2)*phi_eta.get(m,k) );
                phi_y.set(m,k, Mesh.get_jmat(i,2,1)*phi_xi.get(m,k)
                             + Mesh.get_jmat(i,2,2)*phi_eta.get(m,k) );

                phi_xx.set(m,k, Mesh.get_jmat(i,1,1)*Mesh.get_jmat(i,1,1)*phi_xi2.get(m,k)
                              + Mesh.get_jmat(i,1,1)*Mesh.get_jmat(i,1,2)*phi_xieta.get(m,k)
                              + Mesh.get_jmat(i,1,2)*Mesh.get_jmat(i,1,2)*phi_eta2.get(m,k)
                           );

                phi_xy.set(m,k, Mesh.get_jmat(i,1,1)*Mesh.get_jmat(i,2,1)*phi_xi2.get(m,k)
                             +(Mesh.get_jmat(i,1,2)*Mesh.get_jmat(i,2,1)
                             + Mesh.get_jmat(i,1,1)*Mesh.get_jmat(i,2,2))*phi_xieta.get(m,k)
                             + Mesh.get_jmat(i,1,2)*Mesh.get_jmat(i,2,2)*phi_eta2.get(m,k)
                           );

                phi_yy.set(m,k, Mesh.get_jmat(i,2,1)*Mesh.get_jmat(i,2,1)*phi_xi2.get(m,k)
                              + Mesh.get_jmat(i,2,1)*Mesh.get_jmat(i,2,2)*phi_xieta.get(m,k)
                              + Mesh.get_jmat(i,2,2)*Mesh.get_jmat(i,2,2)*phi_eta2.get(m,k)
                           );
            }

            // point on the unit triangle
            const double s = spts.get(m,1);
            const double t = spts.get(m,2);

            // point on the physical triangle
            xpts.set(m,1, xc + (x2-x1)*s + (x3-x1)*t );
            xpts.set(m,2, yc + (y2-y1)*s + (y3-y1)*t );

            // Solution values (q) at each grid point
            for (int me=1; me<=meqn; me++)
            {
                qvals.set(m,me, 0.0 );
                for (int k=1; k<=kmax_qin; k++)
                {
                    qvals.set(m,me, qvals.get(m,me) 
                            + phi.get(m,k) * qin->get(i,me,k) );
                }
            }

            // Auxiliary values (aux) at each grid point
            for (int ma=1; ma<=maux; ma++)
            {
                auxvals.set(m,ma, 0.0 );
                for (int k=1; k<=kmax_auxin; k++)
                {
                    auxvals.set(m,ma, auxvals.get(m,ma) 
                            + phi.get(m,k) * auxin->get(i,ma,k) );
                }
            } 
        }

        // ----------------------------------------------------------------- //
        //
        // Part I:
        //
        // Project the flux function onto the basis 
        // functions.  This is the term of order O( 1 ) in the
        // "time-averaged" Taylor expansion of f and g.
        //
        // ----------------------------------------------------------------- //

        // Call user-supplied function to set fvals
        FluxFunc(xpts, qvals, auxvals, fvals);

        // Evaluate integral on current cell (project onto Legendre basis) 
        // using Gaussian Quadrature for the integration
        //
        // TODO - do we want to optimize this by looking into using transposes,
        // as has been done in the 2d/cart code? (5/14/2014) -DS
        for (int me=1; me<=mcomps_out; me++)		
        for (int k=1; k<=kmax; k++)
        {
            double tmp1 = 0.0;
            double tmp2 = 0.0;
            for (int mp=1; mp <= mpoints; mp++)
            {
                tmp1 += wgts.get(mp)*fvals.get(mp, me, 1)*phi.get(mp, k);
                tmp2 += wgts.get(mp)*fvals.get(mp, me, 2)*phi.get(mp, k);
            }
            F->set(i, me, k,  2.0*tmp1 );
            G->set(i, me, k,  2.0*tmp2 );
        }

        // ----------------------------------------------------------------- //
        //
        // Part II:
        //
        // Project the derivative of the flux function onto the basis 
        // functions.  This is the term of order O( \dt ) in the
        // "time-averaged" Taylor expansion of f and g.
        //
        // ----------------------------------------------------------------- //

        // ----------------------------------------------------------------- //
        // Compute pointwise values for fx+gy:
        //
        // We can't multiply fvals of f, and g,
        // by alpha, otherwise we compute the wrong derivative here!
        //
        dTensor2 fx_plus_gy( mpoints, meqn ); fx_plus_gy.setall(0.);
        for( int mp=1; mp <= mpoints; mp++ )
        for( int me=1; me <= meqn; me++ )
        {
            double tmp = 0.;
            for( int k=2; k <= kmax; k++ )                
            {
                tmp += F->get( i, me, k ) * phi_x.get( mp, k );
                tmp += G->get( i, me, k ) * phi_y.get( mp, k );
            }
            fx_plus_gy.set( mp, me, tmp );
        }

        // Call user-supplied Jacobian to set f'(q) and g'(q):
        DFluxFunc( xpts, qvals, auxvals, A );

        // place-holders for point values of
        // f'(q)( fx + gy ) and g'(q)( fx + gy ):
        dTensor2 dt_times_fdot( mpoints, meqn );
        dTensor2 dt_times_gdot( mpoints, meqn );

        // Compute point values for f'(q) * (fx+gy) and g'(q) * (fx+gy):
        for( int mp=1; mp <= mpoints; mp++ )
        for( int m1=1; m1 <= meqn; m1++ )
        {
            double tmp1 = 0.;
            double tmp2 = 0.;
            for( int m2=1; m2 <= meqn; m2++ )
            {
                tmp1 += A.get(mp, m1, m2, 1 ) * fx_plus_gy.get(mp, m2);
                tmp2 += A.get(mp, m1, m2, 2 ) * fx_plus_gy.get(mp, m2);
            }
            dt_times_fdot.set( mp, m1, -beta_dt*tmp1 );
            dt_times_gdot.set( mp, m1, -beta_dt*tmp2 );
        }

        // ---  Third-order terms --- //
        //
        // These are the terms that are O( \dt^2 ) in the "time-averaged"
        // flux function.
        dTensor2 f_tt( mpoints, meqn );   f_tt.setall(0.);
        dTensor2 g_tt( mpoints, meqn );   g_tt.setall(0.);
        if( mterms > 2 )
        {

            // Construct the Hessian at each (quadrature) point
            D2FluxFunc( xpts, qvals, auxvals, H );

            // Second-order derivative terms
            dTensor2 qx_vals (mpoints, meqn);   qx_vals.setall(0.);
            dTensor2 qy_vals (mpoints, meqn);   qy_vals.setall(0.);

            dTensor2 fxx_vals(mpoints, meqn);   fxx_vals.setall(0.);
            dTensor2 gxx_vals(mpoints, meqn);   gxx_vals.setall(0.);

            dTensor2 fxy_vals(mpoints, meqn);   fxy_vals.setall(0.);
            dTensor2 gxy_vals(mpoints, meqn);   gxy_vals.setall(0.);

            dTensor2 fyy_vals(mpoints, meqn);   fyy_vals.setall(0.);
            dTensor2 gyy_vals(mpoints, meqn);   gyy_vals.setall(0.);

            for( int m=1; m <= mpoints; m++ )
            for( int me=1; me <= meqn; me++ )
            {
                // Can start at k=1, because derivative of a constant is
                // zero.
                double tmp_qx = 0.;
                double tmp_qy = 0.;
                for( int  k=2; k <= kmax; k++   )
                {
                    tmp_qx += phi_x.get(m,k) * qin->get(i,me,k);
                    tmp_qy += phi_y.get(m,k) * qin->get(i,me,k);
                }
                qx_vals.set(m,me, tmp_qx );
                qy_vals.set(m,me, tmp_qy );

                // First non-zero terms start at third-order.
                for( int  k=4; k <= kmax; k++   )
                {
                    fxx_vals.set(m,me, fxx_vals.get(m,me) + phi_xx.get(m,k)*F->get(i,me,k) );
                    gxx_vals.set(m,me, gxx_vals.get(m,me) + phi_xx.get(m,k)*G->get(i,me,k) );

                    fxy_vals.set(m,me, fxy_vals.get(m,me) + phi_xy.get(m,k)*F->get(i,me,k) );
                    gxy_vals.set(m,me, gxy_vals.get(m,me) + phi_xy.get(m,k)*G->get(i,me,k) );

                    fyy_vals.set(m,me, fyy_vals.get(m,me) + phi_yy.get(m,k)*F->get(i,me,k) );
                    gyy_vals.set(m,me, gyy_vals.get(m,me) + phi_yy.get(m,k)*G->get(i,me,k) );
                }

            }

            // ----------------------------------- //
            // Part I: Compute (f_x + g_y)_{,t}
            // ----------------------------------- //

            // Compute terms that get multiplied by \pd2{ f }{ q } and \pd2{ g }{ q }.
            dTensor2 fx_plus_gy_t( mpoints, meqn );
            for( int  m = 1;  m <= mpoints; m++ )
            for( int me = 1; me <= meqn; me++   )
            {

                double tmp = 0.;

                // Terms that get multiplied by the Hessian:
                for( int m1=1; m1 <= meqn; m1++ )
                for( int m2=1; m2 <= meqn; m2++ )
                {

                    tmp += H.get(m,me,m1,m2,1)*qx_vals.get(m,m1)*fx_plus_gy.get(m,m2);
                    tmp += H.get(m,me,m1,m2,2)*qy_vals.get(m,m1)*fx_plus_gy.get(m,m2);
                }

                // Terms that get multiplied by f'(q) and g'(q):
                for( int m1=1; m1 <= meqn; m1++ )
                {

                    tmp += A.get(m,me,m1,1)*( fxx_vals.get(m,m1)+gxy_vals.get(m,m1) );
                    tmp += A.get(m,me,m1,2)*( fxy_vals.get(m,m1)+gyy_vals.get(m,m1) );
                }

                fx_plus_gy_t.set( m, me, tmp );
            }

            // ----------------------------------- //
            // Part II: Compute 
            //      f'(q) * fx_plus_gy_t and 
            //      g'(q) * fx_plus_gy_t
            // ----------------------------------- //

            // Add in the third term that gets multiplied by A:
            for( int m=1; m <= mpoints; m++ )
            for( int m1=1; m1 <= meqn; m1++ )
            {
                double tmp1 = 0.;
                double tmp2 = 0.;
                for( int m2=1; m2 <= meqn; m2++ )
                {
                    tmp1 += A.get(m,m1,m2,1)*fx_plus_gy_t.get(m,m2);
                    tmp2 += A.get(m,m1,m2,2)*fx_plus_gy_t.get(m,m2);
                }
                f_tt.set( m, m1, tmp1 );
                g_tt.set( m, m1, tmp2 );
            }

            // ----------------------------------------------- //
            // Part III: Add in contributions from
            //      f''(q) * (fx_plus_gy, fx_plus_gy ) and 
            //      g''(q) * (fx_plus_gy, fx_plus_gy ).
            // ----------------------------------------------- //
            for( int m =1; m <= mpoints; m++ )
            for( int me =1; me <= meqn; me++ )
            {
                double tmp1 = 0.;
                double tmp2 = 0.;

                // Terms that get multiplied by the Hessian:
                for( int m1=1; m1 <= meqn; m1++ )
                for( int m2=1; m2 <= meqn; m2++ )
                {
                    tmp1 += H.get(m,me,m1,m2,1)*fx_plus_gy.get(m,m1)*fx_plus_gy.get(m,m2);
                    tmp2 += H.get(m,me,m1,m2,2)*fx_plus_gy.get(m,m1)*fx_plus_gy.get(m,m2);
                }

                f_tt.set( m, me, f_tt.get(m,me) + tmp1 );
                g_tt.set( m, me, g_tt.get(m,me) + tmp2 );
            }

        } // End of computing "third"-order terms

        // ---------------------------------------------------------- //
        // 
        // Construct basis coefficients (integrate_on_current_cell)
        //
        // ---------------------------------------------------------- //
        for (int me=1; me<=mcomps_out; me++)		
        for (int k=1; k<=kmax; k++)
        {

            double tmp1 = 0.0;
            double tmp2 = 0.0;
            for (int mp=1; mp<=mpoints; mp++)
            {
                tmp1 += wgts.get(mp)*phi.get(mp,k)*(
                    dt_times_fdot.get(mp, me) + charlie_dt*f_tt.get(mp, me) );
                tmp2 += wgts.get(mp)*phi.get(mp,k)*(
                    dt_times_gdot.get(mp, me) + charlie_dt*g_tt.get(mp, me) );
            }
            F->set(i,me,k,  F->get(i,me,k) + 2.0*tmp1 );
            G->set(i,me,k,  G->get(i,me,k) + 2.0*tmp2 );

        }

    }

}