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