Exemplo n.º 1
0
///Basic test for FastForwardRead class.
TEST ( iszfstream, fastforwardread ) {
  //Do not delete!
  std::stringstream *ss = new std::stringstream;
  *ss << "one" << std::endl;
  *ss << "two" << std::endl;
  *ss << "three" << std::endl;
  *ss << "four" << std::endl;
  *ss << "five" ;
  {
    uu::FastForwardRead<> ffr ( ss );
    std::string line;
    bool finished;
    finished = ffr ( 2, &line );
    EXPECT_EQ ( line, "two" );
    EXPECT_EQ ( finished, false );
    finished = ffr ( 4, &line );
    EXPECT_EQ ( line, "four" );
    EXPECT_EQ ( finished, false );
    finished = ffr ( 5, &line );
    EXPECT_EQ ( line, "five" );
    EXPECT_EQ ( finished, false );
    finished = ffr ( 6, &line );
    //No more readings
    EXPECT_EQ ( line, "" );
    EXPECT_EQ ( finished, true );
    // Cannot read backwards
    user_check_ok = true;
    finished = ffr ( 1, &line );
    EXPECT_EQ ( line, "" );
    EXPECT_EQ ( user_check_ok, false );
    user_check_ok = true;
  }
  ss = new std::stringstream;
  *ss << "one" << std::endl;
  {
    std::string line;
    bool finished;
    uu::FastForwardRead<> ffr ( ss );
    finished = ffr ( 1, &line );
    EXPECT_EQ (finished, false);
    EXPECT_EQ (line, "one");
    finished = ffr ( 2, &line );
    EXPECT_EQ (finished, true);
    EXPECT_EQ (line, "");
  }
};
Exemplo n.º 2
0
// Right-hand side of the Lax-Wendroff discretization:
//
//      ( q(t+dt) - q(t) )/dt = -F_{x} - G_{y}.
//
// This routine constructs the 'time-integrated' flux functions F and G using the
// Cauchy-Kowalewski procedure.
//
// First, consider time derivatives of q
//
//    q^{n+1} = q^n + dt * (q^n_t + dt/2 * q^n_tt + dt^3/6 q^n_ttt ).
//
// Formally, these are given by
//
//   q_{t}    = ( -f(q) )_x + ( -g(q) )_y, 
//   q_{tt}   = ( f'(q) * ( f_x + g_y )_x + ( g'(q) * ( f_x + g_y )_y
//   q_{ttt}  = ...
//
// Now, considering Taylor expansions of f and g, centered about t = t^n
//
//  F = f^n + (t-t^n) \dot{f^n} + \cdots
//  G = g^n + (t-t^n) \dot{g^n} + \cdots
//
// We have the following form, after integrating in time
//
//  F: = ( f - dt/2 * ( f'(q)*( f_x+g_y ) 
//           + dt^2/6 ( \pd2{f}{q} \cdot (f_x+g_y,f_x+g_y) +
//                        \pd{f}{q} (  f_x + g_y )_t  ) + \cdots
//
//  G: = ( g - dt/2 * ( g'(q)*( f_x+g_y )
//           + dt^2/6 ( \pd2{g}{q} \cdot (f_x+g_y,f_x+g_y) +
//                        \pd{g}{q} (  f_x + g_y )_t ) + \cdots
//
// where the final ingredient is
//
//  (f_x+g_y)_t = \pd2{f}{q} \cdot (q_x, f_x+g_y ) + \pd{f}{q} ( f_xx + g_xy ) +
//                \pd2{g}{q} \cdot (q_y, f_x+g_y ) + \pd{g}{q} ( f_xy + g_yy ).
//
// At the end of the day, we set
//
//    L(q) := -F_x - G_y.
//
// See also: ConstructL.
void LaxWendroff(double dt, 
    const dTensorBC4& aux, const dTensorBC4& q,    // set bndy values modifies these
    dTensorBC4& Lstar, dTensorBC3& smax)
{

printf("This call hasn't been tested \n");

    if ( !dogParams.get_flux_term() )
    {  return;  }

    const edge_data& edgeData = Legendre2d::get_edgeData();
    const int space_order = dogParams.get_space_order();
    const int mx   = q.getsize(1);
    const int my   = q.getsize(2);
    const int meqn = q.getsize(3);
    const int kmax = q.getsize(4);
    const int mbc  = q.getmbc();
    const int maux = aux.getsize(3);

    // Flux values
    //
    // Space-order = number of quadrature points needed for 1D integration
    // along cell edges.
    //
    dTensorBC4 Fm(mx, my, meqn, space_order, mbc);
    dTensorBC4 Fp(mx, my, meqn, space_order, mbc);
    dTensorBC4 Gm(mx, my, meqn, space_order, mbc);
    dTensorBC4 Gp(mx, my, meqn, space_order, mbc);

    // Flux function
    void FluxFunc(const dTensor2& xpts,
                  const dTensor2& Q,
                  const dTensor2& Aux,
                  dTensor3& flux);

    // Jacobian of the flux function:
    void DFluxFunc(const dTensor2& xpts, 
                   const dTensor2& Q,
                   const dTensor2& Aux, 
                   dTensor4& Dflux );

    // Hessian of the flux function:
    void D2FluxFunc(const dTensor2& xpts, 
                   const dTensor2& Q,
                   const dTensor2& Aux, 
                   dTensor5& D2flux );


    // Riemann solver that relies on the fact that we already have 
    // f(ql) and f(qr) already computed:
    double RiemannSolveLxW(const dTensor1& nvec,
        const dTensor1& xedge,
        const dTensor1& Ql,   const dTensor1& Qr,
        const dTensor1& Auxl, const dTensor1& Auxr,
        const dTensor1& ffl,  const dTensor1& ffr,
        dTensor1& Fl, dTensor1& Fr);

    void LstarExtra(const dTensorBC4*,
            const dTensorBC4*,
            dTensorBC4*);
    void ArtificialViscosity(const dTensorBC4* aux, 
            const dTensorBC4* q, 
            dTensorBC4* Lstar);

    // Grid information
    const double xlower = dogParamsCart2.get_xlow();
    const double ylower = dogParamsCart2.get_ylow();
    const double dx = dogParamsCart2.get_dx();
    const double dy = dogParamsCart2.get_dy();

    // --------------------------------------------------------------------- //
    // Boundary data:
    // --------------------------------------------------------------------- //
    // TODO - call this routine before calling this function.
//  void SetBndValues(dTensorBC4& q, dTensorBC4& aux);
//  SetBndValues(q, aux);
    // ---------------------------------------------------------

    // --------------------------------------------------------------------- //
    // Part 0: Compute the Lax-Wendroff "flux" function:
    //
    // Here, we include the extra information about time derivatives.
    // --------------------------------------------------------------------- //
    dTensorBC4 F(mx, my, meqn, kmax, mbc);  F.setall(0.);
    dTensorBC4 G(mx, my, meqn, kmax, mbc);  G.setall(0.);
    void L2ProjectLxW( const int mterms, 
        const double alpha, const double beta_dt, const double charlie_dt,
        const int istart, const int iend, 
        const int jstart, const int jend,
        const int QuadOrder,
        const int BasisOrder_auxin,
        const int BasisOrder_fout,    
        const dTensorBC4* qin,
        const dTensorBC4* auxin,
        dTensorBC4* F,
        dTensorBC4* G,
        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) );
