示例#1
0
文件: lininteg.cpp 项目: lyq105/mfem
void BoundaryTangentialLFIntegrator::AssembleRHSElementVect(
    const FiniteElement &el, ElementTransformation &Tr, Vector &elvect)
{
    int dim = el.GetDim()+1;
    int dof = el.GetDof();
    Vector tangent(dim), Qvec;

    shape.SetSize(dof);
    elvect.SetSize(dof);
    elvect = 0.0;

    if (dim != 2)
        mfem_error("These methods make sense only in 2D problems.");

    const IntegrationRule *ir = IntRule;
    if (ir == NULL)
    {
        int intorder = oa * el.GetOrder() + ob;  // <----------
        ir = &IntRules.Get(el.GetGeomType(), intorder);
    }

    for (int i = 0; i < ir->GetNPoints(); i++)
    {
        const IntegrationPoint &ip = ir->IntPoint(i);

        Tr.SetIntPoint(&ip);
        const DenseMatrix &Jac = Tr.Jacobian();
        tangent(0) =  Jac(0,0);
        tangent(1) = Jac(1,0);

        Q.Eval(Qvec, Tr, ip);

        el.CalcShape(ip, shape);

        add(elvect, ip.weight*(Qvec*tangent), shape, elvect);
    }
}
bool Problem_Interface::computePreconditioner(const Epetra_Vector & x,
                                              Epetra_Operator & prec,
                                              Teuchos::ParameterList * /*p*/)
{
  START_LOG("preconditioner()", "TrilinosNoxNonlinearSolver");

  NonlinearImplicitSystem & sys = _solver->system();
  TrilinosPreconditioner<Number> & tpc = dynamic_cast<TrilinosPreconditioner<Number> &>(prec);

  EpetraMatrix<Number> Jac(dynamic_cast<Epetra_FECrsMatrix *>(tpc.mat()),sys.comm());
  EpetraVector<Number> & X_sys = *cast_ptr<EpetraVector<Number> *>(sys.solution.get());
  EpetraVector<Number> X_global(*const_cast<Epetra_Vector *>(&x), sys.comm());

  // Set the dof maps
  Jac.attach_dof_map(sys.get_dof_map());

  // Use the systems update() to get a good local version of the parallel solution
  X_global.swap(X_sys);

  sys.get_dof_map().enforce_constraints_exactly(sys);
  sys.update();

  X_global.swap(X_sys);

  //-----------------------------------------------------------------------------
  // if the user has provided both function pointers and objects only the pointer
  // will be used, so catch that as an error
  if (_solver->jacobian && _solver->jacobian_object)
    libmesh_error_msg("ERROR: cannot specify both a function and object to compute the Jacobian!");

  if (_solver->matvec && _solver->residual_and_jacobian_object)
    libmesh_error_msg("ERROR: cannot specify both a function and object to compute the combined Residual & Jacobian!");

  if      (_solver->jacobian != NULL)                     _solver->jacobian                                            (*sys.current_local_solution.get(), Jac, sys);
  else if (_solver->jacobian_object != NULL)              _solver->jacobian_object->jacobian                           (*sys.current_local_solution.get(), Jac, sys);
  else if (_solver->matvec   != NULL)                     _solver->matvec                                              (*sys.current_local_solution.get(), NULL, &Jac, sys);
  else if (_solver->residual_and_jacobian_object != NULL) _solver->residual_and_jacobian_object->residual_and_jacobian (*sys.current_local_solution.get(), NULL, &Jac, sys);
  else
    libmesh_error_msg("Error! Unable to compute residual and/or Jacobian!");

  Jac.close();
  X_global.close();

  tpc.compute();

  STOP_LOG("preconditioner()", "TrilinosNoxNonlinearSolver");

  return true;
}
// XXX: Jac(i, 6) or column #7 is all zero !
void PointSolver2::prepareMatrices ()
{
	Jac = Eigen::MatrixXd::Zero (ipoints.size(), 7);
	Pcorrect = Eigen::VectorXd::Zero (7);
	pointErrs = Eigen::VectorXd::Zero (ipoints.size());

	for (int ip=0; ip<ipoints.size(); ip++) {
		pointErrs [ip] = ipoints[ip].lineDistance;
		Point2 curpt = ipoints[ip].coord;

		pscalar jacobianPt[7];

		LineSegment2D &line = visibleLines[ipoints[ip].nearestLine];
		line.errorJacobian(curpt, jacobianPt);
		for (int n=0; n<7; n++) {
			Jac(ip, n) = jacobianPt[n];
		}
		continue;
	}
//	std::cout << pointErrs << std::endl;
//	std::cout << Jac << std::endl;
}
示例#4
0
  //---------------------------------------------------------------
  // this function is called by PETSc to evaluate the Jacobian at X
  PetscErrorCode
  __libmesh_petsc_snes_jacobian (SNES snes, Vec x, Mat *jac, Mat *pc, MatStructure *msflag, void *ctx)
  {
    START_LOG("jacobian()", "PetscNonlinearSolver");

    PetscErrorCode ierr=0;

    libmesh_assert(ctx);

    PetscNonlinearSolver<Number>* solver =
      static_cast<PetscNonlinearSolver<Number>*> (ctx);

    // Get the current iteration number from the snes object,
    // store it in the PetscNonlinearSolver object for possible use
    // by the user's Jacobian function.
    {
      PetscInt n_iterations = 0;
      ierr = SNESGetIterationNumber(snes, &n_iterations);
      CHKERRABORT(solver->comm().get(),ierr);
      solver->set_current_nonlinear_iteration_number( static_cast<unsigned>(n_iterations) );
    }

    NonlinearImplicitSystem &sys = solver->system();

    PetscMatrix<Number> PC(*pc, sys.comm());
    PetscMatrix<Number> Jac(*jac, sys.comm());
    PetscVector<Number>& X_sys = *libmesh_cast_ptr<PetscVector<Number>*>(sys.solution.get());
    PetscMatrix<Number>& Jac_sys = *libmesh_cast_ptr<PetscMatrix<Number>*>(sys.matrix);
    PetscVector<Number> X_global(x, sys.comm());

    // Set the dof maps
    PC.attach_dof_map(sys.get_dof_map());
    Jac.attach_dof_map(sys.get_dof_map());

    // Use the systems update() to get a good local version of the parallel solution
    X_global.swap(X_sys);
    Jac.swap(Jac_sys);

    sys.get_dof_map().enforce_constraints_exactly(sys);
    sys.update();

    X_global.swap(X_sys);
    Jac.swap(Jac_sys);

    PC.zero();

    //-----------------------------------------------------------------------------
    // if the user has provided both function pointers and objects only the pointer
    // will be used, so catch that as an error
    if (solver->jacobian && solver->jacobian_object)
      {
	libMesh::err << "ERROR: cannot specifiy both a function and object to compute the Jacobian!" << std::endl;
	libmesh_error();
      }

    if (solver->matvec && solver->residual_and_jacobian_object)
      {
	libMesh::err << "ERROR: cannot specifiy both a function and object to compute the combined Residual & Jacobian!" << std::endl;
	libmesh_error();
      }
    //-----------------------------------------------------------------------------

    if      (solver->jacobian != NULL)                     solver->jacobian                                            (*sys.current_local_solution.get(), PC, sys);
    else if (solver->jacobian_object != NULL)              solver->jacobian_object->jacobian                           (*sys.current_local_solution.get(), PC, sys);
    else if (solver->matvec   != NULL)                     solver->matvec                                              (*sys.current_local_solution.get(), NULL, &PC, sys);
    else if (solver->residual_and_jacobian_object != NULL) solver->residual_and_jacobian_object->residual_and_jacobian (*sys.current_local_solution.get(), NULL, &PC, sys);
    else libmesh_error();

    PC.close();
    Jac.close();
    X_global.close();

    *msflag = SAME_NONZERO_PATTERN;

    STOP_LOG("jacobian()", "PetscNonlinearSolver");

    return ierr;
  }
