LDFE_quad::LDFE_quad(int param) {
    
    /* Calculate number of LDFE ranges */
    order = param;                    // Quadrature order
    int num_LDFE = 2 * pow(2, order); // Number of LDFE regions
    
    /* Calculate quadrature directions */
    double delta_gamma = (pi / num_LDFE) / 4.0;            // Gamma from node to nearest LDFE edge
    double gamma_current = 0.0;
    mat gamma(num_LDFE, 2);
    for (int i=0; i<num_LDFE; i++) {
        gamma(i, 0) = gamma_current + delta_gamma;         // Left node gamma
        gamma(i, 1) = gamma(i, 0) + 2.0 * delta_gamma;     // Right node gamma
        gamma_current = gamma_current + 4.0 * delta_gamma;
    }
    
    /* Solve the basis functions of each LDFE range */
    mat A = mat(2, 2);
    mat B = eye<mat>(2, 2);
    mat C = mat(3, 3);
    vec wgt = vec(2);
    wgts.set_size(num_LDFE, 2);          // Resize matrix storing all LDFE range weights
    dirs.set_size(num_LDFE, 2);          // Resize matrix storing all LDFE range directions
    basis.resize(num_LDFE);              // Resize vector storing all LDFE basis functions
    for (int i=0; i<num_LDFE; i++){
        for (int j=0; j<2; j++){
            A(j, 0) = 1.0;
            A(j, 1) = cos(gamma(i, j));
        }
        C = solve(A, B);                 // Solve for the basis functions

        /* Solve for the weights of each LDFE range */
        double gamma_max = gamma(i, 1) + delta_gamma;
        double gamma_min = gamma(i, 0) - delta_gamma;
        for (int j=0; j<2; j++){
            wgt(j) = C(0, j) * (gamma_max - gamma_min) + \
                     C(1, j) * (sin(gamma_max) - sin(gamma_min));
        }

        /* Store quadrature directions, weights and basis functions */
        for (int j=0; j<2; j++) {
            dirs(i, j) = cos(gamma(i, j));
            wgts(i, j) = wgt(j) / pi * 2.0;
        }
        basis[i] = C;
    }
}
Beispiel #2
0
void
OnTouchDown_RequestToTopFocused(CursorEventArgs&& e)
{
    IWidget& wgt(e.GetSender());

    if(e.Strategy != RoutedEventArgs::Bubble)
        RequestToTop(wgt);
    if(e.Strategy == RoutedEventArgs::Direct)
        ClearFocusingOf(wgt);
    if(e.Strategy != RoutedEventArgs::Tunnel)
        RequestFocus(wgt);
}
int WalkerControlBase::doNotBranch(int iter, MCWalkerConfiguration& W)
{
    MCWalkerConfiguration::iterator it(W.begin());
    MCWalkerConfiguration::iterator it_end(W.end());
    RealType esum=0.0,e2sum=0.0,wsum=0.0,ecum=0.0, w2sum=0.0;
    RealType r2_accepted=0.0,r2_proposed=0.0;
    for(; it!=it_end; ++it)
    {
        r2_accepted+=(*it)->Properties(R2ACCEPTED);
        r2_proposed+=(*it)->Properties(R2PROPOSED);
        RealType e((*it)->Properties(LOCALENERGY));
        int nc= std::min(static_cast<int>((*it)->Multiplicity),MaxCopy);
        RealType wgt((*it)->Weight);
        esum += wgt*e;
        e2sum += wgt*e*e;
        wsum += wgt;
        w2sum += wgt*wgt;
        ecum += e;
    }

    //temp is an array to perform reduction operations
    std::fill(curData.begin(),curData.end(),0);

    curData[ENERGY_INDEX]=esum;
    curData[ENERGY_SQ_INDEX]=e2sum;
    curData[WALKERSIZE_INDEX]=W.getActiveWalkers();
    curData[WEIGHT_INDEX]=wsum;
    curData[EREF_INDEX]=ecum;
    curData[R2ACCEPTED_INDEX]=r2_accepted;
    curData[R2PROPOSED_INDEX]=r2_proposed;

    myComm->allreduce(curData);

    measureProperties(iter);
    trialEnergy=EnsembleProperty.Energy;
    W.EnsembleProperty=EnsembleProperty;

    //return the current data
    return W.getGlobalNumWalkers();
}
  /** evaluate curData and mark the bad/good walkers
   */
  int WalkerControlBase::sortWalkers(MCWalkerConfiguration& W) {

    MCWalkerConfiguration::iterator it(W.begin());

    vector<Walker_t*> bad,good_rn;
    vector<int> ncopy_rn;
    NumWalkers=0;
    MCWalkerConfiguration::iterator it_end(W.end());
    RealType esum=0.0,e2sum=0.0,wsum=0.0,ecum=0.0, w2sum=0.0, besum=0.0, bwgtsum=0.0;
    RealType r2_accepted=0.0,r2_proposed=0.0;
    int nrn(0),ncr(0);
    while(it != it_end) 
    {
      bool inFN=(((*it)->ReleasedNodeAge)==0);
      if ((*it)->ReleasedNodeAge==1) ncr+=1;
      int nc= std::min(static_cast<int>((*it)->Multiplicity),MaxCopy);
      r2_accepted+=(*it)->Properties(R2ACCEPTED);
      r2_proposed+=(*it)->Properties(R2PROPOSED);
      RealType e((*it)->Properties(LOCALENERGY));
      RealType bfe((*it)->Properties(ALTERNATEENERGY));
      RealType rnwgt(0.0);
      if (inFN)
        rnwgt=((*it)->Properties(SIGN));
      
//       RealType wgt((*it)->Weight);
      RealType wgt(0.0);
      if (inFN)
        wgt=((*it)->Weight); 
      
      esum += wgt*e;
      e2sum += wgt*e*e;
      wsum += wgt;
      w2sum += wgt*wgt;
      ecum += e;
      besum += bfe*rnwgt*wgt;
      bwgtsum += rnwgt*wgt;

      if((nc) && (inFN))
      {
        NumWalkers += nc;
        good_w.push_back(*it);
        ncopy_w.push_back(nc-1);
      }
      else if (nc)
      {
        NumWalkers += nc;
        nrn+=nc;
        good_rn.push_back(*it);
        ncopy_rn.push_back(nc-1);
      }
      else
      {
        bad.push_back(*it);
      }
      ++it;
    }

    //temp is an array to perform reduction operations
    std::fill(curData.begin(),curData.end(),0);

    //update curData
    curData[ENERGY_INDEX]=esum;
    curData[ENERGY_SQ_INDEX]=e2sum;
    curData[WALKERSIZE_INDEX]=W.getActiveWalkers();
    curData[WEIGHT_INDEX]=wsum;
    curData[EREF_INDEX]=ecum;
    curData[R2ACCEPTED_INDEX]=r2_accepted;
    curData[R2PROPOSED_INDEX]=r2_proposed;
    curData[FNSIZE_INDEX]=static_cast<RealType>(good_w.size());
    curData[RNONESIZE_INDEX]=static_cast<RealType>(ncr);
    curData[RNSIZE_INDEX]=nrn;
    curData[B_ENERGY_INDEX]=besum;
    curData[B_WGT_INDEX]=bwgtsum;
    
    ////this should be move
    //W.EnsembleProperty.NumSamples=curData[WALKERSIZE_INDEX];
    //W.EnsembleProperty.Weight=curData[WEIGHT_INDEX];
    //W.EnsembleProperty.Energy=(esum/=wsum);
    //W.EnsembleProperty.Variance=(e2sum/wsum-esum*esum);
    //W.EnsembleProperty.Variance=(e2sum*wsum-esum*esum)/(wsum*wsum-w2sum);

    //remove bad walkers empty the container
    for(int i=0; i<bad.size(); i++) delete bad[i];
    if (!WriteRN)
    {
     if(good_w.empty()) {
      app_error() << "All the walkers have died. Abort. " << endl;
      APP_ABORT("WalkerControlBase::sortWalkers");
     }

     int sizeofgood = good_w.size();
     //check if the projected number of walkers is too small or too large
     if(NumWalkers>Nmax) {
      int nsub=0;
      int nsub_target=(NumWalkers-nrn)-static_cast<int>(0.9*Nmax);
      int i=0;
      while(i< sizeofgood && nsub<nsub_target) {
        if(ncopy_w[i]) {ncopy_w[i]--; nsub++;}
        ++i;
      }
      NumWalkers -= nsub;
     } else  if(NumWalkers < Nmin) {
      int nadd=0;
      int nadd_target = static_cast<int>(Nmin*1.1)-(NumWalkers-nrn);
      if(nadd_target> sizeofgood) {
        app_warning() << "The number of walkers is running low. Requested walkers " 
          << nadd_target << " good walkers = " << sizeofgood << endl;
      }
      int i=0;
      while(i< sizeofgood && nadd<nadd_target) {
        ncopy_w[i]++; ++nadd;++i;
      }
      NumWalkers +=  nadd;
     }
    }
    else
    {
    it=good_rn.begin(); it_end=good_rn.end();
    int indy(0);
    while(it!=it_end) {
      good_w.push_back(*it);
      ncopy_w.push_back(ncopy_rn[indy]);
      it++,indy++;
    }
    }
    return NumWalkers;
  }
  int WalkerControlBase::doNotBranch(int iter, MCWalkerConfiguration& W)
  {
    MCWalkerConfiguration::iterator it(W.begin());
    MCWalkerConfiguration::iterator it_end(W.end());
    RealType esum=0.0,e2sum=0.0,wsum=0.0,ecum=0.0, w2sum=0.0, besum=0.0, bwgtsum=0.0;
    RealType r2_accepted=0.0,r2_proposed=0.0;
    int nrn(0),ncr(0),nfn(0),ngoodfn(0);
    for(; it!=it_end;++it)
    {
      bool inFN=(((*it)->ReleasedNodeAge)==0);
      int nc= std::min(static_cast<int>((*it)->Multiplicity),MaxCopy);
      
      if ((*it)->ReleasedNodeAge==1) ncr+=1;
      else if ((*it)->ReleasedNodeAge==0) 
      {
        nfn+=1;
        ngoodfn+=nc;
      }
      
      r2_accepted+=(*it)->Properties(R2ACCEPTED);
      r2_proposed+=(*it)->Properties(R2PROPOSED);
      RealType e((*it)->Properties(LOCALENERGY));
      RealType bfe((*it)->Properties(ALTERNATEENERGY));
      RealType rnwgt(0.0);
      if (inFN)
        rnwgt=((*it)->Properties(SIGN));
      else
        nrn+=nc;
      //       RealType wgt((*it)->Weight);
      RealType wgt(0.0);
      if (inFN)
        wgt=((*it)->Weight); 
      
      esum += wgt*e;
      e2sum += wgt*e*e;
      wsum += wgt;
      w2sum += wgt*wgt;
      ecum += e;
      besum += bfe*rnwgt*wgt;
      bwgtsum += rnwgt*wgt;
    }

    //temp is an array to perform reduction operations
    std::fill(curData.begin(),curData.end(),0);

    curData[ENERGY_INDEX]=esum;
    curData[ENERGY_SQ_INDEX]=e2sum;
    curData[WALKERSIZE_INDEX]=W.getActiveWalkers();
    curData[WEIGHT_INDEX]=wsum;
    curData[EREF_INDEX]=ecum;
    curData[R2ACCEPTED_INDEX]=r2_accepted;
    curData[R2PROPOSED_INDEX]=r2_proposed;
    curData[FNSIZE_INDEX]=static_cast<RealType>(nfn);
    curData[RNONESIZE_INDEX]=static_cast<RealType>(ncr);
    curData[RNSIZE_INDEX]=nrn;
    curData[B_ENERGY_INDEX]=besum;
    curData[B_WGT_INDEX]=bwgtsum;

    myComm->allreduce(curData);

    measureProperties(iter);
    trialEnergy=EnsembleProperty.Energy;
    W.EnsembleProperty=EnsembleProperty;

    return W.getActiveWalkers();
  }
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));
                  }*/ 
            }
        }

      }
    }

}
LDFE_quad_eq::LDFE_quad_eq(int param) {
    
    /* Calculate number of LDFE ranges */
    order = param;                    // Quadrature order
    int num_LDFE = 2 * pow(2, order); // Number of LDFE regions
    
    /* Calculate even quadrature weights */
    double delta_gamma = pi / num_LDFE;
    double wgt_even = delta_gamma / 2.0;
    
    /* Initialize common parameters */
    double gamma_current = 0.0;
    double gamma_min;
    double gamma_max;
    double gamma_center;
    vec dir = vec(2);
    mat A = mat(2, 2);
    mat B = eye<mat>(2, 2);
    mat C = mat(3, 3);
    vec wgt = vec(2);
    wgts.set_size(num_LDFE, 2);   // Resize matrix storing all LDFE range weights
    dirs.set_size(num_LDFE, 2);   // Resize matrix storing all LDFE range directions
    basis.resize(num_LDFE);       // Resize vector storing all LDFE basis functions
    double RE_old;
    double RE_new;
    double ratio_old;
    double ratio_new;
    double ratio_temp;
    int converged;
    int iter_counter;
    double delta;
    for (int r=0; r<num_LDFE; r++) {
        
        /* First quadrature direction guess */
        gamma_min = gamma_current;
        gamma_max = gamma_current + delta_gamma;
        gamma_current = gamma_max;
        gamma_center = (gamma_max + gamma_min) / 2.0;
        ratio_old = 0.5;
        dir(0) = gamma_center - ratio_old * delta_gamma / 2.0;
        dir(1) = gamma_center + ratio_old * delta_gamma / 2.0;
        
        /* Solve for basis functions */
        for (int j=0; j<2; j++){
            A(j, 0) = 1.0;
            A(j, 1) = cos(dir(j));
        }
        C = solve(A, B); // Solve for the basis functions
        
        /* Solve for weights */
        for (int j=0; j<2; j++){
            wgt(j) = C(0, j) * (gamma_max - gamma_min) + \
                     C(1, j) * (sin(gamma_max) - sin(gamma_min));
        }
        
        /* Calculate relative error using first direction guess */
        RE_old = (wgt(0) - wgt_even) / wgt_even;
        
        /* Second ratio guess */
        ratio_new = 0.75;
        
        /* Iterate until weights are equal */
        converged = 0;
        iter_counter = 0;
        while (converged == 0 && iter_counter < 100) {
            
            /* New quadrature directions */
            dir(0) = gamma_center - ratio_new * delta_gamma / 2.0;
            dir(1) = gamma_center + ratio_new * delta_gamma / 2.0;
            
            /* New quadrature basis functions */
            for (int j=0; j<2; j++){
                A(j, 0) = 1.0;
                A(j, 1) = cos(dir(j));
            }
            C = solve(A, B); // Solve for the basis functions
            
            /* New quadrature weights */
            for (int j=0; j<2; j++){
                wgt(j) = C(0, j) * (gamma_max - gamma_min) + \
                         C(1, j) * (sin(gamma_max) - sin(gamma_min));
            }
            
            /* Calculate new relative error */
            RE_new = (wgt(0) - wgt_even) / wgt_even;
            
            /* Calculate next direction guess */
            if (RE_old == RE_new && iter_counter == 1) {
                ratio_temp = ratio_new;
                ratio_new = (ratio_old + ratio_new) / 2.0;
                ratio_old = ratio_temp;
                iter_counter++;
            }
            else {
                delta = ((ratio_new - ratio_old) / (RE_new - RE_old)) * RE_new;
                
                /* Check for convergence */
                if (abs(delta) < 1.e-12) {
                    converged = 1;
                }
                else {
                    RE_old = RE_new;
                    ratio_old = ratio_new;
                    ratio_new = ratio_new - delta;
                    iter_counter++;
                }
            }
        }
        
        /* Store quadrature directions, weights and basis functions */
        for (int j=0; j<2; j++) {
            dirs(r, j) = cos(dir(j));
            wgts(r, j) = wgt(j) / pi * 2.0;
        }
        basis[r] = C;
    }
}
Beispiel #8
0
// semi-lagrangian solver
void DogSolverCart2::DogSolveUser(double tstart, double tend)
{

    // this accomodates the maximum number of stages allowed for the
    // split method ... and is a work in progress ...
    const int MAX_STAGES = 13;

    const edge_data& EdgeData = Legendre2d::instance().get_edgeData();
    dTensorBC3& smax = fetch_smax();
    DogStateCart2* dogStateCart2 = &fetch_state();

    dTensorBC4& qnew = fetch_state().fetch_q();
    dTensorBC4& qold = fetch_state_old().fetch_q();
    dTensorBC4& aux  = fetch_state().fetch_aux();

    const int nv = dogParams.get_nv();
    const double* cflv = dogParams.get_cflv();
    // --------------------------------------------------------------
    // define local variables
    int m_accept;
    const int mx   = qnew.getsize(1);
    const int my   = qnew.getsize(2);
    const int maux = aux.getsize(3);
    const int meqn = qnew.getsize(3);
    const int kmax = qnew.getsize(4);
    const int mbc  = qnew.getmbc();

    const int ndims = 2;

    int n_step = 0;
    double t = tstart;
    double tn = t;
    double told = 0.0;
    double dt = get_dt();
    const double CFL_max = cflv[1];
    const double CFL_target = cflv[2];
    double cfl = 0.0;
    double dtmin = dt;
    double dtmax = dt;

    dTensorBC4   qstar(mx,my,meqn,kmax,mbc);    //temporary place holder
    dTensorBC4 aux_old(mx,my,maux,kmax,mbc);

    //////////////////////////////////////////////////////////////////////////
    // Setup for manipulating velocities.  Store 2 arrays, 1 for each velocity
    //////////////////////////////////////////////////////////////////////////
    // array for storing advection speeds in each cell
    const int mpoints   = int((1+4*kmax-int(sqrt(1+8*kmax)))/2);
    const int mpoints1d = int(sqrt(mpoints));
    const int morder = mpoints1d;
    dTensorBC2 u1(my, mpoints1d,  mbc, ndims-1);    // speed, u(y) (ndims == 1 )
    dTensorBC2 u2(mx, mpoints1d,  mbc, ndims-1);    // speed, v(x) (ndims == 1 )

    ////////Set up any extra state variables associated with this problem /////
    SL_state sl_state;
    sl_state.split_time = new dTensor2(MAX_STAGES, 2);
    sl_state.aux1d      = new dTensorBC4( Max(mx,my), 2, 4, mpoints1d, mbc, 1);
    sl_state.node1d     = new dTensor2(mx+1,1);
    for( int i=1; i <=(mx+1); i++)
    { sl_state.node1d->set(i, 1, dogParamsCart2.get_xl(i) ); }

    sl_state.qold = &qold;
    sl_state.qnew = &qnew;

    const double dx = dogParamsCart2.get_dx();
    const double dy = dogParamsCart2.get_dy();

    // sample grid points (gauss points)
    dTensor2* spts = new dTensor2(mpoints, 2);

    //legendre polys evaluated at spts
    dTensor2 phi(mpoints, kmax);
    dTensor1 x1d(mpoints1d);
    dTensor1 wgt(mpoints1d);

    void setGaussPoints1d(dTensor1& w1d, dTensor1& x1d);
    setGaussPoints1d(wgt, x1d);

    // Tensor product Gaussian Quadrature
    //  See note at top of code in how mpoints are arranged here...
    int k=0;
    for (int m1=1; m1<=(mpoints1d); m1++)
    for (int m2=1; m2<=(mpoints1d); m2++)
    {

        k = k+1;

        //save gauss quad grid point location on interval [-1,1]^2
        spts->set(k,2, x1d.get(m1) );
        spts->set(k,1, x1d.get(m2) );
    }

    //evaluate the legendre polynomials at sample points
    for(int m=1; m <= mpoints; m++)
    {

        double xi, xi2,xi3,xi4, eta, eta2,eta3,eta4;

        //find xi and eta (point to be evaluated)
        xi = spts->get(m,1);
        eta = spts->get(m,2);
        xi2 = xi*xi;
        xi3 = xi*xi2;
        xi4 = xi*xi3;
        eta2 = eta*eta;
        eta3 = eta*eta2;
        eta4 = eta*eta3;

        // Legendre basis functions evaluated at (xi,eta) in the
        // interval [-1,1]x[-1,1].
        switch( mpoints1d )
        {
            case 5:  // fifth order
                phi.set( m,15, 105.0/8.0*eta4 - 45.0/4.0*eta2 + 9.0/8.0 );
                phi.set( m,14, 105.0/8.0*xi4  - 45.0/4.0*xi2  + 9.0/8.0 );
                phi.set( m,13, 5.0/4.0*(3.0*xi2 - 1.0)*(3.0*eta2 - 1.0) );
                phi.set( m,12, sq3*sq7*(2.5*eta3 - 1.5*eta)*xi );
                phi.set( m,11, sq3*sq7*(2.5*xi3 - 1.5*xi)*eta );

            case 4:  // fourth order
                phi.set( m,10, sq7*(2.5*eta3 - 1.5*eta) );
                phi.set( m,9,  sq7*(2.5*xi3 - 1.5*xi) );
                phi.set( m,8,  sq3*sq5*xi*(1.5*eta2 - 0.5) );
                phi.set( m,7,  sq3*sq5*eta*(1.5*xi2 - 0.5) );

            case 3:  // third order
                phi.set( m,6,  sq5*(1.5*eta2 - 0.5) );
                phi.set( m,5,  sq5*(1.5*xi2 - 0.5) );
                phi.set( m,4,  3.0*xi*eta );            

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

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

    }//end of evaluating legendre polys at sample grid points indexed by spts
    delete spts;
    ///////////////////////////////////////////////////////////////////////////

    double time1, time2;   // running time values
    time1 = GetTime();     //running time for this program (can remove this..)

    // fourth order splitting coefficients
    dTensor1* dt_stages;
    if( dogParams.get_time_order() >= 2 )
    {
        dt_stages = new dTensor1(MAX_STAGES);
        sl_state.dt_stages = dt_stages;
    }

    ///////////////////////////////////////////////////////////////////////////
    // Main Time Stepping Loop
    ///////////////////////////////////////////////////////////////////////////
    while (t<tend)
    {
        // initialize time step
        m_accept = 0;      
        n_step = n_step + 1;

        // check if max number of time steps exceeded
        if (n_step>nv)
        {
            cout << " Error in DogSolveAdvec.cpp: "<< 
                " Exceeded allowed # of time steps " << endl;
            cout << "    n_step = " << n_step << endl;
            cout << "        nv = " << nv << endl;
            cout << endl;
            exit(1);
        }

        // copy qnew and aux in case we reject the step
        CopyQ(qnew,qold);
        CopyQ(qnew,qstar);
        CopyQ(aux,aux_old);

        // keep trying until we get a dt that does not violate CFL condition
        while (m_accept==0)
        {
            // set current time          
            told = t;
            tn = t;
            if (told+dt > tend) { dt = tend - told; }
            t = told + dt;

            // Set initial maximum wave speed to zero (this will be saved in
            // SetAdvecSpeed)
            for (int i=(1-mbc); i<=(mx+mbc); i++)
                for (int j=(1-mbc); j<=(my+mbc); j++)
                {
                    smax.set(i,j,1, 0.0e0 );
                    smax.set(i,j,2, 0.0e0 );
                }

            sl_state.dt = dt;
            sl_state.t  = sl_state.tn = tn;

            void InitSLState( const dTensorBC4& q, const dTensorBC4& aux, 
                    SL_state& sl_state );
            InitSLState( qnew, aux, sl_state );

            CopyQ(qold, qstar);
            /////////////////////////////////////
            // Perform a full time step
            /////////////////////////////////////
            switch ( dogParams.get_time_order() )
            {

                case 0:  // used for testing - dont' take any time steps!
                    BeforeStep (dt, aux, qnew, *this);
                    AfterStep  (dt, aux, qnew, *this);
                    perror( "    case 0: Not taking a time step! " );
                    break;

                case 1: // 1st order in time, no corrections

                    sl_state.t     = tn;

                    BeforeStep(dt, aux, qstar, *this);

                    SetAdvecSpeed(phi, qstar, aux, smax, 1, u1, u2, sl_state);
                    SetAdvecSpeed(phi, qstar, aux, smax, 2, u1, u2, sl_state);

                    StepAdvec(dt, qold, qstar, aux, u1, u2, 1, sl_state); 
                    StepAdvec(dt, qstar, qnew, aux, u1, u2, 2, sl_state);

                    break;

                case 2:  // 2nd order in time (strang split method)

                    SetSplitTime(dt, 2, tn, sl_state, dt_stages );
                    sl_state.stage_num = 1;
                    sl_state.t = tn;
                    SetAdvecSpeed( phi, qstar, aux, smax, 1, u1, u2, sl_state);  
                    StepAdvec(0.5*dt, qstar, qnew, aux, u1, u2, 1, sl_state ); 

                    // Poisson solve called in BeforeStep for VP system  
                    //                  BeforeStep(dt, aux, qstar );
                    sl_state.stage_num = 2;
                    BeforeStep(dt, aux, qnew, *this);

                    sl_state.t  = tn;
                    SetAdvecSpeed(phi, qnew, aux, smax, 2, u1, u2, sl_state);
                    StepAdvec(dt, qnew, qstar, aux, u1, u2, 2, sl_state ); 

                    sl_state.stage_num = 3;
                    sl_state.t = tn + 0.5*dt;
                    StepAdvec(0.5*dt, qstar, qnew, aux, u1, u2, 1, sl_state);

                    break;

                case 4: // 4th order method (Yoshida Splitting)		  

                    // initial setup ... Save all appropriate times into SL_state
                    SetSplitTime(dt, 4, tn, sl_state, dt_stages );

                    ///////////////////////////////////////////////////////////
                    ///// There are 7 stages for Yoshida Splitting        /////
                    ///////////////////////////////////////////////////////////


                    ///////// stage 1: A //////////////////////////////////////
                    sl_state.stage_num = 1;
                    sl_state.t         = sl_state.split_time->get(1,1);
                    SetAdvecSpeed( phi, qstar, aux, smax, 1, u1, u2, sl_state);
                    StepAdvec(sl_state.dt_stages->get(1), qstar, qnew,  aux, u1, u2,  1, sl_state ); 

                    ///////// stage 2: B //////////////////////////////////////
                    sl_state.stage_num = 2;
                    sl_state.t         = sl_state.split_time->get(2,2);
                    SetAdvecSpeed( phi, qnew, aux, smax, 2, u1, u2, sl_state);
                    StepAdvec(sl_state.dt_stages->get(2), qnew, qstar,  aux, u1, u2, 2, sl_state); 

                    ///////// stage 3: A //////////////////////////////////////
                    sl_state.stage_num = 3;
                    sl_state.t         = sl_state.split_time->get(3,1);
                    SetAdvecSpeed( phi, qstar, aux, smax, 1, u1, u2, sl_state);
                    StepAdvec(sl_state.dt_stages->get(3), qstar , qnew, aux, u1, u2, 1, sl_state);

                    ///////// stage 4: B //////////////////////////////////////
                    sl_state.stage_num = 4;
                    sl_state.t         = sl_state.split_time->get(4,2);
                    SetAdvecSpeed(phi, qnew, aux, smax, 2, u1, u2, sl_state);
                    StepAdvec(sl_state.dt_stages->get(4), qnew, qstar,  aux, u1, u2, 2, sl_state); 

                    ///////// stage 5: A //////////////////////////////////////
                    sl_state.stage_num = 5;
                    sl_state.t         = sl_state.split_time->get(5,1);
                    SetAdvecSpeed( phi, qstar, aux, smax, 1, u1, u2, sl_state);
                    StepAdvec(sl_state.dt_stages->get(5), qstar, qnew, aux, u1, u2, 1, sl_state);

                    ///////// stage 6: B //////////////////////////////////////
                    sl_state.stage_num = 6;
                    sl_state.t         = sl_state.split_time->get(6,2);
                    SetAdvecSpeed(phi, qnew, aux, smax, 2, u1, u2, sl_state);
                    StepAdvec(sl_state.dt_stages->get(6), qnew, qstar, aux, u1, u2, 2, sl_state); 

                    ///////// stage 7: A //////////////////////////////////////
                    sl_state.stage_num = 7;
                    sl_state.t         = sl_state.split_time->get(7,1);
                    SetAdvecSpeed( phi, qstar, aux, smax, 1, u1, u2, sl_state);
                    StepAdvec(sl_state.dt_stages->get(7), qstar , qnew, aux, u1, u2, 1, sl_state);

                    //////////////// --- Experimental New Time Stepping --- ///////////////////

                    //                  ///////// stage 1: A //////////////////////////////////////
                    //                  sl_state.stage_num = 1;
                    //                  sl_state.t         = sl_state.split_time->get(1,1);
                    //                  SetAdvecSpeed( phi, qstar, aux, smax, 1, u1, u2, sl_state);
                    //                  StepAdvec(sl_state.dt_stages->get(1), qstar, qnew,  aux, u1, u2,  1, sl_state ); 

                    //                  ///////// stage 2: B //////////////////////////////////////
                    //                  sl_state.stage_num = 2;
                    //                  sl_state.t         = sl_state.split_time->get(2,2);
                    //                  SetAdvecSpeed( phi, qnew, aux, smax, 2, u1, u2, sl_state);
                    //                  StepAdvec(sl_state.dt_stages->get(2), qnew, qstar,  aux, u1, u2, 2, sl_state); 

                    //                  ///////// stage 3: A //////////////////////////////////////
                    //                  sl_state.stage_num = 3;
                    //                  sl_state.t         = sl_state.split_time->get(3,1);
                    //                  StepAdvec(sl_state.dt_stages->get(3), qstar , qnew, aux, u1, u2, 1, sl_state);

                    //                  ///////// stage 4: B //////////////////////////////////////
                    //                  sl_state.stage_num = 4;
                    //                  sl_state.t         = sl_state.split_time->get(4,2);
                    //                  SetAdvecSpeed(phi, qnew, aux, smax, 2, u1, u2, sl_state);
                    //                  StepAdvec(sl_state.dt_stages->get(4), qnew, qstar,  aux, u1, u2, 2, sl_state); 

                    //                  ///////// stage 5: A //////////////////////////////////////
                    //                  sl_state.stage_num = 5;
                    //                  sl_state.t         = sl_state.split_time->get(5,1);
                    //                  StepAdvec(sl_state.dt_stages->get(5), qstar, qnew, aux, u1, u2, 1, sl_state);

                    //                  ///////// stage 6: B //////////////////////////////////////
                    //                  sl_state.stage_num = 6;
                    //                  sl_state.t         = sl_state.split_time->get(6,2);
                    //                  SetAdvecSpeed(phi, qnew, aux, smax, 2, u1, u2, sl_state);
                    //                  StepAdvec(sl_state.dt_stages->get(6), qnew, qstar, aux, u1, u2, 2, sl_state); 

                    //                  ///////// stage 7: A //////////////////////////////////////
                    //                  sl_state.stage_num = 7;
                    //                  sl_state.t         = sl_state.split_time->get(7,1);
                    //                  StepAdvec(sl_state.dt_stages->get(7), qstar , qnew, aux, u1, u2, 1, sl_state);

                    //                  ///////// stage 8: B //////////////////////////////////////
                    //                  sl_state.stage_num = 8;
                    //                  sl_state.t         = sl_state.split_time->get(8,2);
                    //                  SetAdvecSpeed(phi, qnew, aux, smax, 2, u1, u2, sl_state);
                    //                  StepAdvec(sl_state.dt_stages->get(8), qnew, qstar, aux, u1, u2, 2, sl_state); 

                    //                  ///////// stage 9: A //////////////////////////////////////
                    //                  sl_state.stage_num = 9;
                    //                  sl_state.t         = sl_state.split_time->get(9,1);
                    //                  StepAdvec(sl_state.dt_stages->get(9), qstar , qnew, aux, u1, u2, 1, sl_state);

                    //                  ///////// stage 10: B //////////////////////////////////////
                    //                  sl_state.stage_num = 10;
                    //                  sl_state.t         = sl_state.split_time->get(10,2);
                    //                  SetAdvecSpeed(phi, qnew, aux, smax, 2, u1, u2, sl_state);
                    //                  StepAdvec(sl_state.dt_stages->get(10), qnew, qstar, aux, u1, u2, 2, sl_state); 

                    //                  ///////// stage 11: A //////////////////////////////////////
                    //                  sl_state.stage_num = 11;
                    //                  sl_state.t         = sl_state.split_time->get(11,1);
                    //                  StepAdvec(sl_state.dt_stages->get(11), qstar , qnew, aux, u1, u2, 1, sl_state);

                    //                  ///////// stage 12: B //////////////////////////////////////
                    //                  sl_state.stage_num = 12;
                    //                  sl_state.t         = sl_state.split_time->get(12,2);
                    //                  SetAdvecSpeed(phi, qnew, aux, smax, 2, u1, u2, sl_state);
                    //                  StepAdvec(sl_state.dt_stages->get(12), qnew, qstar, aux, u1, u2, 2, sl_state); 

                    //                  ///////// stage 13: A //////////////////////////////////////
                    //                  sl_state.stage_num = 13;
                    //                  sl_state.t         = sl_state.split_time->get(13,1);
                    //                  StepAdvec(sl_state.dt_stages->get(13), qstar , qnew, aux, u1, u2, 1, sl_state);

                    //////////////// --- Experimental New Time Stepping --- ///////////////////

                    break;
					
				case 6: // 6th order method (SRKN Splitting)		  
				
					// Added by Pierson Guthrey 5/22/2015
                    // initial setup ... Save all appropriate times into SL_state
                    SetSplitTime(dt, 6, tn, sl_state, dt_stages );
					
                    ///////// stage 1: A //////////////////////////////////////
                    sl_state.stage_num = 1;
                    sl_state.t         = sl_state.split_time->get(1,1);
                    SetAdvecSpeed( phi, qstar, aux, smax, 1, u1, u2, sl_state);
                    StepAdvec(sl_state.dt_stages->get(1), qstar, qnew,  aux, u1, u2,  1, sl_state ); 

                    ///////// stage 2: B //////////////////////////////////////
                    sl_state.stage_num = 2;
                    sl_state.t         = sl_state.split_time->get(2,2);
                    SetAdvecSpeed( phi, qnew, aux, smax, 2, u1, u2, sl_state);
                    StepAdvec(sl_state.dt_stages->get(2), qnew, qstar,  aux, u1, u2, 2, sl_state); 

                    ///////// stage 3: A //////////////////////////////////////
                    sl_state.stage_num = 3;
                    sl_state.t         = sl_state.split_time->get(3,1);
                    SetAdvecSpeed( phi, qstar, aux, smax, 1, u1, u2, sl_state);
                    StepAdvec(sl_state.dt_stages->get(3), qstar , qnew, aux, u1, u2, 1, sl_state);

                    ///////// stage 4: B //////////////////////////////////////
                    sl_state.stage_num = 4;
                    sl_state.t         = sl_state.split_time->get(4,2);
                    SetAdvecSpeed(phi, qnew, aux, smax, 2, u1, u2, sl_state);
                    StepAdvec(sl_state.dt_stages->get(4), qnew, qstar,  aux, u1, u2, 2, sl_state); 
					
                    ///////// stage 5: A //////////////////////////////////////
                    sl_state.stage_num = 5;
                    sl_state.t         = sl_state.split_time->get(5,1);
                    SetAdvecSpeed( phi, qstar, aux, smax, 1, u1, u2, sl_state);
                    StepAdvec(sl_state.dt_stages->get(5), qstar, qnew,  aux, u1, u2,  1, sl_state ); 

                    ///////// stage 6: B //////////////////////////////////////
                    sl_state.stage_num = 6;
                    sl_state.t         = sl_state.split_time->get(6,2);
                    SetAdvecSpeed( phi, qnew, aux, smax, 2, u1, u2, sl_state);
                    StepAdvec(sl_state.dt_stages->get(6), qnew, qstar,  aux, u1, u2, 2, sl_state); 

                    ///////// stage 7: A //////////////////////////////////////
                    sl_state.stage_num = 7;
                    sl_state.t         = sl_state.split_time->get(7,1);
                    SetAdvecSpeed( phi, qstar, aux, smax, 1, u1, u2, sl_state);
                    StepAdvec(sl_state.dt_stages->get(7), qstar , qnew, aux, u1, u2, 1, sl_state);

                    ///////// stage 8: B //////////////////////////////////////
                    sl_state.stage_num = 8;
                    sl_state.t         = sl_state.split_time->get(8,2);
                    SetAdvecSpeed(phi, qnew, aux, smax, 2, u1, u2, sl_state);
                    StepAdvec(sl_state.dt_stages->get(8), qnew, qstar,  aux, u1, u2, 2, sl_state); 					
										
                    ///////// stage 9: A //////////////////////////////////////
                    sl_state.stage_num = 9;
                    sl_state.t         = sl_state.split_time->get(9,1);
                    SetAdvecSpeed( phi, qstar, aux, smax, 1, u1, u2, sl_state);
                    StepAdvec(sl_state.dt_stages->get(9), qstar, qnew,  aux, u1, u2,  1, sl_state ); 

                    ///////// stage 10: B //////////////////////////////////////
                    sl_state.stage_num = 10;
                    sl_state.t         = sl_state.split_time->get(10,2);
                    SetAdvecSpeed( phi, qnew, aux, smax, 2, u1, u2, sl_state);
                    StepAdvec(sl_state.dt_stages->get(10), qnew, qstar,  aux, u1, u2, 2, sl_state); 

                    ///////// stage 11: A //////////////////////////////////////
                    sl_state.stage_num = 11;
                    sl_state.t         = sl_state.split_time->get(11,1);
                    SetAdvecSpeed( phi, qstar, aux, smax, 1, u1, u2, sl_state);
                    StepAdvec(sl_state.dt_stages->get(11), qstar , qnew, aux, u1, u2, 1, sl_state);

                    ///////// stage 12: B //////////////////////////////////////
                    sl_state.stage_num = 12;
                    sl_state.t         = sl_state.split_time->get(12,2);
                    SetAdvecSpeed(phi, qnew, aux, smax, 2, u1, u2, sl_state);
                    StepAdvec(sl_state.dt_stages->get(12), qnew, qstar,  aux, u1, u2, 2, sl_state); 
					
                    ///////// stage 13: A //////////////////////////////////////
                    sl_state.stage_num = 13;
                    sl_state.t         = sl_state.split_time->get(13,1);
                    SetAdvecSpeed( phi, qstar, aux, smax, 1, u1, u2, sl_state);
                    StepAdvec(sl_state.dt_stages->get(13), qstar , qnew, aux, u1, u2, 1, sl_state);

                default:
                    // still here?  too bad!  Pick a valid time stepping
                    // method
                    fprintf(stderr, 
                            "Bad time stepping method chosen in DogSolveAdvec\n");
                    fprintf(stderr, 
                            "dogParams.get_time_order() = %d\n",
                            dogParams.get_time_order());
                    exit(1);

            }// end of taking a full time step

            // compute cfl number
            cfl = GetCFL(dt);

            // output time step information
            if (dogParams.get_verbosity()>0) 
            {
                cout << setprecision(3);
                cout << "DogSolve2D ... Step" << setw(5) << n_step;
                cout << "   CFL =" << setw(6) << fixed << cfl;
                cout << "   dt =" << setw(11) << scientific << dt;
                cout << "   t =" << setw(11) << scientific << t << endl;
            }

            if (cfl>0.0)
            {   dt = Min(dogParams.get_max_dt(),dt*CFL_target/cfl); }
            else
            { dt = dogParams.get_max_dt(); }

            // see whether to accept or reject this step
            if (cfl<=CFL_max)
            {   // accept 
                m_accept = 1;
                dogStateCart2->set_time(t);
                dogParams.set_time(t); // time hack
            }
            else 
            {   //reject
                t = told;
                if (dogParams.get_verbosity()>0)
                {
                    cout<<"DogSolve2D rejecting step...";
                    cout<<"CFL number too large";
                    cout<<endl;
                    // find index of larger value...
                    int imax = 1; int jmax = 1; int dmax = 1;
                    for( int i = 1; i <= smax.getsize(1); i++ )
                        for( int j = 1; j <= smax.getsize(2); j++ )
                            for( int d = 1; d <= ndims; d++ )
                            {
                                if( smax.get(i,j,d) > smax.get(imax,jmax,dmax) )
                                { imax = i;   jmax = j; dmax = d;}
                            }
                    printf("   imax = %d, jmax = %d, dmax = %d\n", imax, jmax, dmax );
                    printf("   smax(imax,jmax,dmax) = %3.2e\n", smax.get(imax, jmax, dmax ) );

                }

                // copy qold into qnew
                CopyQ(qold,qnew);
                CopyQ(aux_old,aux);
            }
        }

        void AfterFullSLTimeStep( dTensorBC4& aux, dTensorBC4& qnew, double t );
        AfterFullSLTimeStep(aux, qnew, t );

        // apply the limiter - This way global integrals stay positive
        void ApplyPosLimiter(const dTensorBC4& aux, dTensorBC4& q);
        if(dogParams.using_moment_limiter())
        { ApplyPosLimiter(aux, qnew); }

        // compute conservation and print to file
        ConSoln(aux,qnew,t);
    }

    void AfterSLFrame(double dt, dTensorBC4& aux, dTensorBC4& q, DogSolverCart2&
            solver, SL_state sl_state );
    AfterSLFrame(dt, aux, qnew, *this, sl_state );

    // set initial time step for next call to DogSolveAdvec
    set_dt(dt);

    // Clock the running time for this call to DogSolveAdvec
    time2 = GetTime();
    if(dogParams.get_verbosity()>0)
    {
        cout << "         DogSolveAdvec Running Time = " 
            << setw(3) << time2 - time1 << "  seconds" << endl << endl;        
    }

    if( dogParams.get_time_order() >= 2 )
    {
        delete dt_stages;
    }
    delete sl_state.split_time;
    delete sl_state.aux1d;
    delete sl_state.node1d;

}
//////////////////////////////////////////////////////////////////////////////
// Function for stepping advection equation forward in time.
//
// The advection equation: q_t + u q_x = 0.  
//
// It is assumed that aux(1,1,1) = u is constant.
//
//////////////////////////////////////////////////////////////////////////////
void StepAdvecFluxForm(const double& dt, const dTensor2& node,
  dTensorBC3& auxvals, dTensorBC1& smax,
  const dTensorBC3& qold, dTensorBC3& qnew)
{

    void SetBndValues(const dTensor2& node, dTensorBC3& aux, dTensorBC3& q);
    SetBndValues(node, auxvals, qnew);

    //-local parameters -----------------------------------------------------//
    const int melems  = qnew.getsize(1);     //number of elements in grid
    const int meqn    = qnew.getsize(2);     //number of equations
    const int kmax    = qnew.getsize(3);     //number of polynomials
    const int mbc     = qnew.getmbc();       //number of ghost cells
    //-----------------------------------------------------------------------//

    //save the center of each grid cell
    const double dx = node.get(2,1)-node.get(1,1);
    const double speed = auxvals.get(1,1,1);

    for(int j=1-mbc; j<=melems+mbc; j++)
    { smax.set(j, Max(smax.get(j), fabs(speed) ) ); }

    // compute quadrature points for where Q needs to be sampled
    const double s_area = 2.0;
    const double large_eta = speed*dt/dx;

    // integration points and weights (for interior)
    const int mpts = 5;

    dTensor1 wgt( mpts ), spts( mpts );
    dTensor2 phi( mpts, 5), phi_x(mpts, 5);
    if( kmax > 1 )
    {
        void setGaussPoints1d(dTensor1& x1d, dTensor1& w1d);
        void evaluateLegendrePolys( 
                const double dx, const dTensor1& spts, dTensor2& phi, dTensor2& phi_x);

        setGaussPoints1d( spts, wgt );
        evaluateLegendrePolys(dx, spts, phi, phi_x);
    }

#pragma omp parallel for
    for(int i=1; i<=melems; i++)
    {

        //loop over each equation
        for(int me=1; me<= meqn; me++)
        {

            dg_cell* dgc = new dg_cell();

            for( int k=1; k <= kmax; k++)
            {

                double qnp1 = qold.get(i,me,k);

                if( k > 1 )
                {
                    // interior integral
                    for( int m=1; m <= mpts; m++ )
                    {

                        double a   = spts.get(m) - 2.0 * large_eta;
                        double b   = spts.get(m);

                        int ishift = get_shift_index( a );

                        double integral = 0.0;
                        if( ishift == 0 )
                        {
                            // no shift takes place, can simply integrate from a to b
                            for( int kq = 1; kq <= kmax; kq++ )
                            {
                                integral += qold.get(i, me, kq) * 
                                    dgc->integratePhi( a, b, kq );
                            }

                        }
                        else if( ishift < 0 )
                        {

                            // integral at the shifted value
                            for( int kq = 1; kq <= kmax; kq++ )
                            {
                                integral += qold.get(i+ishift, me, kq) * 
                                    dgc->integratePhi( shift_xi(a), 1.0, kq );
                            }

                            // integrals between i and ishift
                            for( int n=-1; n > ishift; n-- )
                            { integral += qold.get(i + n, meqn, 1) * dgc->integratePhi(-1.0, 1.0, 1); }

                            // integral inside current cell
                            for( int kq = 1; kq <= kmax; kq++ )
                            {
                                integral += qold.get(i, me, kq) * 
                                    dgc->integratePhi( -1.0, spts.get(m), kq );
                            }

                        }
                        else
                        {
                            printf("   StepAdvecFluxForm.cpp problem can't handle negative velocities yet\n");
                            exit(1);
                        }

                        qnp1 += 0.25 * dx * wgt.get(m) * phi_x.get(m,k) * integral;

                    }
                }

                // left flux
                double a = -1.0 - 2.0 * large_eta;
                int ishift = get_shift_index( a );

                double Fm = 0.0;
                if( ishift < 0 )
                {
                    for( int kq = 1; kq <= kmax; kq++ )
                    {
                        Fm += qold.get(i+ishift, me, kq) * 
                            dgc->integratePhi( shift_xi(a), 1.0, kq ) / 2.0;
                    }
                    for( int n=-1; n > ishift; n-- )
                    {
                        Fm += qold.get(i+n, me, 1);
                    }
                }
                Fm *= sqrt(2*k-1) * pow(-1, k+1 );

                // right flux
                double Fp = 0.0;
                a += 2.0;
                ishift = get_shift_index( a );
                if( ishift < 1 )
                {
                    for( int kq = 1; kq <= kmax; kq++ )
                    {
                        Fp += qold.get(i+ishift, me, kq) * 
                            dgc->integratePhi( shift_xi(a), 1.0, kq ) / 2.0;
                    }
                }
                for( int n=0; n > ishift; n-- )
                { Fp += qold.get(i+n, me, 1); }
                Fp *= sqrt(2*k-1);

                qnew.set(i, me, k, qnp1 - ( Fp - Fm ) );

            }

            delete dgc;

        }//end of loop over each cell
    }//end of loop over each eqn  

    void SetBndValues(const dTensor2& node, dTensorBC3& aux, dTensorBC3& q);
    SetBndValues(node, auxvals, qnew);

}