00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef __deal2__mesh_worker_functional_h
00014 #define __deal2__mesh_worker_functional_h
00015
00016 #include <deal.II/base/named_data.h>
00017 #include <deal.II/base/smartpointer.h>
00018 #include <deal.II/base/mg_level_object.h>
00019 #include <deal.II/lac/block_vector.h>
00020 #include <deal.II/meshworker/dof_info.h>
00021 #include <deal.II/multigrid/mg_constrained_dofs.h>
00022
00023
00024 DEAL_II_NAMESPACE_OPEN
00025
00026 namespace MeshWorker
00027 {
00028 namespace Assembler
00029 {
00039 template <typename number = double>
00040 class Functional
00041 {
00042 public:
00050 void initialize(unsigned int n);
00062 template <class DOFINFO>
00063 void initialize_info(DOFINFO& info, bool face);
00064
00069 template<class DOFINFO>
00070 void assemble(const DOFINFO& info);
00071
00076 template<class DOFINFO>
00077 void assemble(const DOFINFO& info1,
00078 const DOFINFO& info2);
00079
00084 number operator() (unsigned int i) const;
00085 private:
00090 std::vector<double> results;
00091 };
00092
00100 template <typename number = double>
00101 class CellsAndFaces
00102 {
00103 public:
00109 typedef NamedData<BlockVector<number>*> DataVectors;
00110
00147 void initialize(DataVectors& results,
00148 bool separate_faces = true);
00162 template <class DOFINFO>
00163 void initialize_info(DOFINFO& info, bool face) const;
00164
00169 template<class DOFINFO>
00170 void assemble(const DOFINFO& info);
00171
00176 template<class DOFINFO>
00177 void assemble(const DOFINFO& info1,
00178 const DOFINFO& info2);
00179
00184 number operator() (unsigned int i) const;
00185 private:
00186 DataVectors results;
00187 bool separate_faces;
00188 };
00189
00190
00191 template <typename number>
00192 inline void
00193 Functional<number>::initialize(unsigned int n)
00194 {
00195 results.resize(n);
00196 std::fill(results.begin(), results.end(), 0.);
00197 }
00198
00199
00200 template <typename number>
00201 template <class DOFINFO>
00202 inline void
00203 Functional<number>::initialize_info(DOFINFO& info, bool)
00204 {
00205 info.initialize_numbers(results.size());
00206 }
00207
00208
00209 template <typename number>
00210 template <class DOFINFO>
00211 inline void
00212 Functional<number>::assemble(const DOFINFO& info)
00213 {
00214 for (unsigned int i=0;i<results.size();++i)
00215 results[i] += info.value(i);
00216 }
00217
00218
00219 template <typename number>
00220 template <class DOFINFO>
00221 inline void
00222 Functional<number>::assemble(const DOFINFO& info1,
00223 const DOFINFO& info2)
00224 {
00225 for (unsigned int i=0;i<results.size();++i)
00226 {
00227 results[i] += info1.value(i);
00228 results[i] += info2.value(i);
00229 }
00230 }
00231
00232
00233 template <typename number>
00234 inline number
00235 Functional<number>::operator() (unsigned int i) const
00236 {
00237 AssertIndexRange(i, results.size());
00238 return results[i];
00239 }
00240
00241
00242
00243 template <typename number>
00244 inline void
00245 CellsAndFaces<number>::initialize(DataVectors& r, bool sep)
00246 {
00247 Assert(r.name(0) == "cells", typename DataVectors::ExcNameMismatch(0, "cells"));
00248 if (sep)
00249 {
00250 Assert(r.name(1) == "faces", typename DataVectors::ExcNameMismatch(1, "faces"));
00251 AssertDimension(r(0)->n_blocks(), r(1)->n_blocks());
00252 }
00253
00254 results = r;
00255 separate_faces = sep;
00256 }
00257
00258
00259 template <typename number>
00260 template <class DOFINFO>
00261 inline void
00262 CellsAndFaces<number>::initialize_info(DOFINFO& info, bool) const
00263 {
00264 info.initialize_numbers(results(0)->n_blocks());
00265 }
00266
00267
00268 template <typename number>
00269 template <class DOFINFO>
00270 inline void
00271 CellsAndFaces<number>::assemble(const DOFINFO& info)
00272 {
00273 for (unsigned int i=0;i<info.n_values();++i)
00274 {
00275 if (separate_faces &&
00276 info.face_number != deal_II_numbers::invalid_unsigned_int)
00277 results(1)->block(i)(info.face->user_index()) += info.value(i);
00278 else
00279 results(0)->block(i)(info.cell->user_index()) += info.value(i);
00280 }
00281 }
00282
00283
00284 template <typename number>
00285 template <class DOFINFO>
00286 inline void
00287 CellsAndFaces<number>::assemble(const DOFINFO& info1,
00288 const DOFINFO& info2)
00289 {
00290 for (unsigned int i=0;i<info1.n_values();++i)
00291 {
00292 if (separate_faces)
00293 {
00294 const double J = info1.value(i) + info2.value(i);
00295 results(1)->block(i)(info1.face->user_index()) += J;
00296 if (info2.face != info1.face)
00297 results(1)->block(i)(info2.face->user_index()) += J;
00298 }
00299 else
00300 {
00301 results(0)->block(i)(info1.cell->user_index()) += .5*info1.value(i);
00302 results(0)->block(i)(info2.cell->user_index()) += .5*info2.value(i);
00303 }
00304 }
00305 }
00306 }
00307 }
00308
00309 DEAL_II_NAMESPACE_CLOSE
00310
00311 #endif
00312