示例#5
0
文件: ASMs1D.C 项目: OPM/IFEM
bool ASMs1D::integrate (Integrand& integrand, int lIndex,
			GlobalIntegral& glInt,
			const TimeDomain& time)
{
  if (!curv) return true; // silently ignore empty patches

  // Integration of boundary point

  FiniteElement fe(curv->order());
  size_t iel = 0;
  switch (lIndex)
    {
    case 1:
      fe.xi = -1.0;
      fe.u = curv->startparam();
      break;

    case 2:
      fe.xi = 1.0;
      fe.u = curv->endparam();
      iel = nel-1;
      break;

    default:
      return false;
    }

  std::map<char,size_t>::const_iterator iit = firstBp.find(lIndex);
  fe.iGP = iit == firstBp.end() ? 0 : iit->second;
  fe.iel = MLGE[iel];
  if (fe.iel < 1) return true; // zero-length element

  // Set up control point coordinates for current element
  if (!this->getElementCoordinates(fe.Xn,1+iel)) return false;

  if (integrand.getIntegrandType() & Integrand::ELEMENT_CORNERS)
    this->getElementEnds(iel+curv->order(),fe.XC);

  if (integrand.getIntegrandType() & Integrand::NODAL_ROTATIONS)
  {
    this->getElementNodalRotations(fe.Tn,iel);
    if (!elmCS.empty()) fe.Te = elmCS[iel];
  }

  // Initialize element matrices
  LocalIntegral* A = integrand.getLocalIntegral(fe.N.size(),fe.iel,true);
  bool ok = integrand.initElementBou(MNPC[iel],*A);

  Vec3 normal;

  // Evaluate basis functions and corresponding derivatives
  if (integrand.getIntegrandType() & Integrand::NO_DERIVATIVES)
    this->extractBasis(fe.u,fe.N);
  else
  {
    // Compute basis function derivatives
    Matrix dNdu, Jac;
    this->extractBasis(fe.u,fe.N,dNdu);
    utl::Jacobian(Jac,fe.dNdX,fe.Xn,dNdu);

    // Set up the normal vector
    if (lIndex == 1)
      normal.x = -copysign(1.0,Jac(1,1));
    else
      normal.x = copysign(1.0,Jac(1,1));
  }

  // Cartesian coordinates of current integration point
  Vec4 X(fe.Xn*fe.N,time.t);

  // Evaluate the integrand and accumulate element contributions
  if (ok && !integrand.evalBou(*A,fe,time,X,normal))
    ok = false;

  // Assembly of global system integral
  if (ok && !glInt.assemble(A->ref(),fe.iel))
    ok = false;

  A->destruct();
  return ok;
}
示例#6
0
	void Triangle::setdetJ(){
	    M_detJ = Jac().determinant();
	}
