00001 #include "mixedhybridcompressiblenewton.h"
00002 
00003 
00004 MixedHybridCompressibleNewton::MixedHybridCompressibleNewton(OrthoMesh &mesh,Function3D &fPrescribedVelocities, Function3D &fPrescribedPression, const VecDouble &K,  Function1D &g, Function1D &dg,LinearSolver &solver) 
00005   :m_mesh(mesh),
00006    m_g(g),
00007    m_dg(dg),
00008    m_vK(K),
00009    m_grav(grav),
00010    m_solver(solver),
00011    _debugLevel(debugLevel)
00012 {
00013    this->setBoundaryCondition(m_bc,m_mesh,fPrescribedVelocities,fPrescribedPression,true);
00014   this->buildSparsityPattern(mesh,m_sparsePattern);
00015   m_A.reinit(m_sparsePattern);
00016   m_B.reinit(m_mesh.numCells());
00017   m_Pn.reinit(m_mesh.numCells(),NAN); 
00018   m_Pnn.reinit(m_mesh.numCells(),NAN);
00019 
00020 }
00021 
00022  void MixedHybridCompressibleNewton::iterate(TransportBase &trans) 
00023 {
00024   
00025   A = 0;
00026   B = 0;
00027   
00028   OrthoMesh::Face_It face = mesh.begin_face();
00029   unsigned nFaces = mesh.numFaces();
00030     
00031   
00032   for (unsigned faceIndex=0;faceIndex < nFaces; faceIndex++,face++)
00033   {
00034     unsigned c1,c2;
00035     face->getAdjCellIndices(c1,c2);
00036     
00037     
00038     if (!face->at_boundary())
00039     {
00040       const double P1 = Pn(c1);
00041       const double P2 = Pn(c2);
00042       const double K1 = K(c1);
00043       const double K2 = K(c2);
00044       const double Kh1 = K1*g(P1);
00045       const double Kh2 = K2*g(P2);
00046       const double Mh = 2*Kh1*Kh2/(Kh1+Kh2); 
00047       const double Keff =Mh*Inv_DX2;
00048       const double vv = Keff*(P1-P2);
00049       const double den = (Kh1+Kh2)*(Kh1+Kh2); 
00050       const double d1 = Kh2*Kh2*K1*dg(P1)/den*(P1-P2)*Inv_DX2;
00051       const double d2 = Kh1*Kh1*K2*dg(P2)/den*(P1-P2)*Inv_DX2;
00052 
00053  
00054       
00055       A.add(c1,c1,  d1+Keff);
00056       A.add(c1,c2,  d2-Keff);
00057       A.add(c2,c2, -d2+Keff);
00058       A.add(c2,c1, -d1-Keff);
00059       
00060       B(c1)-=vv;
00061       B(c2)+=vv;
00062     }
00063   }
00064   
00065     
00066     HybridFaceBC::iterator bcEnd = bc.end();
00067     for(HybridFaceBC::iterator bcIt = bc.begin();bcIt!=bcEnd;bcIt++)
00068     {
00069       OrthoMesh::Face_It face = bcIt->face;
00070       assert(face->at_boundary());
00071       
00072       unsigned c1,c2;
00073       face->getAdjCellIndices(c1,c2);
00074 
00075       if (bcIt->bcType == Dirichlet)
00076       {
00077         double vv 
00078         double c = (c1 != OrthoMesh::invalidIndex()) ? c1 : c2;
00079         double Keff = 2*K(c)*vMobT(c)*face->area()*face->areaPerCellVol();
00080         A.add(c,c,Keff);
00081         B(c) += Keff*bcIt->value;
00082       }
00083       else 
00084       {
00085         if (c1 != OrthoMesh::invalidIndex())
00086           B(c1) += -bcIt->value;
00087         else
00088           B(c2) += +bcIt->value;
00089       }
00090     }
00091 
00092 }
00093