printf("hello\n");
    L2ProjectLxW( 3, 1.0, 0.5*dt, dt*dt/6.0,
        1-mbc, mx+mbc, 1-mbc, my+mbc,
        space_order, space_order, space_order,
        &q, &aux, &F, &G, &FluxFunc, &DFluxFunc, D2FluxFunc );

    // ---------------------------------------------------------
    // Part I: compute source term
    // --------------------------------------------------------- 
    if( dogParams.get_source_term() > 0 )
    {
        // eprintf("error: have not implemented source term for LxW solver.");
        printf("Source term has not been implemented for LxW solver.  Terminating program.");
        exit(1);
    }
    Lstar.setall( 0. );

    // ---------------------------------------------------------
    // Part II: compute inter-element interaction fluxes
    //
    //   N = int( F(q,x,t) * phi_x, x ) / dA
    //
    // ---------------------------------------------------------

    // 1-direction: loop over interior edges and solve Riemann problems
    dTensor1 nvec(2);
    nvec.set(1, 1.0e0 );
    nvec.set(2, 0.0e0 );

#pragma omp parallel for
    for (int i=(2-mbc); i<=(mx+mbc); i++)
    {

        dTensor1 Ql(meqn),   Qr(meqn);
        dTensor1 ffl(meqn),  ffr(meqn);
        dTensor1 Fl(meqn),   Fr(meqn);
        dTensor1 DFl(meqn),  DFr(meqn);
        dTensor1 Auxl(maux), Auxr(maux);

        dTensor1 xedge(2);

        for (int j=(2-mbc); j<=(my+mbc-1); j++)
        {
            // ell indexes Riemann point along the edge
            for (int ell=1; ell<=space_order; ell++)
            {
                // Riemann data - q and f (from basis functions/q)
                for (int m=1; m<=meqn; m++)
                {
                    Ql.set (m, 0.0 );
                    Qr.set (m, 0.0 );
                    ffl.set(m, 0.0 );
                    ffr.set(m, 0.0 );

                    for (int k=1; k<=kmax; k++)
                    {
                        // phi_xl( xi=1.0, eta ), phi_xr( xi=-1.0, eta )
                        Ql.fetch(m)  += edgeData.phi_xl->get(ell,k)*q.get(i-1, j, m, k );
                        Qr.fetch(m)  += edgeData.phi_xr->get(ell,k)*q.get(i,   j, m, k );
                        ffl.fetch(m) += edgeData.phi_xl->get(ell,k)*F.get(i-1, j, m, k );
                        ffr.fetch(m) += edgeData.phi_xr->get(ell,k)*F.get(i,   j, m, k );
                    }

                }

                // Riemann data - aux
                for (int m=1; m<=maux; m++)
                {
                    Auxl.set(m, 0.0 );
                    Auxr.set(m, 0.0 );

                    for (int k=1; k<=kmax; k++)
                    {
                        Auxl.fetch(m) += edgeData.phi_xl->get(ell,k)*aux.get(i-1, j, m, k);
                        Auxr.fetch(m) += edgeData.phi_xr->get(ell,k)*aux.get(i,   j, m, k);
                    }
                }

                // Solve Riemann problem
                xedge.set(1, xlower + (double(i)-1.0)*dx );
                xedge.set(2, ylower + (double(j)-0.5)*dy );

                const double smax_edge = RiemannSolveLxW(
                    nvec, xedge, Ql, Qr, Auxl, Auxr, ffl, ffr, Fl, Fr);

                smax.set(i-1, j, 1, Max(dy*smax_edge,smax.get(i-1, j, 1)) );
                smax.set(i,   j, 1, Max(dy*smax_edge,smax.get(i,   j, 1)) );

                // Construct fluxes
                for (int m=1; m<=meqn; m++)
                {
                    Fm.set(i  , j, m, ell,  Fr.get(m) );
                    Fp.set(i-1, j, m, ell,  Fl.get(m) );
                }
            }
        }
    }


    // 2-direction: loop over interior edges and solve Riemann problems
    nvec.set(1, 0.0e0 );
    nvec.set(2, 1.0e0 );