示例#7
0
文件: main.cpp 项目: labmec/neopz
int main()
{
#ifdef _AUTODIFF

#ifdef FAD
  const int dim = 3;
  const int nstate = dim+2;
  const int nphi = 6;

  // emulating state variables
  TPZVec<TPZDiffMatrix<REAL> > Ai, Tau;
  TPZVec<TPZVec<REAL> > TauDiv;
  TPZVec<TPZDiffMatrix<REAL> > TaudDiv;
  /*char ArtDiff[32]="LS";*/
  TPZArtDiffType artDiffType = LeastSquares_AD;
  TPZFMatrix dsol(dim,nstate);
  TPZFMatrix dphi(dim,nphi);
  TPZVec<REAL> phi(nphi);
  TPZVec<REAL> sol(nstate);


  TPZVec<FADREAL> FADsol(nstate);
  TPZVec<FADREAL> FADdsol(nstate*dim);
  TPZVec<TPZVec<FADREAL> > FADTauDiv;
  // generating data

  TPZArtDiff ArtDiff(artDiffType, 1.4);

  //solution
  sol[0]=2.;
  sol[1]=3.;
  sol[2]=5.;
  sol[3]=7.;
  sol[4]=11.;

  //phi
  phi[0]=2.3;
  phi[1]=3.5;
  phi[2]=5.7;
  phi[3]=7.11;
  phi[4]=11.13;
  phi[5]=13.17;

  //dphi
  int i;
  int j;
  for(i=0;i<dim;i++)
     for(j=0;j<nphi;j++)
        dphi(i,j)=45.8*i-3.2*j; // any choice

  //dsol
  for(i=0;i<dim;i++)
     for(j=0;j<nstate;j++)
        dsol(i,j)=49.8*i-3.1*j; // any choice

  int k, l;

  //FADsol
  for(i=0;i<nstate;i++)
     {
        FADsol[i]=sol[i];
        FADsol[i].diff(0,nphi*nstate);
	FADsol[i].fastAccessDx(0)=0.;
	for(j=0;j<nphi;j++)FADsol[i].fastAccessDx(i+j*nstate)=phi[j];
     }

/*  FADREAL teste;
  for(i=0;i<FADsol.NElements();i++)teste+=FADsol[i];
  cout << "\n\nFADsol\n" << teste;

  cout << "\n\nphi\n" << phi;
*/

  //FADdSol
  for(k=0;k<dim;k++)
     for(i=0;i<nstate;i++)
        {
            FADdsol[k+i*dim]=dsol(k,i);
	    FADdsol[k+i*dim].diff(0,nphi*nstate);
	    FADdsol[k+i*dim].fastAccessDx(0)=0.;
	    for(j=0;j<nphi;j++)
	    	    FADdsol[k+i*dim].fastAccessDx(i+j*nstate)=dphi(k,j);
	}
/*
	cout << "\n\nFADdsol\n";
teste=0;
for(i=0;i<FADdsol.NElements();i+=3)teste+=FADdsol[i];

cout << teste << endl;

teste=0;
for(i=1;i<FADdsol.NElements();i+=3)teste+=FADdsol[i];

cout << teste << endl;

teste=0;
for(i=2;i<FADdsol.NElements();i+=3)teste+=FADdsol[i];

cout << teste << endl;

//cout << "\n\nFADdsol\n" << FADdsol;

cout << "\n\ndphi\n" << dphi;
*/
  TPZFMatrix Jac(dim,dim,1.);
  ArtDiff.PrepareFastDiff(dim,Jac, sol, dsol, dphi, TauDiv, &TaudDiv);
  ArtDiff.PrepareFastDiff(dim, Jac, FADsol, FADdsol, FADTauDiv);


  cout << "\n\nFADTauDiv\n" << FADTauDiv;

  cout << "\n\nTauDiv\n" << TauDiv;

  cout << "\n\nTaudDiv\n" << TaudDiv;
#endif
	
#endif
  return 0;
}
    void MappingExtrapolate::v_CorrectPressureBCs(
        const Array<OneD, NekDouble>  &pressure)
    {
        if(m_HBCdata.num_elements()>0)
        {
            int cnt, n;
            int physTot = m_fields[0]->GetTotPoints();
            int nvel = m_fields.num_elements()-1;
            
            Array<OneD, NekDouble> Vals;
            // Remove previous correction
            for(cnt = n = 0; n < m_PBndConds.num_elements(); ++n)
            {
                if(m_PBndConds[n]->GetUserDefined() == "H")
                {
                    int nq = m_PBndExp[n]->GetNcoeffs();
                    Vmath::Vsub(nq, &(m_PBndExp[n]->GetCoeffs()[0]),  1,
                                    &(m_bcCorrection[cnt]), 1, 
                                    &(m_PBndExp[n]->UpdateCoeffs()[0]), 1);
                    cnt += nq;
                }
            }
            
            // Calculate new correction
            Array<OneD, NekDouble> Jac(physTot, 0.0);
            m_mapping->GetJacobian(Jac);
            
            Array<OneD, Array<OneD, NekDouble> > correction(nvel);
            Array<OneD, Array<OneD, NekDouble> > gradP(nvel);
            Array<OneD, Array<OneD, NekDouble> > wk(nvel);
            Array<OneD, Array<OneD, NekDouble> > wk2(nvel);
            for (int i=0; i<nvel; i++)
            {
                wk[i] = Array<OneD, NekDouble> (physTot, 0.0);
                gradP[i] = Array<OneD, NekDouble> (physTot, 0.0);
                correction[i] = Array<OneD, NekDouble> (physTot, 0.0);
            }

            // Calculate G(p)
            for(int i = 0; i < nvel; ++i)
            {
                m_fields[0]->PhysDeriv(MultiRegions::DirCartesianMap[i], pressure, gradP[i]);
                if(m_fields[0]->GetWaveSpace())
                {
                    m_fields[0]->HomogeneousBwdTrans(gradP[i], wk[i]);
                }
                else
                {
                    Vmath::Vcopy(physTot, gradP[i], 1, wk[i], 1);
                }
            }
            m_mapping->RaiseIndex(wk, correction);   // G(p)

            // alpha*J*(G(p))
            if (!m_mapping->HasConstantJacobian())
            {
                for(int i = 0; i < nvel; ++i)
                {
                    Vmath::Vmul(physTot, correction[i], 1, Jac, 1, correction[i], 1);
                }                
            }   
            for(int i = 0; i < nvel; ++i)
            {
                Vmath::Smul(physTot, m_pressureRelaxation, correction[i], 1, correction[i], 1); 
            }
            
            if(m_pressure->GetWaveSpace())
            {
                for(int i = 0; i < nvel; ++i)
                {
                    m_pressure->HomogeneousFwdTrans(correction[i], correction[i]);
                }
            }            
            // p_i - alpha*J*div(G(p))    
            for (int i = 0; i < nvel; ++i)
            {
                Vmath::Vsub(physTot, gradP[i], 1, correction[i], 1, correction[i], 1);
            }
            
            // Get value at boundary and calculate Inner product
            StdRegions::StdExpansionSharedPtr Pbc;
            StdRegions::StdExpansionSharedPtr elmt;
            Array<OneD, Array<OneD, const NekDouble> > correctionElmt(m_bnd_dim);
            Array<OneD, Array<OneD, NekDouble> > BndValues(m_bnd_dim);
            for(int i = 0; i < m_bnd_dim; i++)
            {
                BndValues[i] = Array<OneD, NekDouble> (m_pressureBCsMaxPts,0.0);
            }
            for(int j = 0 ; j < m_HBCdata.num_elements() ; j++)
            {
                /// Casting the boundary expansion to the specific case
                Pbc =  boost::dynamic_pointer_cast<StdRegions::StdExpansion> 
                            (m_PBndExp[m_HBCdata[j].m_bndryID]
                                ->GetExp(m_HBCdata[j].m_bndElmtID));

                /// Picking up the element where the HOPBc is located
                elmt = m_pressure->GetExp(m_HBCdata[j].m_globalElmtID);

                /// Assigning
                for(int i = 0; i < m_bnd_dim; i++)
                {
                    correctionElmt[i]  = correction[i] + m_HBCdata[j].m_physOffset;
                }
                Vals = m_bcCorrection + m_HBCdata[j].m_coeffOffset;
                // Getting values on the edge and filling the correction
                switch(m_pressure->GetExpType())
                {
                    case MultiRegions::e2D:
                    case MultiRegions::e3DH1D:
                    {                                                         
                        elmt->GetEdgePhysVals(m_HBCdata[j].m_elmtTraceID, Pbc,
                                              correctionElmt[0], BndValues[0]);                    
                        elmt->GetEdgePhysVals(m_HBCdata[j].m_elmtTraceID, Pbc,
                                              correctionElmt[1], BndValues[1]);

                        // InnerProduct 
                        Pbc->NormVectorIProductWRTBase(BndValues[0], BndValues[1],
                                                       Vals);
                    }
                    break;

                    case MultiRegions::e3D:
                    {
                        elmt->GetFacePhysVals(m_HBCdata[j].m_elmtTraceID, Pbc, 
                                              correctionElmt[0], BndValues[0]);
                        elmt->GetFacePhysVals(m_HBCdata[j].m_elmtTraceID, Pbc,
                                              correctionElmt[1], BndValues[1]);
                        elmt->GetFacePhysVals(m_HBCdata[j].m_elmtTraceID, Pbc,
                                              correctionElmt[2], BndValues[2]);
                        Pbc->NormVectorIProductWRTBase(BndValues[0], BndValues[1],
                                              BndValues[2], Vals);
                    }
                    break;
                default:
                    ASSERTL0(0,"Dimension not supported");
                    break;
                }
            }      
            
            // Apply new correction
            for(cnt = n = 0; n < m_PBndConds.num_elements(); ++n)
            {
                if(m_PBndConds[n]->GetUserDefined() == "H")
                {
                    int nq = m_PBndExp[n]->GetNcoeffs();
                    Vmath::Vadd(nq, &(m_PBndExp[n]->GetCoeffs()[0]),  1,
                                    &(m_bcCorrection[cnt]), 1, 
                                    &(m_PBndExp[n]->UpdateCoeffs()[0]), 1);
                    cnt += nq;
                }
            }                
        }        
    }
    void MappingExtrapolate::v_CalcNeumannPressureBCs(
        const Array<OneD, const Array<OneD, NekDouble> > &fields,
        const Array<OneD, const Array<OneD, NekDouble> >  &N,
        NekDouble kinvis)
    {
        if (m_mapping->HasConstantJacobian() && !m_implicitViscous)
        {
            Extrapolate::v_CalcNeumannPressureBCs( fields, N, kinvis);
        }
        else
        {
            int physTot = m_fields[0]->GetTotPoints();
            int nvel = m_fields.num_elements()-1;
            
            Array<OneD, NekDouble> Pvals;
            StdRegions::StdExpansionSharedPtr Pbc;
            StdRegions::StdExpansionSharedPtr elmt;

            Array<OneD, Array<OneD, const NekDouble> > Velocity(m_bnd_dim);
            Array<OneD, Array<OneD, const NekDouble> > Advection(m_bnd_dim);
            // Get transformation Jacobian
            Array<OneD, NekDouble> Jac(physTot,0.0);
            m_mapping->GetJacobian(Jac);
            // Declare variables
            Array<OneD, Array<OneD, NekDouble> > BndValues(m_bnd_dim);
            Array<OneD, Array<OneD, NekDouble> > Q(m_bnd_dim);
            Array<OneD, Array<OneD, NekDouble> > Q_field(nvel);
            Array<OneD, Array<OneD, NekDouble> > fields_new(nvel);
            Array<OneD, Array<OneD, NekDouble> > N_new(m_bnd_dim);
            // Temporary variables
            Array<OneD, NekDouble> tmp(physTot,0.0);
            Array<OneD, NekDouble> tmp2(physTot,0.0);
            for(int i = 0; i < m_bnd_dim; i++)
            {
                BndValues[i] = Array<OneD, NekDouble> (m_pressureBCsMaxPts,0.0);
                Q[i]         = Array<OneD, NekDouble> (m_pressureBCsElmtMaxPts,0.0);
                N_new[i]   = Array<OneD, NekDouble> (physTot,0.0);
            }
            for(int i = 0; i < nvel; i++)
            {
                Q_field[i]   = Array<OneD, NekDouble> (physTot,0.0);
                fields_new[i]   = Array<OneD, NekDouble> (physTot,0.0);
            }
            
            // Multiply convective terms by Jacobian
            for(int i = 0; i < m_bnd_dim; i++)
            {
                if (m_fields[0]->GetWaveSpace())
                {
                    m_fields[0]->HomogeneousBwdTrans(N[i],N_new[i]);
                }
                else
                {
                    Vmath::Vcopy(physTot, N[i], 1, N_new[i], 1);
                }
                Vmath::Vmul(physTot, Jac, 1, N_new[i], 1, N_new[i], 1);
                if (m_fields[0]->GetWaveSpace())
                {
                    m_fields[0]->HomogeneousFwdTrans(N_new[i],N_new[i]);
                }                          
            }
            
            // Get velocity in physical space
            for(int i = 0; i < nvel; i++)
            {
                if (m_fields[0]->GetWaveSpace())
                {
                    m_fields[0]->HomogeneousBwdTrans(fields[i],fields_new[i]);
                }        
                else
                {
                    Vmath::Vcopy(physTot, fields[i], 1, fields_new[i], 1);
                }
            }
            
            // Calculate appropriate form of the CurlCurl operator
            m_mapping->CurlCurlField(fields_new, Q_field, m_implicitViscous);
            
            // If viscous terms are treated explicitly,
            //     add grad(U/J \dot grad J) to CurlCurl
            if ( !m_implicitViscous)
            {
                m_mapping->DotGradJacobian(fields_new, tmp);
                Vmath::Vdiv(physTot, tmp, 1, Jac, 1, tmp, 1);
                
                bool wavespace = m_fields[0]->GetWaveSpace();
                m_fields[0]->SetWaveSpace(false);
                for(int i = 0; i < m_bnd_dim; i++)
                {
                    m_fields[0]->PhysDeriv(MultiRegions::DirCartesianMap[i], 
                                            tmp, tmp2);
                    Vmath::Vadd(physTot, Q_field[i], 1, tmp2, 1, Q_field[i], 1);
                }     
                m_fields[0]->SetWaveSpace(wavespace);
            }        
            
            // Multiply by Jacobian and convert to wavespace (if necessary)
            for(int i = 0; i < m_bnd_dim; i++)
            {
                Vmath::Vmul(physTot, Jac, 1, fields_new[i], 1, fields_new[i], 1);
                Vmath::Vmul(physTot, Jac, 1, Q_field[i]   , 1, Q_field[i]   , 1);
                if (m_fields[0]->GetWaveSpace())
                {
                    m_fields[0]->HomogeneousFwdTrans(fields_new[i],fields_new[i]);
                    m_fields[0]->HomogeneousFwdTrans(Q_field[i],Q_field[i]);
                }                          
            }            

            for(int j = 0 ; j < m_HBCdata.num_elements() ; j++)
            {
                /// Casting the boundary expansion to the specific case
                Pbc =  boost::dynamic_pointer_cast<StdRegions::StdExpansion> 
                            (m_PBndExp[m_HBCdata[j].m_bndryID]
                                ->GetExp(m_HBCdata[j].m_bndElmtID));

                /// Picking up the element where the HOPBc is located
                elmt = m_pressure->GetExp(m_HBCdata[j].m_globalElmtID);

                /// Assigning
                for(int i = 0; i < m_bnd_dim; i++)
                {
                    Velocity[i]  = fields_new[i] + m_HBCdata[j].m_physOffset;
                    Advection[i] = N_new[i]      + m_HBCdata[j].m_physOffset;
                    Q[i]         = Q_field[i]   + m_HBCdata[j].m_physOffset;
                }

                // Mounting advection component into the high-order condition
                for(int i = 0; i < m_bnd_dim; i++)
                {
                    MountHOPBCs(m_HBCdata[j].m_ptsInElmt,kinvis,Q[i],Advection[i]);
                }

                Pvals = m_pressureHBCs[0] + m_HBCdata[j].m_coeffOffset;

                // Getting values on the edge and filling the pressure boundary
                // expansion and the acceleration term. Multiplication by the
                // normal is required
                switch(m_pressure->GetExpType())
                {
                    case MultiRegions::e2D:
                    case MultiRegions::e3DH1D:
                    {                                                         
                        elmt->GetEdgePhysVals(m_HBCdata[j].m_elmtTraceID, Pbc,
                                              Q[0], BndValues[0]);                    
                        elmt->GetEdgePhysVals(m_HBCdata[j].m_elmtTraceID, Pbc,
                                              Q[1], BndValues[1]);

                        // InnerProduct 
                        Pbc->NormVectorIProductWRTBase(BndValues[0], BndValues[1],
                                                       Pvals);
                    }
                    break;
                    case MultiRegions::e3DH2D:
                    {
                        if(m_HBCdata[j].m_elmtTraceID == 0)
                        {
                            (m_PBndExp[m_HBCdata[j].m_bndryID]->UpdateCoeffs()
                                + m_PBndExp[m_HBCdata[j].m_bndryID]
                                    ->GetCoeff_Offset(
                                        m_HBCdata[j].m_bndElmtID))[0]
                                                                    = -1.0*Q[0][0];
                        }
                        else if (m_HBCdata[j].m_elmtTraceID == 1)
                        {
                            (m_PBndExp[m_HBCdata[j].m_bndryID]->UpdateCoeffs()
                                + m_PBndExp[m_HBCdata[j].m_bndryID]
                                    ->GetCoeff_Offset(
                                        m_HBCdata[j].m_bndElmtID))[0] 
                                                = Q[0][m_HBCdata[j].m_ptsInElmt-1];
                        }
                        else
                        {
                            ASSERTL0(false,
                                     "In the 3D homogeneous 2D approach BCs edge "
                                     "ID can be just 0 or 1 ");
                        }
                    }
                    break;
                    case MultiRegions::e3D:
                    {
                        elmt->GetFacePhysVals(m_HBCdata[j].m_elmtTraceID, Pbc, 
                                              Q[0], BndValues[0]);
                        elmt->GetFacePhysVals(m_HBCdata[j].m_elmtTraceID, Pbc,
                                              Q[1], BndValues[1]);
                        elmt->GetFacePhysVals(m_HBCdata[j].m_elmtTraceID, Pbc,
                                              Q[2], BndValues[2]);
                        Pbc->NormVectorIProductWRTBase(BndValues[0], BndValues[1],
                                              BndValues[2], Pvals);
                    }
                    break;
                default:
                    ASSERTL0(0,"Dimension not supported");
                    break;
                }
            }            
        }
        // If pressure terms are treated implicitly, we need to multiply
        //     by the relaxation parameter, and zero the correction term
        if (m_implicitPressure)
        {
            Vmath::Smul(m_pressureHBCs[0].num_elements(), m_pressureRelaxation,
                            m_pressureHBCs[0],  1,
                            m_pressureHBCs[0], 1);
        } 
        m_bcCorrection  = Array<OneD, NekDouble> (m_pressureHBCs[0].num_elements(), 0.0);
    }