00001 #ifndef  _MY_AssemblySystemII_
00002 #define  _MY_AssemblySystemII_
00003 #include "numericmethods.h"
00004 #include "assemblysystembase.h"
00005 #include "matrix.h"
00006 #include "mappedfevalues.h"
00007 #include "unitcube.h"
00008 
00009 
00010 
00011 
00012 
00013 template <class EqVarType,class Matriz = SparseMatrix<double>, class Vetor = VecDouble>
00014   class AssemblyOrthoMeshSystemII : public AssemblySystemBase
00015   {
00016   private:
00017     Matrix m_Ml;
00018     VecDouble  m_Bl;
00019   
00020 
00021   protected:
00022 
00023 
00024   public:
00025     AssemblyOrthoMeshSystemII(){}
00026     ~AssemblyOrthoMeshSystemII(){}
00027   
00028   void buildGlobalMatrix(Matriz& GM, EqVarType& eqvar)
00029   {
00030     GM=0;
00031     assert(eqvar.getMesh());
00032     OrthoMesh &mesh=*(eqvar.getMesh());
00033 
00034 
00035     
00036     const Matrix &MSparsity = eqvar.get_local_sparsity();
00037 
00038     assert(MSparsity.m() == MSparsity.n());
00039     unsigned n_rank = MSparsity.m();
00040     
00041     
00042     
00043     m_Ml.reinit(n_rank,n_rank);
00044     
00045     OrthoMesh::Cell_It cell = mesh.begin_cell(),
00046     endc = mesh.end_cell();
00047     for (; cell!=endc; cell++)
00048     {
00049       eqvar.reinit(cell);
00050       const VecIndex &local_global_map = eqvar.getFE().get_global_map(cell);
00051 
00052       eqvar.assembly_local_system(cell,m_Ml);
00053 
00054 
00055       
00056       for (unsigned i=0;i<n_rank;i++)
00057       {
00058         for (unsigned j=0;j<n_rank;j++)
00059         {
00060           if (MSparsity(i,j) != 0.0) 
00061             GM.add(local_global_map[i],local_global_map[j],m_Ml(i,j));
00062         }
00063       }
00064     }
00065     m_Ml.print(std::cout);
00066   }
00067 
00068       void  buildGlobalRHS(Vetor& vRHS,EqVarType& eqvar)
00069     {
00070 
00071     assert(eqvar.getMesh());
00072     OrthoMesh &mesh=*(eqvar.getMesh());
00073     vRHS=0;
00074 
00075     
00076     unsigned n_rank = eqvar.get_local_sparsity().m();
00077 
00078 
00079 
00080     
00081     m_Bl.reinit(n_rank);
00082 
00083     
00084     OrthoMesh::Cell_It cell = mesh.begin_cell(),
00085     endc = mesh.end_cell();
00086     for (; cell!=endc; cell++)
00087     {
00088       eqvar.reinit(cell);
00089       const VecIndex &local_global_map = eqvar.getFE().get_global_map(cell);
00090 
00091       
00092       eqvar.assembly_local_rhs(cell,m_Bl);
00093 
00094 
00095       
00096 
00097       for (unsigned i=0;i<n_rank;i++)
00098       {
00099         vRHS(local_global_map[i])+=m_Bl(i);
00100       }
00101 
00102     }
00103 
00104     }
00105 
00106 
00107   Index global_system_rank(EqVarType &eqvar)
00108   {
00109     
00110     Index max=0;
00111     assert(eqvar.getMesh() != NULL);
00112     OrthoMesh &mesh = *(eqvar.getMesh());
00113     
00114     OrthoMesh::Cell_It cell = mesh.begin_cell(),
00115     endc = mesh.end_cell();
00116     for (; cell!=endc; cell++)
00117     {
00118       eqvar.reinit(cell);
00119       const VecIndex &local_global_map = eqvar.getFE().get_global_map(cell);
00120       for (unsigned i=0;i<local_global_map.size();i++)
00121       {
00122         if (max < local_global_map[i])
00123           max = local_global_map[i];
00124       } 
00125     }
00126     return max+1;
00127   }
00128 
00129 
00130  
00131   Index max_nz_per_row(EqVarType& eqvar)
00132   {
00133     Point3D P1(0,0,0),P2(1,1,1);
00134     
00135     
00136     OrthoMesh mesh(P1,P2,3,3,3);
00137 
00138     
00139     OrthoMesh *backMesh = eqvar.getMesh();
00140 
00141     
00142     eqvar.reinit(mesh);
00143 
00144     
00145     
00146     Index global_rank = global_system_rank(eqvar);
00147 
00148     
00149     
00150     
00151     SparsityPattern pattern;
00152     pattern.reinit(global_rank,global_rank,global_rank);
00153     
00154     
00155     const Matrix &localSparsity = eqvar.get_local_sparsity();
00156     assert(localSparsity.m() == localSparsity.n());
00157     unsigned n_rank=localSparsity.m();
00158     
00159     OrthoMesh::Cell_It cell = mesh.begin_cell(),
00160     endc = mesh.end_cell();
00161     for (; cell!=endc; cell++)
00162     {
00163       eqvar.reinit(cell);
00164       const VecIndex &local_global_map = eqvar.getFE().get_global_map(cell);
00165       for (unsigned i=0;i<n_rank;i++)
00166         for (unsigned j=0;j<n_rank;j++)
00167         {
00168           if (localSparsity(i,j) != 0.0)
00169             pattern.add(local_global_map[i],local_global_map[j]);
00170         }
00171     }
00172     
00173     eqvar.reinit(*backMesh);
00174 
00175 
00176     
00177     pattern.compress();
00178 
00179     
00180     
00181     
00182     return pattern.max_entries_per_row();
00183   }
00184   
00185   template<class SparsePattern>
00186   void buildSparsityPattern(SparsePattern &pattern,EqVarType& eqvar)
00187   {
00188 
00189     assert(eqvar.getMesh());
00190     OrthoMesh &mesh=*(eqvar.getMesh());
00191 
00192     
00193     Index global_rank = global_system_rank(eqvar);
00194 
00195     
00196     
00197     pattern.reinit(global_rank,
00198                    global_rank,
00199                    this->max_nz_per_row(eqvar));
00200     
00201     
00202     const Matrix &localSparsity = eqvar.get_local_sparsity();
00203     assert(localSparsity.m() == localSparsity.n());
00204     unsigned n_rank=localSparsity.m();
00205 
00206     
00207     
00208     OrthoMesh::Cell_It cell = mesh.begin_cell(),
00209     endc = mesh.end_cell();
00210     for (; cell!=endc; cell++)
00211     {
00212       eqvar.reinit(cell);
00213       const VecIndex &local_global_map = eqvar.getFE().get_global_map(cell);
00214       for (unsigned i=0;i<n_rank;i++)
00215         for (unsigned j=0;j<n_rank;j++)
00216         {
00217           if (localSparsity(i,j) != 0.0)
00218             pattern.add(local_global_map[i],local_global_map[j]);
00219         }
00220     }
00221 
00222 
00223     
00224     pattern.compress();
00225 
00226     
00227   }
00228   
00229 
00230 
00243   void    addNeumannCondition(Vetor &vRHS,EqVarType& eqvar,Function3D &fN)
00244   {
00245     assert(eqvar.getMesh());
00246     OrthoMesh &mesh=*(eqvar.getMesh());
00247     
00248     Point3D pt;
00249     OrthoMesh::Cell_It cell = mesh.begin_cell(),
00250     endc = mesh.end_cell();
00251 
00252     VecDouble Bl(eqvar.getFE().n_dofs_per_face());
00253     
00254     for (; cell!=endc; cell++)
00255     {
00256       if (cell->at_boundary()) 
00257       {
00258         eqvar.reinit(cell);
00259 
00260         
00261         for (unsigned face_dir=0;face_dir<OrthoMesh::FACES_PER_CELL;face_dir++)
00262         {
00263           OrthoMesh::Face_It face = cell->face(static_cast<FaceDirection3D>(face_dir));
00264           if (face->at_boundary()) 
00265           {
00266             if (fN.isInDomain(face->barycenter()))
00267             {
00268               const VecIndex& global_map = eqvar.getFE().get_global_map(cell);
00269               const VecIndex& face_local_map = eqvar.getFE().face_to_cell_local_map(face_dir);
00270 
00271               
00272               eqvar.neumann_condition(Bl,cell,face,face_dir,fN);
00273 
00274 
00275               
00276               for (unsigned face_dof=0;face_dof<face_local_map.size();face_dof++)
00277               {
00278                 
00279                 
00280                 unsigned local_cell_dof=face_local_map[face_dof];
00281                 vRHS(global_map[local_cell_dof])+=Bl(face_dof);
00282 
00283               }
00284             }
00285           }
00286         }
00287       }
00288     }
00289   }
00290 
00291 
00292   void setBoundaryValue(const OrthoMesh &mesh,EqVarType& eqvar,Function3D &f,MapIntDouble &map_boundary)
00293   {
00294     assert(&mesh == eqvar.getMesh());
00295     VecDouble pt(3);
00296     VecDouble ptRef(3);
00297     MappingOrthoMesh map;
00298     map.reinit(mesh);
00299     OrthoMesh::Cell_It cell = mesh.begin_cell(),
00300     endc = mesh.end_cell();
00301     for (; cell!=endc; cell++)
00302     {
00303       if (cell->at_boundary()) 
00304       {
00305         eqvar.reinit(cell);
00306 
00307         
00308         for (unsigned face_no=0;face_no<OrthoMesh::FACES_PER_CELL;face_no++)
00309         {
00310           
00311           if (cell->face(static_cast<FaceDirection3D>(face_no))->at_boundary())
00312           {
00313             
00314             
00315             if (f.isInDomain(cell->face(static_cast<FaceDirection3D>(face_no))->barycenter()))
00316             {
00317               map.reinit(cell);
00318               const VecIndex &global_map=eqvar.getFE().get_global_map(cell);
00319               const VecIndex &face_dofs= eqvar.getFE().face_to_cell_local_map(face_no);
00320               
00321               for (Index local_face_dof=0;local_face_dof<face_dofs.size();local_face_dof++)
00322               {
00323                 
00324                 
00325                 Index cell_dof = face_dofs[local_face_dof]; 
00326 
00327                 
00328                 ptRef=eqvar.getFE().get_support_points()[cell_dof];
00329 
00330                 
00331                 map.T(ptRef,pt);
00332                 
00333                 
00334                 
00335                 
00336                 map_boundary[global_map[cell_dof]]=f(pt,eqvar.getFE().local_dof_field(cell_dof));
00337               }
00338             }
00339           }
00340         }
00341       }
00342     }
00343   }
00344 
00345     
00346   void getDOFSolAtVertices(VecDouble &vSol,const VecDouble &dofSol,EqVarType &eqvar,unsigned component=0)
00347   {
00348     
00349     
00350     MappedFEValues feValues(eqvar.getFE());;
00351     UnitCube refDomain;
00352     VecDouble weights(refDomain.n_vertices());
00353     weights=1;
00354     feValues.setPoints(refDomain.vertices(),weights);
00355     feValues.compute_values();
00356     
00357 
00358     
00359     vSol=INFINITY;
00360 
00361     
00362     assert(eqvar.getMesh());
00363     OrthoMesh &mesh = *(eqvar.getMesh());
00364     OrthoMesh::Cell_It cell = mesh.begin_cell(),
00365     endc = mesh.end_cell();
00366     for (; cell!=endc; cell++)
00367     {
00368       
00369       const VecIndex &global_map=  eqvar.getFE().get_global_map(cell);
00370 
00371       
00372       for (unsigned v=0;v<refDomain.n_vertices();v++)
00373       {
00374         
00375         unsigned vIndex=cell->vertex_index(static_cast<VertexDirection3D>(v));
00376         
00377         if (vSol(vIndex) == INFINITY)
00378         {
00379           
00380           
00381           vSol(vIndex)=0;
00382           for (unsigned fId=0;fId<global_map.size();fId++)
00383           {
00384             vSol(vIndex)+=feValues.function_value(v,fId)*dofSol(global_map[fId]);
00385           }
00386         }
00387       }
00388 
00389     }
00390   }
00391     
00392   
00393 
00394 
00395 
00396   };
00397 
00398 
00399 #endif