00001 #ifndef _MY_AssemblySystem_
00002 #define _MY_AssemblySystem_
00003 #include "numericmethods.h"
00004 #include "assemblysystembase.h"
00005
00006
00007
00008
00009
00010
00011 template <class EqVarType,class Matriz = SparseMatrix<double>, class Vetor = VecDouble>
00012 class AssemblyOrthoMeshSystem : public AssemblySystemBase
00013 {
00014 private:
00015 FullMatrix<double> m_Ml;
00016 Vector<double> m_Bl;
00017
00018 protected:
00019 void distribute_local_to_global(Matriz&GM,FullMatrix<double> &lM,const std::vector<unsigned> &local_dof_indices,const bool checkZero,double tolerance=0.0)
00020 {
00021 const unsigned dofs_per_cell = local_dof_indices.size();
00022 if (checkZero)
00023 {
00024
00025 for (unsigned int i=0; i<dofs_per_cell; ++i)
00026 for (unsigned int j=0; j<dofs_per_cell; ++j)
00027 {
00028 if (fabs(lM(i,j))<=tolerance)
00029 continue;
00030 else
00031 {
00032 #ifdef DEBUG
00033 if (GM.get_sparsity_pattern().exists(local_dof_indices[i],local_dof_indices[j]))
00034 {
00035 GM.add (local_dof_indices[i],local_dof_indices[j],lM(i,j));
00036 }
00037 else
00038 printf("Trying to put value %g in invalid entry (%d,%d)\n",lM(i,j),local_dof_indices[i],local_dof_indices[j]);
00039 #else
00040 GM.add (local_dof_indices[i],local_dof_indices[j],lM(i,j));
00041 #endif
00042 }
00043 }
00044 }
00045 else
00046 {
00047
00048 for (unsigned int i=0; i<dofs_per_cell; ++i)
00049 for (unsigned int j=0; j<dofs_per_cell; ++j)
00050 GM.add (local_dof_indices[i],local_dof_indices[j],lM(i,j));
00051 }
00052
00053 }
00054
00055
00056 public:
00057 AssemblyOrthoMeshSystem(){}
00058 ~AssemblyOrthoMeshSystem(){}
00059
00060 void buildGlobalMatrix(Matriz& GM,OrthoMesh &mesh, EqVarType& eqvar,const bool checkZero=false,double tolerance =0.0)
00061 {
00062
00063
00064 unsigned i,j;
00065 const unsigned int dofs_per_cell = eqvar.n_dofs_per_cell();
00066 const unsigned n_quadrature_points = eqvar.n_quadrature_points();
00067
00068
00069 GM = 0;
00070 m_Ml.reinit(dofs_per_cell,dofs_per_cell);
00071
00072
00073
00074
00075
00076
00077 OrthoMesh::Cell_It cell = mesh.begin_cell(),
00078 endc = mesh.end_cell();
00079
00080 for (; cell!=endc; cell++)
00081 {
00082 eqvar.setCell(cell);
00083 eqvar.changedCellEvent();
00084
00085 m_Ml=0.0;
00086 for (Index qPoint=0; qPoint<n_quadrature_points; qPoint++)
00087 {
00088 for (i=0; i<dofs_per_cell; ++i)
00089 {
00090 for (j=0; j<dofs_per_cell; ++j)
00091 m_Ml(i,j) += eqvar.localEqVar(i,j,qPoint);
00092 }
00093 }
00094
00095 this->distribute_local_to_global(GM,m_Ml,eqvar.local_to_global_dofs_map(),checkZero,tolerance);
00096 }
00097 return;
00098 }
00099
00100
00101 template<class SparsePattern>
00102 void buildSparsityPattern(SparsePattern &pattern,OrthoMesh &mesh,EqVarType& eqvar)
00103 {
00104 unsigned i,j;
00105
00106
00107 m_Ml.reinit(eqvar.n_dofs_per_cell(),eqvar.n_dofs_per_cell());
00108
00109 OrthoMesh::Cell_It cell = mesh.begin_cell(),
00110 endc = mesh.end_cell();
00111
00112
00113 m_Ml=0.0;
00114 unsigned n_dofs_per_cell=eqvar.n_dofs_per_cell();
00115
00116 for (i=0; i<n_dofs_per_cell; ++i)
00117 {
00118 for (j=0; j<n_dofs_per_cell; ++j)
00119 m_Ml(i,j) += (eqvar.nullProduct(i,j)) ? 0 : 1;
00120 }
00121
00122
00123 for (; cell!=endc; cell++)
00124 {
00125 eqvar.setCell(cell);
00126 for (unsigned int i=0; i<n_dofs_per_cell; ++i)
00127 for (unsigned int j=0; j<n_dofs_per_cell; ++j)
00128 {
00129 if (m_Ml(i,j) == 0.0)
00130 {
00131
00132 continue;
00133 }
00134 else
00135 pattern.add (eqvar.local_to_global_dofs_map()[i],eqvar.local_to_global_dofs_map()[j]);
00136 }
00137 }
00138 }
00139
00140 void buildGlobalRhs(Vetor& vRhs,OrthoMesh &mesh,EqVarType& eqvar)
00141 {
00142 unsigned i;
00143
00144 const unsigned int n_dofs_per_cell = eqvar.n_dofs_per_cell();
00145 unsigned n_quadrature_points = eqvar.n_quadrature_points();
00146
00147
00148 assert(vRhs.size() == eqvar.n_dofs());
00149 vRhs = 0;
00150
00151
00152
00153 m_Bl.reinit(n_dofs_per_cell);
00154
00155
00156
00157 OrthoMesh::Cell_It cell = mesh.begin_cell(),
00158 endc = mesh.end_cell();
00159
00160 for (; cell!=endc; cell++)
00161 {
00162 eqvar.setCell(cell);
00163 m_Bl = 0;
00164 for (unsigned qPoint=0; qPoint<n_quadrature_points; qPoint++)
00165 {
00166 for (i=0; i<n_dofs_per_cell; ++i)
00167 {
00168 m_Bl(i) += eqvar.localRHS(i,qPoint);
00169 }
00170 }
00171
00172 for (unsigned int i=0; i<n_dofs_per_cell; ++i)
00173 {
00174 vRhs(eqvar.local_to_global_dofs_map()[i]) += m_Bl(i);
00175 }
00176 }
00177 }
00178
00179
00192 void addNeummanCondition(const OrthoMesh &mesh,Vetor &vRHS,EqVarType& eqvar,Function3D &fN)
00193 {
00194 Point3D pt;
00195 const unsigned int dofs_per_cell = eqvar.n_dofs_per_cell();
00196 const unsigned int n_face_quadrature_pts = eqvar.n_face_quadrature_points();
00197 OrthoMesh::Cell_It cell = mesh.begin_cell(),
00198 endc = mesh.end_cell();
00199
00200 for (; cell!=endc; cell++)
00201 {
00202 if (cell->at_boundary())
00203 {
00204 eqvar.setCell(cell);
00205
00206
00207 for (unsigned face_no=0;face_no<OrthoMesh::FACES_PER_CELL;face_no++)
00208 {
00209 OrthoMesh::Face_It face = cell->face(static_cast<FaceDirection3D>(face_no));
00210 if (face->at_boundary())
00211 {
00212 if (fN.isInDomain(face->barycenter()))
00213 {
00214 eqvar.setFace(face);
00215
00216 for (Index local_dof=0;local_dof<dofs_per_cell;local_dof++)
00217 {
00218
00219
00220 Index cell_dof = eqvar.local_to_global_dofs_map()[local_dof];
00221 double acum=0;
00222 for (unsigned fQPoint=0;fQPoint < n_face_quadrature_pts;fQPoint++)
00223 {
00224 vRHS(cell_dof)+=eqvar.localNeummanCondition(face_no,local_dof,fQPoint,fN);
00225 acum+=eqvar.localNeummanCondition(face_no,local_dof,fQPoint,fN);
00226 }
00227 printf("Acum: %g\n",acum);
00228 }
00229 }
00230 }
00231 }
00232 }
00233 }
00234 }
00235
00236
00237 void setBoundaryValue(const OrthoMesh &mesh,EqVarType& eqvar,Function3D &f,MapIntDouble &map_boundary)
00238 {
00239 Point3D pt;
00240 const unsigned int dofs_per_face = eqvar.n_dofs_per_face();
00241 std::vector<unsigned> face_dofs(dofs_per_face);
00242 OrthoMesh::Cell_It cell = mesh.begin_cell(),
00243 endc = mesh.end_cell();
00244
00245 for (; cell!=endc; cell++)
00246 {
00247 if (cell->at_boundary())
00248 {
00249 eqvar.setCell(cell);
00250
00251 for (unsigned face_no=0;face_no<OrthoMesh::FACES_PER_CELL;face_no++)
00252 {
00253
00254 if (cell->face(static_cast<FaceDirection3D>(face_no))->at_boundary())
00255 {
00256 if (f.isInDomain(cell->face(static_cast<FaceDirection3D>(face_no))->barycenter()))
00257
00258 for (Index local_face_dof=0;local_face_dof<dofs_per_face;local_face_dof++)
00259 {
00260
00261
00262 Index cell_dof = eqvar.local_face_to_local_cell_map(face_no,local_face_dof);
00263 pt=eqvar.get_global_dof_position(cell_dof);
00264 map_boundary[eqvar.local_to_global_dofs_map()[cell_dof]]=f(pt,eqvar.local_dof_component(cell_dof));
00265
00266 }
00267 }
00268 }
00269 }
00270 }
00271 }
00272
00273
00274
00275 };
00276
00277
00278 #endif