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