#pragma omp parallel for
    for (int i=(2-mbc); i<=(mx+mbc-1); i++)
    {
        dTensor1  Ql(meqn),   Qr(meqn);
        dTensor1  Fl(meqn),   Fr(meqn);
        dTensor1 ffl(meqn),  ffr(meqn);
        dTensor1 Auxl(maux),Auxr(maux);
        dTensor1 xedge(2);

        for (int j=(2-mbc); j<=(my+mbc); j++)
        for (int ell=1; ell<=space_order; ell++)
        {
            // Riemann data - q
            for (int m=1; m<=meqn; m++)
            {

                Ql.set  (m, 0.0 );
                Qr.set  (m, 0.0 );
                ffl.set (m, 0.0 );
                ffr.set (m, 0.0 );

                for (int k=1; k<=kmax; k++)
                {
                    Ql.fetch(m)  += edgeData.phi_yl->get(ell, k)*q.get(i, j-1, m, k );
                    Qr.fetch(m)  += edgeData.phi_yr->get(ell, k)*q.get(i, j,   m, k );
                    ffl.fetch(m) += edgeData.phi_yl->get(ell, k)*G.get(i, j-1, m, k );
                    ffr.fetch(m) += edgeData.phi_yr->get(ell, k)*G.get(i,   j, m, k );
                }
            }

            // Riemann data - aux
            for (int m=1; m<=maux; m++)
            {
                Auxl.set(m, 0.0 );
                Auxr.set(m, 0.0 );

                for (int k=1; k<=kmax; k++)
                {
                    Auxl.fetch(m) += edgeData.phi_yl->get(ell,k)*aux.get(i,j-1,m,k);
                    Auxr.fetch(m) += edgeData.phi_yr->get(ell,k)*aux.get(i,j,m,k);
                }
            }

            // Solve Riemann problem
            xedge.set(1, xlower + (double(i)-0.5)*dx );
            xedge.set(2, ylower + (double(j)-1.0)*dy );

            const double smax_edge = RiemannSolveLxW(
                nvec, xedge, Ql, Qr, Auxl, Auxr, ffl, ffr, Fl, Fr);

            smax.set(i, j-1, 2,  Max(dx*smax_edge, smax.get(i, j-1, 2)) );
            smax.set(i, j,   2,  Max(dx*smax_edge, smax.get(i, j,   2)) );

            // Construct fluxes
            for (int m=1; m<=meqn; m++)
            {
                Gm.set(i, j,   m, ell, Fr.get(m) );
                Gp.set(i, j-1, m, ell, Fl.get(m) );
            }
        }
    }

    // Compute ``flux differences'' dF and dG    
    const double half_dx_inv = 0.5/dx;
    const double half_dy_inv = 0.5/dy;
    const int mlength = Lstar.getsize(3);   assert_eq( meqn, mlength );

    // Use the four values, Gm, Gp, Fm, Fp to construct the boundary integral:
#pragma omp parallel for
    for (int i=(2-mbc); i<=(mx+mbc-1); i++)    
    for (int j=(2-mbc); j<=(my+mbc-1); j++)
    for (int m=1; m<=mlength; m++)
    for (int k=1; k<=kmax; k++)
    {
        // 1-direction: dF
        double F1 = 0.0;
        double F2 = 0.0;
        for (int ell=1; ell<=space_order; ell++)
        {
            F1 = F1 + edgeData.wght_phi_xr->get(ell,k)*Fm.get(i,j,m,ell);
            F2 = F2 + edgeData.wght_phi_xl->get(ell,k)*Fp.get(i,j,m,ell);
        }

        // 2-direction: dG
        double G1 = 0.0;
        double G2 = 0.0;
        for (int ell=1; ell<=space_order; ell++)
        {
            G1 = G1 + edgeData.wght_phi_yr->get(ell,k)*Gm.get(i,j,m,ell);
            G2 = G2 + edgeData.wght_phi_yl->get(ell,k)*Gp.get(i,j,m,ell);
        }

        Lstar.fetch(i,j,m,k) -= (half_dx_inv*(F2-F1) + half_dy_inv*(G2-G1));

    }
    // ---------------------------------------------------------


    // ---------------------------------------------------------
    // Part III: compute intra-element contributions
    // ---------------------------------------------------------
    // No need to call this if first-order in space
    if(dogParams.get_space_order()>1)
    {

        dTensorBC4 Ltmp( mx, my, meqn, kmax, mbc );
        void L2ProjectGradAddLegendre(const int istart, 
                const int iend, 
                const int jstart, 
                const int jend,
                const int QuadOrder, 
                const dTensorBC4* F, 
                const dTensorBC4* G, 
                dTensorBC4* fout );
        L2ProjectGradAddLegendre( 1-mbc, mx+mbc, 1-mbc, my+mbc,
            space_order, &F, &G, &Lstar );

    }
    // ---------------------------------------------------------  

    // ---------------------------------------------------------
    // Part IV: add extra contributions to Lstar
    // ---------------------------------------------------------
    // Call LstarExtra
    LstarExtra(&q,&aux,&Lstar);
    // ---------------------------------------------------------


    // ---------------------------------------------------------
    // Part V: artificial viscosity limiter
    // ---------------------------------------------------------  
    if (dogParams.get_space_order()>1  &&
            dogParams.using_viscosity_limiter())
    {  ArtificialViscosity(&aux,&q,&Lstar);  }
    // ---------------------------------------------------------

}
Exemplo n.º 3
0
// Right-hand side for hyperbolic PDE in divergence form
//
//       q_t = -( f(q,x,y,t)_x + g(q,x,y,t)_y ) + Psi(q,x,y,t)
//
void LaxWendroff_Unst(double dt,
    const mesh& Mesh, const edge_data_Unst& EdgeData,
    dTensor3& aux,                  // SetBndValues modifies ghost cells
    dTensor3& q,                    // SetBndValues modifies ghost cells
    dTensor3& Lstar, dTensor1& smax)
{

    const int NumElems      = Mesh.get_NumElems();
    const int NumPhysElems  = Mesh.get_NumPhysElems();
    const int NumEdges      = Mesh.get_NumEdges();
    const int meqn          = q.getsize(2);
    const int kmax          = q.getsize(3);
    const int maux          = aux.getsize(2);
    const int space_order   = dogParams.get_space_order();
    dTensor3 EdgeFluxIntegral(NumElems,meqn,kmax);
    dTensor3 ElemFluxIntegral(NumElems,meqn,kmax);
    dTensor3              Psi(NumElems,meqn,kmax);

    // ---------------------------------------------------------
    // Boundary Conditions
    SetBndValues_Unst(Mesh, &q, &aux);
    // ---------------------------------------------------------

    // --------------------------------------------------------------------- //
    // Part 0: Compute the Lax-Wendroff "flux" function:
    //
    // Here, we include the extra information about time derivatives.
    // --------------------------------------------------------------------- //
    dTensor3 F(NumElems, meqn, kmax );  F.setall(0.);
    dTensor3 G(NumElems, meqn, kmax );  G.setall(0.);
    L2ProjectLxW_Unst( dogParams.get_time_order(), 1.0, 0.5*dt, dt*dt/6.0, 1, NumElems,
        space_order, space_order, space_order, space_order, Mesh,
        &q, &aux, &F, &G, &FluxFunc, &DFluxFunc, &D2FluxFunc );

    // ---------------------------------------------------------
    // Part I: compute source term
    // --------------------------------------------------------- 
    if ( dogParams.get_source_term()>0 )
    {        
        // eprintf("error: have not implemented source term for LxW solver.");
        printf("Source term has not been implemented for LxW solver.  Terminating program.");
        exit(1);
    }
    Lstar.setall(0.);
    // ---------------------------------------------------------


    // ---------------------------------------------------------
    // Part II: compute flux integral on element edges
    // ---------------------------------------------------------

    // Loop over all interior edges
    EdgeFluxIntegral.setall(0.);
    ElemFluxIntegral.setall(0.);

#pragma omp parallel for
    // Loop over all interior edges
    for (int i=1; i<=NumEdges; i++)
    {
        // Edge coordinates
        double x1 = Mesh.get_edge(i,1);
        double y1 = Mesh.get_edge(i,2);
        double x2 = Mesh.get_edge(i,3);
        double y2 = Mesh.get_edge(i,4);

        // Elements on either side of edge
        int ileft  = Mesh.get_eelem(i,1);
        int iright = Mesh.get_eelem(i,2);  
        double Areal = Mesh.get_area_prim(ileft);
        double Arear = Mesh.get_area_prim(iright);

        // Scaled normal to edge
        dTensor1 nhat(2);      
        nhat.set(1, (y2-y1) );
        nhat.set(2, (x1-x2) );

        // Variables to store flux integrals along edge
        dTensor2 Fr_tmp(meqn,dogParams.get_space_order());
        dTensor2 Fl_tmp(meqn,dogParams.get_space_order());

        // Loop over number of quadrature points along each edge
        for (int ell=1; ell<=dogParams.get_space_order(); ell++)
        {
            dTensor1   Ql(meqn),   Qr(meqn);
            dTensor1  ffl(meqn),  ffr(meqn);  // << -- NEW PART -- >>
            dTensor1 Auxl(maux), Auxr(maux);

            // Riemann data - q
            for (int m=1; m<=meqn; m++)
            {
                Ql.set(m, 0.0 );
                Qr.set(m, 0.0 );

                // << -- NEW PART, ffl and ffr -- >> //
                ffl.set(m, 0.0 );
                ffr.set(m, 0.0 );

                for (int k=1; k<=kmax; k++)
                {
                    Ql.set(m, Ql.get(m) + EdgeData.phi_left->get(i,ell,k) 
                            *q.get(ileft, m,k) );
                    Qr.set(m, Qr.get(m) + EdgeData.phi_right->get(i,ell,k)
                            *q.get(iright,m,k) );

                    // << -- NEW PART, ffl and ffr -- >> //
                    // Is this the correct way to use the normal vector?
                    ffl.set(m, ffl.get(m) + EdgeData.phi_left->get (i, ell, k) * ( 
                        nhat.get(1)*F.get( ileft, m, k) + nhat.get(2)*G.get( ileft, m, k) ) );

                    ffr.set(m, ffr.get(m) + EdgeData.phi_right->get(i, ell, k) * (
                        nhat.get(1)*F.get(iright, m, k) + nhat.get(2)*G.get(iright, m, k) ) );

                }
            }

            // Riemann data - aux
            for (int m=1; m<=maux; m++)
            {
                Auxl.set(m, 0.0 );
                Auxr.set(m, 0.0 );

                for (int k=1; k<=kmax; k++)
                {
                    Auxl.set(m, Auxl.get(m) + EdgeData.phi_left->get(i,ell,k)  * aux.get(ileft, m,k) );
                    Auxr.set(m, Auxr.get(m) + EdgeData.phi_right->get(i,ell,k) * aux.get(iright,m,k) );
                }
            }

            // Solve Riemann problem
            dTensor1 xedge(2);
            double s = EdgeData.xpts1d->get(ell);
            xedge.set(1, x1 + 0.5*(s+1.0)*(x2-x1) );
            xedge.set(2, y1 + 0.5*(s+1.0)*(y2-y1) );

            // Solve the Riemann problem for this edge
            dTensor1 Fl(meqn), Fr(meqn);

            // Use the time-averaged fluxes to define left and right values for
            // the Riemann solver.
            const double smax_edge = RiemannSolveLxW(
                    nhat, xedge, Ql, Qr, Auxl, Auxr, ffl, ffr, Fl, Fr);
            smax.set(i, Max(smax_edge,smax.get(i)) );

            // Construct fluxes
            for (int m=1; m<=meqn; m++)
            {
                Fr_tmp.set(m,ell, Fr.get(m) );
                Fl_tmp.set(m,ell, Fl.get(m) );
            }
        }

        // Add edge integral to line integral around the full element
        for (int m=1; m<=meqn; m++)
        for (int k=1; k<=kmax; k++)
        {
            double Fl_sum = 0.0;
            double Fr_sum = 0.0;
            for (int ell=1; ell<=dogParams.get_space_order(); ell++)
            {
                Fl_sum = Fl_sum + 0.5*EdgeData.wgts1d->get(ell)
                    *EdgeData.phi_left->get(i,ell,k) *Fl_tmp.get(m,ell);
                Fr_sum = Fr_sum + 0.5*EdgeData.wgts1d->get(ell)
                    *EdgeData.phi_right->get(i,ell,k)*Fr_tmp.get(m,ell);
            }
            EdgeFluxIntegral.set(ileft, m,k, EdgeFluxIntegral.get(ileft, m,k) + Fl_sum/Areal );
            EdgeFluxIntegral.set(iright,m,k, EdgeFluxIntegral.get(iright,m,k) - Fr_sum/Arear );
        }
    }
    // ---------------------------------------------------------

    // ---------------------------------------------------------
    // Part III: compute intra-element contributions
    // ---------------------------------------------------------
    if( dogParams.get_space_order() > 1 )
    {
        L2ProjectGradAddLegendre_Unst(1, NumPhysElems, space_order, 
            Mesh, &F, &G, &ElemFluxIntegral );
    }
    // ---------------------------------------------------------

    // ---------------------------------------------------------
    // Part IV: construct Lstar
    // ---------------------------------------------------------
    if (dogParams.get_source_term()==0)  // Without Source Term
    { 
#pragma omp parallel for
        for (int i=1; i<=NumPhysElems; i++)	
        for (int m=1; m<=meqn; m++)
        for (int k=1; k<=kmax; k++)
        {
            double tmp = ElemFluxIntegral.get(i,m,k) - EdgeFluxIntegral.get(i,m,k);
            Lstar.set(i,m,k, tmp );	      
        }
    }
    else  // With Source Term
    {
#pragma omp parallel for
        for (int i=1; i<=NumPhysElems; i++)
        for (int m=1; m<=meqn; m++)
        for (int k=1; k<=kmax; k++)
        {
//          double tmp = ElemFluxIntegral.get(i,m,k) 
//              - EdgeFluxIntegral.get(i,m,k)
//              + Psi.get(i,m,k);

//          Lstar.set(i,m,k, tmp );

            printf("Source term has not been implemented for LxW solver.  Terminating program.");
            exit(1);
        }
    }
    // ---------------------------------------------------------

    // ---------------------------------------------------------
    // Part V: add extra contributions to Lstar
    // ---------------------------------------------------------
    // Call LstarExtra
    LstarExtra_Unst(Mesh, &q, &aux, &Lstar);
    // ---------------------------------------------------------

    // ---------------------------------------------------------
    // Part VI: artificial viscosity limiter
    // ---------------------------------------------------------  
//  if (dogParams.get_space_order()>1  &&
//          dogParams.using_viscosity_limiter())
//  {  ArtificialViscosity(&aux,&q,&Lstar);  }
    // ---------------------------------------------------------

}