LifeV
OseenAssembler.hpp
Go to the documentation of this file.
1 //@HEADER
2 /*
3 ************************************************************************
4 
5  This file is part of the LifeV Applications.
6  Copyright (C) 2001-2010 EPFL, Politecnico di Milano, INRIA
7 
8  This library is free software; you can redistribute it and/or modify
9  it under the terms of the GNU Lesser General Public License as
10  published by the Free Software Foundation; either version 2.1 of the
11  License, or (at your option) any later version.
12 
13  This library is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  Lesser General Public License for more details.
17 
18  You should have received a copy of the GNU Lesser General Public
19  License along with this library; if not, write to the Free Software
20  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21  USA
22 
23 ************************************************************************
24 */
25 //@HEADER
26 
27 /*!
28  @file
29  @brief A short description of the file content
30 
31  @author Samuel Quinodoz <samuel.quinodoz@epfl.ch>
32  @contributor Gwenol Grandperrin <gwenol.grandperrin@epfl.ch>
33  @date 16 Nov 2010
34 
35  A more detailed description of the file (if necessary)
36  */
37 
38 #ifndef OSEENASSEMBLER_H
39 #define OSEENASSEMBLER_H 1
40 
41 #include <lifev/core/util/LifeChrono.hpp>
42 #include <lifev/core/LifeV.hpp>
43 
44 #include <lifev/core/fem/Assembly.hpp>
45 #include <lifev/core/fem/FESpace.hpp>
46 #include <lifev/core/fem/AssemblyElemental.hpp>
47 #include <lifev/core/fem/BCHandler.hpp>
48 #include <lifev/core/fem/QuadratureRuleProvider.hpp>
49 
50 #include <boost/shared_ptr.hpp>
51 #include <boost/scoped_ptr.hpp>
52 
53 namespace LifeV
54 {
55 
56 //! OseenAssembler - Assembly class for the Oseen problem
57 /*!
58  Signes!!
59  Coefficients
60 
61  @author Samuel Quinodoz
62 
63  */
64 
65 template< typename meshType, typename matrixType, typename vectorType>
67 {
68 public:
69 
70  //! @name Public Types
71  //@{
72 
74 
75  typedef FESpace<meshType, map_Type> fespace_Type;
77 
78  typedef AssemblyElemental::function_Type function_Type;
79 
81 
83 
84  //@}
85 
86 
87  //! @name Constructor & Destructor
88  //@{
89 
90  //! Empty Constructor
92 
93  //! Destructor
94  virtual ~OseenAssembler() {};
95 
96  //@}
97 
98 
99  //! @name Methods
100  //@{
101 
102  //! Setup method for the FESpaces.
103  /*!
104  This method sets the FESpace for the assembly. With this method, the convective
105  field is assumed to be the same as the velocity field. If they differ, use another
106  setup method.
107  */
108  void setup (const fespacePtr_Type& uFESpace, const fespacePtr_Type& pFESpace)
109  {
110  setup (uFESpace, pFESpace, uFESpace);
111  }
112 
113  //! Setup method for the FESpace with a different space for the convective field
114  void setup (const fespacePtr_Type& uFESpace, const fespacePtr_Type& pFESpace, const fespacePtr_Type& betaFESpace);
115 
116  //@}
117 
118 
119  //! @name Assembly procedures
120  //@{
121 
122  //! Add the viscous stress in the standard block
123  void addViscousStress (matrixType& matrix, const Real& viscosity)
124  {
125  addViscousStress (matrix, viscosity, 0, 0);
126  };
127 
128  //! Add the viscous stress using the given offsets
129  void addViscousStress (matrixType& matrix, const Real& viscosity, const UInt& offsetLeft, const UInt& offsetUp);
130 
131  //! Add the stiff strain in the standard block
132  void addStiffStrain (matrixType& matrix, const Real& viscosity)
133  {
134  addStiffStrain (matrix, viscosity, 0, 0);
135  };
136 
137  //! Add the stiff strain using the given offsets
138  void addStiffStrain (matrixType& matrix, const Real& viscosity, const UInt& offsetLeft, const UInt& offsetUp);
139 
140  //! Add the term involved in the gradient of the pressure term
141  void addGradPressure (matrixType& matrix)
142  {
143  addGradPressure (matrix, M_uFESpace->dof().numTotalDof() *nDimensions, 0);
144  };
145 
146  //! Add the term involved in the gradient of the pressure term using the given offsets
147  void addGradPressure (matrixType& matrix, const UInt& offsetLeft, const UInt& offsetUp);
148 
149  //! Add the term corresponding to the divergence free constraint
150  /*!
151  * The default choice coefficient=1.0 leads to a divergence matrix which is the transpose of the
152  * pressure gradient matrix.
153  */
154  void addGradientTranspose (matrixType& matrix, const Real& coefficient = 1.0)
155  {
156  addGradientTranspose (matrix, 0, M_uFESpace->dof().numTotalDof() *nDimensions, coefficient);
157  };
158 
159  //! Add the divergence free constraint in a given position of the matrix using the grad calls.
160  void addGradientTranspose (matrixType& matrix, const UInt& offsetLeft, const UInt& offsetUp, const Real& coefficient = 1.0);
161 
162  //! Add the term corresponding to the divergence free constraint
163  /*!
164  * The default choice coefficient=1.0 leads to a divergence matrix which is the transpose of the
165  * pressure gradient matrix.
166  */
167  void addDivergence (matrixType& matrix, const Real& coefficient = 1.0)
168  {
169  addDivergence (matrix, 0, M_uFESpace->dof().numTotalDof() *nDimensions, coefficient);
170  };
171 
172  //! Add the divergence free constraint in a given position of the matrix.
173  void addDivergence (matrixType& matrix, const UInt& offsetLeft, const UInt& offsetUp, const Real& coefficient = 1.0);
174 
175  //! Add the mass
176  void addMass (matrixType& matrix, const Real& coefficient)
177  {
178  addMass (matrix, coefficient, 0, 0);
179  };
180 
181  //! Add the mass using offsets
182  void addMass (matrixType& matrix, const Real& coefficient, const UInt& offsetLeft, const UInt offsetUp);
183 
184  //! Add the Pressure mass
185  void addPressureMass (matrixType& matrix, const Real& coefficient)
186  {
187  addPressureMass (matrix, coefficient, M_uFESpace->dof().numTotalDof() *nDimensions,
188  M_uFESpace->dof().numTotalDof() *nDimensions);
189  }
190 
191  //! Add the mass using offsets
192  void addPressureMass (matrixType& matrix, const Real& coefficient, const UInt& offsetLeft, const UInt offsetUp);
193 
194  //! Add a consistent stabilizing term
195  void addMassDivW (matrixType& matrix, const Real& coefficient, const vectorType& beta)
196  {
197  addMassDivW (matrix, coefficient, beta, 0, 0);
198  }
199 
200  //! Add a consistent stabilizing term with the given offsets
201  void addMassDivW (matrixType& matrix, const Real& coefficient, const vectorType& beta, const UInt& offsetLeft, const UInt offsetUp);
202 
203  //! Add the convective term
204  void addConvection (matrixType& matrix, const Real& coefficient, const vectorType& beta)
205  {
206  addConvection (matrix, coefficient, beta, 0, 0);
207  }
208 
209  //! Add the convective term with the given offsets
210  void addConvection (matrixType& matrix, const Real& coefficient, const vectorType& beta, const UInt& offsetLeft, const UInt offsetUp);
211 
212  //! Add the convective term necessary to build the Newton method
213  void addNewtonConvection ( matrixType& matrix, const vectorType& beta, const UInt& offsetLeft, const UInt offsetUp );
214 
215  //! Add the convective term necessary to build the Newton method
216  void addNewtonConvection ( matrixType& matrix, const vectorType& beta )
217  {
218  addNewtonConvection ( matrix, beta, 0, 0 );
219  }
220 
221  //! Add the convective term
222  void addSymmetricConvection (matrixType& matrix, const Real& coefficient, const vectorType& beta)
223  {
224  addSymmetricConvection (matrix, coefficient, beta, 0, 0);
225  }
226 
227  //! Add the symmetric convective term with the given offset
228  void addSymmetricConvection (matrixType& matrix, const Real& coefficient, const vectorType& beta, const UInt& offsetLeft, const UInt offsetUp);
229 
230  //! Add an explicit convection term to the right hand side
231  void addConvectionRhs (vectorType& rhs, const Real& coefficient, const vectorType& velocity);
232 
233  void addMassRhs (vectorType& rhs, const function_Type& fun, const Real& t);
234 
235  void addFluxTerms (vectorType& vector, BCHandler const& bcHandler);
236  //@}
237 
238 
239  //! @name Set Methods
240  //@{
241 
242  //! Setter for the quadrature used for the right hand side
243  /*!
244  Beware that calling this function might be quite heavy, so avoid using
245  it when it is not necessary.
246  */
247  inline void setQuadRuleForMassRhs (const QuadratureRule& qr)
248  {
249  ASSERT (M_massRhsCFE != 0, "No Rhs currentFE for setting the quadrature rule!");
250  M_massRhsCFE->setQuadRule (qr);
251  }
252 
253 
254  //@}
255 
256 
257  //! @name Get Methods
258  //@{
259 
260  //@}
261 
262 private:
263 
266 
267  typedef MatrixElemental localMatrix_Type;
269 
270  typedef VectorElemental localVector_Type;
272 
273 
274  //! @name Private Methods
275  //@{
276 
277  // No copy constructor
279 
280  //@}
281 
282  // Velocity FE space
284 
285  // Pressure FE space
287 
288  // Beta FE space
290 
291  // CurrentFE
293 
296 
299 
303 
306 
308 
309  // CurrentFE for the mass rhs
311 
312 
313  // Local matrix
315 
317 
319 
321 
323 
325 
327  // Local vector for the right hand side
329 
330 };
331 
332 template< typename meshType, typename matrixType, typename vectorType>
333 OseenAssembler<meshType, matrixType, vectorType>::
335 
336  M_uFESpace(),
337  M_pFESpace(),
338  M_betaFESpace(),
339 
340  M_viscousCFE(),
345  M_massCFE(),
346  M_massBetaCFE(),
351  M_massRhsCFE(),
352 
353  M_localViscous(),
356  M_localMass(),
361 
362 {}
363 
364 
365 template< typename meshType, typename matrixType, typename vectorType>
366 void
367 OseenAssembler<meshType, matrixType, vectorType>::
368 setup (const fespacePtr_Type& uFESpace, const fespacePtr_Type& pFESpace, const fespacePtr_Type& betaFESpace)
369 {
370  ASSERT (uFESpace != 0, "Impossible to set empty FE space for the velocity. ");
371  ASSERT (pFESpace != 0, "Impossible to set empty FE space for the pressure. ");
372  ASSERT (betaFESpace != 0, "Impossible to set empty FE space for the convective field (beta). ");
373 
374  ASSERT (uFESpace->fieldDim() == nDimensions, "FE space for the velocity has to be vectorial");
375  ASSERT (pFESpace->fieldDim() == 1, "FE space for the pressure has to be scalar");
376  ASSERT (betaFESpace->fieldDim() == nDimensions, "FE space for the convective field (beta) has to be vectorial");
377 
378  M_uFESpace = uFESpace;
379  M_pFESpace = pFESpace;
380  M_betaFESpace = betaFESpace;
381 
382  UInt uDegree (M_uFESpace->polynomialDegree() );
383  UInt pDegree (M_pFESpace->polynomialDegree() );
384  UInt betaDegree (M_betaFESpace->polynomialDegree() );
385 
386  M_viscousCFE.reset (new currentFE_Type (M_uFESpace->refFE(),
387  M_uFESpace->fe().geoMap(),
388  QuadratureRuleProvider::provideExactness (TETRA, 2 * uDegree - 2) ) );
389 
390  M_gradPressureUCFE.reset (new currentFE_Type (M_uFESpace->refFE(),
391  M_uFESpace->fe().geoMap(),
392  QuadratureRuleProvider::provideExactness (TETRA, uDegree + pDegree - 1) ) );
393 
394  M_gradPressurePCFE.reset (new currentFE_Type (M_pFESpace->refFE(),
395  M_uFESpace->fe().geoMap(),
396  QuadratureRuleProvider::provideExactness (TETRA, uDegree + pDegree - 1) ) );
397 
398  M_divergenceUCFE.reset (new currentFE_Type (M_uFESpace->refFE(),
399  M_uFESpace->fe().geoMap(),
400  QuadratureRuleProvider::provideExactness (TETRA, uDegree + pDegree - 1) ) );
401 
402 
403  M_divergencePCFE.reset (new currentFE_Type (M_pFESpace->refFE(),
404  M_uFESpace->fe().geoMap(),
405  QuadratureRuleProvider::provideExactness (TETRA, uDegree + pDegree - 1) ) );
406 
407  M_massCFE.reset (new currentFE_Type (M_uFESpace->refFE(),
408  M_uFESpace->fe().geoMap(),
409  QuadratureRuleProvider::provideExactness (TETRA, 2 * uDegree) ) );
410 
411  M_massBetaCFE.reset (new currentFE_Type (M_betaFESpace->refFE(),
412  M_uFESpace->fe().geoMap(),
413  QuadratureRuleProvider::provideExactness (TETRA, 2 * uDegree) ) );
414 
415  M_massPressureCFE.reset (new currentFE_Type (M_pFESpace->refFE(),
416  M_pFESpace->fe().geoMap(),
417  QuadratureRuleProvider::provideExactness (TETRA, 2 * pDegree) ) );
418 
419  M_convectionUCFE.reset (new currentFE_Type (M_uFESpace->refFE(),
420  M_uFESpace->fe().geoMap(),
421  QuadratureRuleProvider::provideExactness (TETRA, 2 * uDegree + betaDegree - 1) ) );
422 
423  M_convectionBetaCFE.reset (new currentFE_Type (M_betaFESpace->refFE(),
424  M_uFESpace->fe().geoMap(),
425  QuadratureRuleProvider::provideExactness (TETRA, 2 * uDegree + betaDegree - 1) ) );
426 
427  M_convectionRhsUCFE.reset (new currentFE_Type (M_betaFESpace->refFE(),
428  M_uFESpace->fe().geoMap(),
429  QuadratureRuleProvider::provideExactness (TETRA, 2 * betaDegree + betaDegree - 1) ) );
430 
431  M_localViscous.reset (new localMatrix_Type (M_uFESpace->fe().nbFEDof(),
432  M_uFESpace->fieldDim(),
433  M_uFESpace->fieldDim() ) );
434 
435  M_localGradPressure.reset (new localMatrix_Type (M_uFESpace->fe().nbFEDof(), nDimensions, 0,
436  M_pFESpace->fe().nbFEDof(), 0, 1) );
437 
438  M_localDivergence.reset (new localMatrix_Type (M_uFESpace->fe().nbFEDof(), 0, nDimensions,
439  M_pFESpace->fe().nbFEDof(), 1, 0) );
440 
441  M_localMass.reset (new localMatrix_Type (M_uFESpace->fe().nbFEDof(),
442  M_uFESpace->fieldDim(),
443  M_uFESpace->fieldDim() ) );
444 
445  M_localMassPressure.reset (new localMatrix_Type (M_pFESpace->fe().nbFEDof(),
446  M_pFESpace->fieldDim(),
447  M_pFESpace->fieldDim() ) );
448  M_localConvection.reset (new localMatrix_Type (M_uFESpace->fe().nbFEDof(),
449  M_uFESpace->fieldDim(),
450  M_uFESpace->fieldDim() ) );
451 
452  M_localConvectionRhs.reset (new localVector_Type (M_uFESpace->fe().nbFEDof(), M_uFESpace->fieldDim() ) );
453 
454  M_massRhsCFE.reset (new currentFE_Type (M_uFESpace->refFE(), M_uFESpace->fe().geoMap(), M_uFESpace->qr() ) );
455 
456  M_localMassRhs.reset (new localVector_Type (M_uFESpace->fe().nbFEDof(), M_uFESpace->fieldDim() ) );
457 
458 
459 
460 }
461 
462 
463 template< typename meshType, typename matrixType, typename vectorType>
464 void
465 OseenAssembler<meshType, matrixType, vectorType>::
466 addViscousStress (matrixType& matrix, const Real& viscosity, const UInt& offsetLeft, const UInt& offsetUp)
467 {
468  ASSERT (M_uFESpace != 0, "No FE space for assembling the viscous stress.");
469  ASSERT (offsetLeft + M_uFESpace->dof().numTotalDof() * (M_uFESpace->fieldDim() ) <=
470  UInt (matrix.matrixPtr()->NumGlobalCols() ),
471  " The matrix is too small (columns) for the assembly of the viscous stress");
472  ASSERT (offsetUp + M_uFESpace->dof().numTotalDof() * (M_uFESpace->fieldDim() ) <=
473  UInt (matrix.matrixPtr()->NumGlobalRows() ),
474  " The matrix is too small (rows) for the assembly of the viscous stress");
475 
476  // Some constants
477  const UInt nbElements (M_uFESpace->mesh()->numElements() );
478  const UInt fieldDim (M_uFESpace->fieldDim() );
479  const UInt nbTotalDof (M_uFESpace->dof().numTotalDof() );
480 
481  // Loop over the elements
482  for (UInt iterElement (0); iterElement < nbElements; ++iterElement)
483  {
484  // Update the diffusion current FE
485  M_viscousCFE->update ( M_uFESpace->mesh()->element (iterElement), UPDATE_DPHI | UPDATE_WDET );
486 
487  // Clean the local matrix
488  M_localViscous->zero();
489 
490  // local stiffness
491  AssemblyElemental::stiffness (*M_localViscous, *M_viscousCFE, viscosity, fieldDim);
492 
493  // Assembly
494  for (UInt iFieldDim (0); iFieldDim < fieldDim; ++iFieldDim)
495  {
496  assembleMatrix ( matrix,
497  *M_localViscous,
498  *M_viscousCFE,
499  *M_viscousCFE,
500  M_uFESpace->dof(),
501  M_uFESpace->dof(),
502  iFieldDim, iFieldDim,
503  iFieldDim * nbTotalDof + offsetUp, iFieldDim * nbTotalDof + offsetLeft);
504  }
505  }
506 }
507 
508 template< typename meshType, typename matrixType, typename vectorType>
509 void
510 OseenAssembler<meshType, matrixType, vectorType>::
511 addStiffStrain (matrixType& matrix, const Real& viscosity, const UInt& offsetLeft, const UInt& offsetUp)
512 {
513  ASSERT (M_uFESpace != 0, "No FE space for assembling the stiff strain.");
514  ASSERT (offsetLeft + M_uFESpace->dof().numTotalDof() * (M_uFESpace->fieldDim() ) <=
515  UInt (matrix.matrixPtr()->NumGlobalCols() ),
516  " The matrix is too small (columns) for the assembly of the stiff strain");
517  ASSERT (offsetUp + M_uFESpace->dof().numTotalDof() * (M_uFESpace->fieldDim() ) <=
518  UInt (matrix.matrixPtr()->NumGlobalRows() ),
519  " The matrix is too small (rows) for the assembly of the stiff strain");
520 
521  // Some constants
522  const UInt nbElements (M_uFESpace->mesh()->numElements() );
523  const UInt fieldDim (M_uFESpace->fieldDim() );
524  const UInt nbTotalDof (M_uFESpace->dof().numTotalDof() );
525 
526  // Loop over the elements
527  for (UInt iterElement (0); iterElement < nbElements; ++iterElement)
528  {
529  // Update the diffusion current FE
530  M_viscousCFE->update ( M_uFESpace->mesh()->element (iterElement), UPDATE_DPHI | UPDATE_WDET );
531 
532  // Clean the local matrix
533  M_localViscous->zero();
534 
535  // local stiffness
536  AssemblyElemental::stiffStrain (*M_localViscous, *M_viscousCFE, 2.0 * viscosity, fieldDim);
537 
538  // Assembly
539  for (UInt iFieldDim (0); iFieldDim < fieldDim; ++iFieldDim)
540  {
541  for (UInt jFieldDim (0); jFieldDim < fieldDim; ++jFieldDim)
542  {
543  assembleMatrix ( matrix,
544  *M_localViscous,
545  *M_viscousCFE,
546  *M_viscousCFE,
547  M_uFESpace->dof(),
548  M_uFESpace->dof(),
549  iFieldDim, jFieldDim,
550  iFieldDim * nbTotalDof + offsetUp, jFieldDim * nbTotalDof + offsetLeft);
551  }
552  }
553  }
554 }
555 
556 template< typename meshType, typename matrixType, typename vectorType>
557 void
558 OseenAssembler<meshType, matrixType, vectorType>::
559 addGradPressure (matrixType& matrix, const UInt& offsetLeft, const UInt& offsetUp)
560 {
561  ASSERT (M_uFESpace != 0, "No velocity FE space for assembling the pressure gradient.");
562  ASSERT (M_pFESpace != 0, "No pressure FE space for assembling the pressure gradient.");
563  ASSERT (offsetLeft + M_pFESpace->dof().numTotalDof() <=
564  UInt (matrix.matrixPtr()->NumGlobalCols() ),
565  "The matrix is too small (columns) for the assembly of the pressure gradient");
566  ASSERT (offsetUp + M_uFESpace->dof().numTotalDof() *nDimensions <=
567  UInt (matrix.matrixPtr()->NumGlobalRows() ),
568  " The matrix is too small (rows) for the assembly of the pressure gradient");
569 
570  // Some constants
571  const UInt nbElements (M_uFESpace->mesh()->numElements() );
572  const UInt fieldDim (M_uFESpace->fieldDim() );
573  const UInt nbUTotalDof (M_uFESpace->dof().numTotalDof() );
574 
575  // Loop over the elements
576  for (UInt iterElement (0); iterElement < nbElements; ++iterElement)
577  {
578  // Update the diffusion current FE
579  M_gradPressureUCFE->update ( M_uFESpace->mesh()->element (iterElement), UPDATE_DPHI | UPDATE_WDET );
580  M_gradPressurePCFE->update ( M_uFESpace->mesh()->element (iterElement), UPDATE_WDET );
581 
582  // Clean the local matrix
583  M_localGradPressure->zero();
584 
585  // local stiffness
586  AssemblyElemental::grad (*M_localGradPressure, *M_gradPressureUCFE, *M_gradPressurePCFE, fieldDim);
587 
588  // Assembly
589  for (UInt iFieldDim (0); iFieldDim < nDimensions; ++iFieldDim)
590  {
591  assembleMatrix ( matrix,
592  *M_localGradPressure,
593  *M_gradPressureUCFE,
594  *M_gradPressurePCFE,
595  M_uFESpace->dof(),
596  M_pFESpace->dof(),
597  iFieldDim, 0,
598  iFieldDim * nbUTotalDof + offsetUp, offsetLeft);
599  }
600  }
601 }
602 
603 template< typename meshType, typename matrixType, typename vectorType>
604 void
605 OseenAssembler<meshType, matrixType, vectorType>::
606 addGradientTranspose (matrixType& matrix, const UInt& offsetLeft, const UInt& offsetUp, const Real& coefficient)
607 {
608  ASSERT (M_uFESpace != 0, "No velocity FE space for assembling the pressure gradient.");
609  ASSERT (M_pFESpace != 0, "No pressure FE space for assembling the pressure gradient.");
610  ASSERT (offsetUp + M_pFESpace->dof().numTotalDof() <=
611  UInt (matrix.matrixPtr()->NumGlobalCols() ),
612  "The matrix is too small (columns) for the assembly of the pressure gradient");
613  ASSERT (offsetLeft + M_uFESpace->dof().numTotalDof() *nDimensions <=
614  UInt (matrix.matrixPtr()->NumGlobalRows() ),
615  " The matrix is too small (rows) for the assembly of the pressure gradient");
616 
617  // Some constants
618  const UInt nbElements (M_uFESpace->mesh()->numElements() );
619  const UInt fieldDim (M_uFESpace->fieldDim() );
620  const UInt nbUTotalDof (M_uFESpace->dof().numTotalDof() );
621 
622  // Loop over the elements
623  for (UInt iterElement (0); iterElement < nbElements; ++iterElement)
624  {
625  // Update the diffusion current FE
626  M_gradPressureUCFE->update ( M_uFESpace->mesh()->element (iterElement), UPDATE_DPHI | UPDATE_WDET );
627  M_gradPressurePCFE->update ( M_uFESpace->mesh()->element (iterElement), UPDATE_WDET );
628 
629  // Clean the local matrix
630  M_localGradPressure->zero();
631 
632  // local stiffness
633  AssemblyElemental::grad (*M_localGradPressure, *M_gradPressureUCFE, *M_gradPressurePCFE, fieldDim);
634 
635  // Assembly
636  for (UInt iFieldDim (0); iFieldDim < nDimensions; ++iFieldDim)
637  {
638  assembleTransposeMatrix ( matrix,
639  -coefficient,
640  *M_localGradPressure,
641  *M_gradPressurePCFE,
642  *M_gradPressureUCFE,
643  M_pFESpace->dof(),
644  M_uFESpace->dof(),
645  0, iFieldDim,
646  offsetUp, iFieldDim * nbUTotalDof + offsetLeft);
647  }
648  }
649 }
650 template< typename meshType, typename matrixType, typename vectorType>
651 void
652 OseenAssembler<meshType, matrixType, vectorType>::
653 addDivergence (matrixType& matrix, const UInt& offsetLeft, const UInt& offsetUp, const Real& coefficient)
654 {
655  ASSERT (M_uFESpace != 0, "No velocity FE space for assembling the divergence.");
656  ASSERT (M_pFESpace != 0, "No pressure FE space for assembling the divergence.");
657  ASSERT (offsetLeft + M_uFESpace->dof().numTotalDof() *nDimensions <=
658  UInt (matrix.matrixPtr()->NumGlobalCols() ),
659  "The matrix is too small (columns) for the assembly of the divergence");
660  ASSERT (offsetUp + M_pFESpace->dof().numTotalDof() <=
661  UInt ( matrix.matrixPtr()->NumGlobalRows() ),
662  " The matrix is too small (rows) for the assembly of the divergence");
663 
664  // Some constants
665  const UInt nbElements (M_uFESpace->mesh()->numElements() );
666  const UInt fieldDim (M_uFESpace->fieldDim() );
667  const UInt nbUTotalDof (M_uFESpace->dof().numTotalDof() );
668 
669  // Loop over the elements
670  for (UInt iterElement (0); iterElement < nbElements; ++iterElement)
671  {
672  // Update the diffusion current FE
673  M_divergenceUCFE->update ( M_uFESpace->mesh()->element (iterElement), UPDATE_DPHI | UPDATE_WDET );
674  M_divergencePCFE->update ( M_uFESpace->mesh()->element (iterElement), UPDATE_WDET );
675 
676  // Clean the local matrix
677  M_localDivergence->zero();
678 
679  // local stiffness
680  AssemblyElemental::divergence (*M_localDivergence, *M_divergenceUCFE, *M_divergencePCFE, fieldDim, coefficient);
681 
682  // Assembly
683  for (UInt iFieldDim (0); iFieldDim < nDimensions; ++iFieldDim)
684  {
685  assembleMatrix ( matrix,
686  *M_localDivergence,
687  *M_divergencePCFE,
688  *M_divergenceUCFE,
689  M_pFESpace->dof(),
690  M_uFESpace->dof(),
691  0, iFieldDim,
692  offsetUp, iFieldDim * nbUTotalDof + offsetLeft);
693  }
694  }
695 }
696 
697 
698 template< typename meshType, typename matrixType, typename vectorType>
699 void
700 OseenAssembler<meshType, matrixType, vectorType>::
701 addConvection (matrixType& matrix, const Real& coefficient, const vectorType& beta, const UInt& offsetLeft, const UInt offsetUp)
702 {
703  // Beta has to be repeated
704  if (beta.mapType() == Unique)
705  {
706  addConvection (matrix, coefficient, vectorType (beta, Repeated), offsetLeft, offsetUp);
707  return;
708  }
709 
710  ASSERT (M_uFESpace != 0, "No velocity FE space for assembling the convection.");
711  ASSERT (M_betaFESpace != 0, "No convective FE space for assembling the convection.");
712  ASSERT (static_cast<Int> (offsetLeft + M_uFESpace->dof().numTotalDof() *nDimensions) <= matrix.matrixPtr()->NumGlobalCols(),
713  "The matrix is too small (columns) for the assembly of the convection");
714  ASSERT (static_cast<Int> (offsetUp + M_uFESpace->dof().numTotalDof() *nDimensions) <= matrix.matrixPtr()->NumGlobalRows(),
715  " The matrix is too small (rows) for the assembly of the convection");
716 
717  // Some constants
718  const UInt nbElements (M_uFESpace->mesh()->numElements() );
719  const UInt fieldDim (M_uFESpace->fieldDim() );
720  const UInt nbUTotalDof (M_uFESpace->dof().numTotalDof() );
721  const UInt nbQuadPt (M_convectionUCFE->nbQuadPt() );
722 
723  std::vector< std::vector< Real > > localBetaValue (nbQuadPt, std::vector<Real> (nDimensions, 0.0) );
724 
725  // Loop over the elements
726  for (UInt iterElement (0); iterElement < nbElements; ++iterElement)
727  {
728  // Update the diffusion current FE
729  M_convectionUCFE->update ( M_uFESpace->mesh()->element (iterElement), UPDATE_DPHI | UPDATE_WDET );
730 
731  // Clean the local matrix
732  M_localConvection->zero();
733 
734  // Interpolate
735  AssemblyElemental::interpolate (localBetaValue, *M_convectionBetaCFE, nDimensions, M_betaFESpace->dof(), iterElement, beta);
736 
737  // Local convection
738  AssemblyElemental::advection (*M_localConvection, *M_convectionUCFE, coefficient, localBetaValue, fieldDim);
739 
740  // Assembly
741  for (UInt iFieldDim (0); iFieldDim < nDimensions; ++iFieldDim)
742  {
743  assembleMatrix ( matrix,
744  *M_localConvection,
745  *M_convectionUCFE,
746  *M_convectionUCFE,
747  M_uFESpace->dof(),
748  M_uFESpace->dof(),
749  iFieldDim, iFieldDim,
750  iFieldDim * nbUTotalDof + offsetUp, iFieldDim * nbUTotalDof + offsetLeft);
751  }
752  }
753 }
754 
755 template< typename meshType, typename matrixType, typename vectorType>
756 void
757 OseenAssembler<meshType, matrixType, vectorType>::
758 addNewtonConvection ( matrixType& matrix, const vectorType& beta, const UInt& offsetLeft, const UInt offsetUp )
759 {
760  // Beta has to be repeated
761  if ( beta.mapType() == Unique )
762  {
763  addNewtonConvection ( matrix, vectorType ( beta, Repeated ), offsetLeft, offsetUp );
764  return;
765  }
766 
767  ASSERT ( M_uFESpace != 0, "No velocity FE space for assembling the convection." );
768  ASSERT ( M_betaFESpace != 0, "No convective FE space for assembling the convection." );
769  ASSERT ( offsetLeft + M_uFESpace->dof().numTotalDof() *nDimensions <= matrix.matrixPtr()->NumGlobalCols(),
770  "The matrix is too small (columns) for the assembly of the convection" );
771  ASSERT ( offsetUp + M_uFESpace->dof().numTotalDof() *nDimensions <= matrix.matrixPtr()->NumGlobalRows(),
772  " The matrix is too small (rows) for the assembly of the convection" );
773 
774  // Some constants
775  const UInt nbElements ( M_uFESpace->mesh()->numElements() );
776  const UInt fieldDim ( M_uFESpace->fieldDim() );
777  const UInt nbUTotalDof ( M_uFESpace->dof().numTotalDof() );
778 
779  // Loop over the elements
780  for ( UInt iterElement ( 0 ); iterElement < nbElements; ++iterElement )
781  {
782  // Update the diffusion current FE
783  M_convectionUCFE->update ( M_uFESpace->mesh()->element ( iterElement ), UPDATE_DPHI | UPDATE_WDET );
784 
785  // Clean the local matrix
786  M_localConvection->zero();
787 
788  localVector_Type betaLocal ( M_uFESpace->fe().nbFEDof(), M_uFESpace->fieldDim() );
789 
790  // Create local vector
791  for ( UInt iNode = 0 ; iNode < M_uFESpace->fe().nbFEDof() ; iNode++ )
792  {
793  UInt iLocal = M_uFESpace->fe().patternFirst ( iNode ); // iLocal = iNode
794 
795  for ( Int iComponent = 0; iComponent < fieldDim; ++iComponent )
796  {
797  UInt iGlobal = M_uFESpace->dof().localToGlobalMap ( iterElement, iLocal ) + iComponent * nbUTotalDof;
798 
799  // un local
800  betaLocal.vec() [ iLocal + iComponent * M_uFESpace->fe().nbFEDof() ] = beta ( iGlobal );
801  }
802  }
803 
804  // Assembly
805  for ( UInt iFieldDim ( 0 ); iFieldDim < nDimensions; ++iFieldDim )
806  {
807  for ( UInt jFieldDim ( 0 ); jFieldDim < nDimensions; ++jFieldDim )
808  {
809  AssemblyElemental::advectionNewton ( 1.0, betaLocal, *M_localConvection,
810  *M_convectionUCFE, iFieldDim, jFieldDim );
811  assembleMatrix ( matrix,
812  *M_localConvection,
813  *M_convectionUCFE,
814  *M_convectionUCFE,
815  M_uFESpace->dof(),
816  M_uFESpace->dof(),
817  iFieldDim, jFieldDim,
818  iFieldDim * nbUTotalDof + offsetUp, jFieldDim * nbUTotalDof + offsetLeft );
819  }
820  }
821  }
822 }
823 
824 template< typename meshType, typename matrixType, typename vectorType>
825 void
826 OseenAssembler<meshType, matrixType, vectorType>::
827 addSymmetricConvection (matrixType& matrix, const Real& coefficient, const vectorType& beta, const UInt& offsetLeft, const UInt offsetUp)
828 
829 {
830  // Beta has to be repeated
831  if (beta.mapType() == Unique)
832  {
833  addSymmetricConvection (matrix, coefficient, vectorType (beta, Repeated), offsetLeft, offsetUp);
834  return;
835  }
836 
837  ASSERT (M_uFESpace != 0, "No velocity FE space for assembling the convection.");
838  ASSERT (M_betaFESpace != 0, "No convective FE space for assembling the convection.");
839  ASSERT ( (int) offsetLeft + (int) M_uFESpace->dof().numTotalDof() *nDimensions <= matrix.matrixPtr()->NumGlobalCols(),
840  "The matrix is too small (columns) for the assembly of the convection");
841  ASSERT ( (int) offsetUp + (int) M_uFESpace->dof().numTotalDof() *nDimensions <= matrix.matrixPtr()->NumGlobalRows(),
842  " The matrix is too small (rows) for the assembly of the convection");
843 
844  // Some constants
845  const UInt nbElements (M_uFESpace->mesh()->numElements() );
846  const UInt fieldDim (M_uFESpace->fieldDim() );
847  const UInt nbUTotalDof (M_uFESpace->dof().numTotalDof() );
848  const UInt nbQuadPt (M_convectionUCFE->nbQuadPt() );
849 
850  std::vector< std::vector< Real > > localBetaValue (nbQuadPt, std::vector<Real> (nDimensions, 0.0) );
851  std::vector< std::vector< std::vector< Real > > >
852  localBetaGradient (nbQuadPt, std::vector<std::vector<Real> > (nDimensions, std::vector<Real> (nDimensions, 0.0) ) );
853 
854  // Loop over the elements
855  for (UInt iterElement (0); iterElement < nbElements; ++iterElement)
856  {
857  // Update the diffusion current FE
858  M_convectionUCFE->update ( M_uFESpace->mesh()->element (iterElement), UPDATE_DPHI | UPDATE_WDET );
859  M_convectionBetaCFE->update ( M_uFESpace->mesh()->element (iterElement), UPDATE_DPHI );
860 
861  // Clean the local matrix
862  M_localConvection->zero();
863 
864  // Interpolate
865  AssemblyElemental::interpolate (localBetaValue, *M_convectionBetaCFE, nDimensions, M_betaFESpace->dof(), iterElement, beta);
866  // Interpolate
867  AssemblyElemental::interpolateGradient (localBetaGradient, *M_convectionBetaCFE, nDimensions, M_betaFESpace->dof(), iterElement, beta);
868 
869  // Local convection
870  // AssemblyElemental::advection(*M_localConvection,*M_convectionUCFE,localBetaValue,fieldDim);
871 
872  // Local convection, 1/2 \beta \grad u v + 1/2 u\grad \beta v
873  AssemblyElemental::symmetrizedAdvection (*M_localConvection, *M_convectionUCFE, coefficient, localBetaGradient, fieldDim);
874 
875  // Assembly
876  for (UInt iFieldDim (0); iFieldDim < nDimensions; ++iFieldDim)
877  {
878  // Assembly
879  for (UInt jFieldDim (0); jFieldDim < nDimensions; ++jFieldDim)
880  {
881  assembleMatrix ( matrix,
882  *M_localConvection,
883  *M_convectionUCFE,
884  *M_convectionUCFE,
885  M_uFESpace->dof(),
886  M_uFESpace->dof(),
887  iFieldDim, jFieldDim,
888  iFieldDim * nbUTotalDof + offsetUp, jFieldDim * nbUTotalDof + offsetLeft);
889  }
890  }
891  }
892 }
893 
894 template< typename meshType, typename matrixType, typename vectorType>
895 void
896 OseenAssembler<meshType, matrixType, vectorType>::
897 addConvectionRhs (vectorType& rhs, const Real& coefficient, const vectorType& velocity)
898 {
899  // velocity has to be repeated!
900  if (velocity.mapType() == Unique)
901  {
902  addConvectionRhs (rhs, coefficient, vectorType (velocity, Repeated) );
903  return;
904  }
905 
906  // Check that the FESpace is set
907  ASSERT (M_betaFESpace != 0, "No convective FE space for assembling the convection.");
908 
909  // Some constants
910  const UInt nbElements (M_betaFESpace->mesh()->numElements() );
911  const UInt fieldDim (M_betaFESpace->fieldDim() );
912  const UInt dim (M_betaFESpace->dim() );
913  const UInt nbFEDof (M_convectionRhsUCFE->nbFEDof() );
914 
915  // Temporaries
916  VectorElemental localVelocity (M_betaFESpace->fe().nbFEDof(), fieldDim);
917 
918  // Loop over the elements
919  for (UInt iterElement (0); iterElement < nbElements; ++iterElement)
920  {
921  // Update the diffusion current FE
922  M_convectionRhsUCFE->update ( M_betaFESpace->mesh()->element (iterElement), UPDATE_DPHI | UPDATE_WDET );
923 
924  // Clean the local vector
925  M_localConvectionRhs->zero();
926  localVelocity.zero();
927 
928  for ( UInt iNode = 0 ; iNode < nbFEDof ; iNode++ )
929  {
930  UInt iLocal = M_betaFESpace->fe().patternFirst ( iNode ); // iLocal = iNode
931 
932  for ( UInt iComponent = 0; iComponent < fieldDim; ++iComponent )
933  {
934  UInt iGlobal = M_betaFESpace->dof().localToGlobalMap ( iterElement, iLocal ) + iComponent * dim;
935 
936  localVelocity.vec( ) [ iLocal + iComponent * nbFEDof ] = velocity ( iGlobal );
937  }
938  }
939 
940  AssemblyElemental::source_advection (coefficient, localVelocity, localVelocity, *M_localConvectionRhs, *M_convectionRhsUCFE);
941 
942  // Here add in the global rhs
943  for (UInt iterFDim (0); iterFDim < fieldDim; ++iterFDim)
944  {
945  assembleVector ( rhs,
946  iterElement,
947  *M_localConvectionRhs,
948  nbFEDof,
949  M_betaFESpace->dof(),
950  iterFDim,
951  iterFDim * M_betaFESpace->dof().numTotalDof() );
952  }
953  }
954 }
955 
956 template< typename meshType, typename matrixType, typename vectorType>
957 void
958 OseenAssembler<meshType, matrixType, vectorType>::
959 addMass (matrixType& matrix, const Real& coefficient, const UInt& offsetLeft, const UInt offsetUp)
960 {
961 
962  ASSERT (M_uFESpace != 0, "No velocity FE space for assembling the mass.");
963  ASSERT (static_cast<Int> (offsetLeft + M_uFESpace->dof().numTotalDof() *nDimensions) <= matrix.matrixPtr()->NumGlobalCols(),
964  "The matrix is too small (columns) for the assembly of the mass");
965  ASSERT (static_cast<Int> (offsetUp + M_uFESpace->dof().numTotalDof() *nDimensions) <= matrix.matrixPtr()->NumGlobalRows(),
966  " The matrix is too small (rows) for the assembly of the mass");
967 
968  // Some constants
969  const UInt nbElements (M_uFESpace->mesh()->numElements() );
970  const UInt fieldDim (M_uFESpace->fieldDim() );
971  const UInt nbUTotalDof (M_uFESpace->dof().numTotalDof() );
972 
973  // Loop over the elements
974  for (UInt iterElement (0); iterElement < nbElements; ++iterElement)
975  {
976  // Update the diffusion current FE
977  M_massCFE->update ( M_uFESpace->mesh()->element (iterElement), UPDATE_WDET );
978 
979  // Clean the local matrix
980  M_localMass->zero();
981 
982  // local stiffness
983  AssemblyElemental::mass (*M_localMass, *M_massCFE, coefficient, fieldDim);
984 
985  // Assembly
986  for (UInt iFieldDim (0); iFieldDim < nDimensions; ++iFieldDim)
987  {
988  assembleMatrix ( matrix,
989  *M_localMass,
990  *M_massCFE,
991  *M_massCFE,
992  M_uFESpace->dof(),
993  M_uFESpace->dof(),
994  iFieldDim, iFieldDim,
995  iFieldDim * nbUTotalDof + offsetUp, iFieldDim * nbUTotalDof + offsetLeft);
996  }
997  }
998 }
999 
1000 template< typename meshType, typename matrixType, typename vectorType>
1001 void
1002 OseenAssembler<meshType, matrixType, vectorType>::
1003 addPressureMass (matrixType& matrix, const Real& coefficient, const UInt& offsetLeft, const UInt offsetUp)
1004 {
1005 
1006  ASSERT (M_pFESpace != 0, "No pressure FE space for assembling the mass.");
1007  ASSERT ( (int) offsetLeft + (int) M_pFESpace->dof().numTotalDof() <= matrix.matrixPtr()->NumGlobalCols(),
1008  "The matrix is too small (columns) for the assembly of the mass");
1009  ASSERT ( (int) offsetUp + (int) M_pFESpace->dof().numTotalDof() <= matrix.matrixPtr()->NumGlobalRows(),
1010  " The matrix is too small (rows) for the assembly of the mass");
1011 
1012  // Some constants
1013  const UInt nbElements (M_pFESpace->mesh()->numElements() );
1014  const UInt fieldDim (M_pFESpace->fieldDim() );
1015 
1016 
1017  // Loop over the elements
1018  for (UInt iterElement (0); iterElement < nbElements; ++iterElement)
1019  {
1020  // Update the diffusion current FE
1021  M_massPressureCFE->update ( M_pFESpace->mesh()->element (iterElement), UPDATE_WDET );
1022 
1023  // Clean the local matrix
1024  M_localMassPressure->zero();
1025 
1026  // local stiffness
1027  AssemblyElemental::mass (*M_localMassPressure, *M_massPressureCFE, coefficient, fieldDim);
1028 
1029  // Assembly
1030  for (UInt iFieldDim (0); iFieldDim < fieldDim; ++iFieldDim)
1031  {
1032  assembleMatrix ( matrix,
1033  *M_localMassPressure,
1034  *M_massPressureCFE,
1035  *M_massPressureCFE,
1036  M_pFESpace->dof(),
1037  M_pFESpace->dof(),
1038  iFieldDim, iFieldDim,
1039  offsetUp, offsetLeft);
1040  }
1041  }
1042 }
1043 
1044 template< typename meshType, typename matrixType, typename vectorType>
1045 void
1046 OseenAssembler<meshType, matrixType, vectorType>::
1047 addMassDivW (matrixType& matrix, const Real& coefficient, const vectorType& beta, const UInt& offsetLeft, const UInt offsetUp)
1048 {
1049  // Beta has to be repeated
1050  if (beta.mapType() == Unique)
1051  {
1052  addMassDivW (matrix, coefficient, vectorType (beta, Repeated), offsetLeft, offsetUp);
1053  return;
1054  }
1055 
1056  ASSERT (M_uFESpace != 0, "No velocity FE space for assembling the mass.");
1057  ASSERT (M_betaFESpace != 0, "No convective FE space for assembling the divergence.");
1058  ASSERT ( (int) offsetLeft + (int) M_uFESpace->dof().numTotalDof() *nDimensions <= matrix.matrixPtr()->NumGlobalCols(),
1059  "The matrix is too small (columns) for the assembly of the mass");
1060  ASSERT ( (int) offsetUp + (int) M_uFESpace->dof().numTotalDof() *nDimensions <= matrix.matrixPtr()->NumGlobalRows(),
1061  " The matrix is too small (rows) for the assembly of the mass");
1062 
1063  // Some constants
1064  const UInt nbElements (M_uFESpace->mesh()->numElements() );
1065  const UInt fieldDim (M_uFESpace->fieldDim() );
1066  const UInt nbUTotalDof (M_uFESpace->dof().numTotalDof() );
1067  const UInt nbQuadPt (M_convectionUCFE->nbQuadPt() );
1068 
1069  std::vector< Real > localBetaDivergence (nbQuadPt);
1070 
1071  // Loop over the elements
1072  for (UInt iterElement (0); iterElement < nbElements; ++iterElement)
1073  {
1074  // Update the diffusion current FE
1075  M_convectionUCFE->update ( M_uFESpace->mesh()->element (iterElement), UPDATE_WDET );
1076  M_convectionBetaCFE->update ( M_uFESpace->mesh()->element (iterElement), UPDATE_DPHI | UPDATE_WDET );
1077 
1078  // Clean the local matrix
1079  M_localMass->zero();
1080 
1081  // Interpolate
1082  AssemblyElemental::interpolateDivergence (localBetaDivergence, *M_convectionBetaCFE, M_betaFESpace->dof(), iterElement, beta);
1083 
1084  // local mass, with coefficients
1085  AssemblyElemental::massDivW (*M_localMass, *M_convectionUCFE, coefficient, localBetaDivergence, fieldDim);
1086 
1087  // Assembly
1088  for (UInt iFieldDim (0); iFieldDim < nDimensions; ++iFieldDim)
1089  {
1090  assembleMatrix ( matrix,
1091  *M_localMass,
1092  *M_convectionUCFE,
1093  *M_convectionUCFE,
1094  M_uFESpace->dof(),
1095  M_uFESpace->dof(),
1096  iFieldDim, iFieldDim,
1097  iFieldDim * nbUTotalDof + offsetUp, iFieldDim * nbUTotalDof + offsetLeft);
1098  }
1099  }
1100 }
1101 
1102 template< typename meshType, typename matrixType, typename vectorType>
1103 void
1104 OseenAssembler<meshType, matrixType, vectorType>::
1105 addMassRhs (vectorType& rhs, const function_Type& fun, const Real& t)
1106 {
1107  // Check that the fespace is set
1108  ASSERT (M_uFESpace != 0, "No FE space for assembling the right hand side (mass)!");
1109 
1110  // Some constants
1111  const UInt nbElements (M_uFESpace->mesh()->numElements() );
1112  const UInt fieldDim (M_uFESpace->fieldDim() );
1113  const UInt nbFEDof (M_massRhsCFE->nbFEDof() );
1114 
1115  // Loop over the elements
1116  for (UInt iterElement (0); iterElement < nbElements; ++iterElement)
1117  {
1118  // Update the diffusion current FE
1119  M_massRhsCFE->update ( M_uFESpace->mesh()->element (iterElement), UPDATE_QUAD_NODES | UPDATE_WDET );
1120 
1121  // Clean the local matrix
1122  M_localMassRhs->zero();
1123 
1124  AssemblyElemental::bodyForces ( *M_localMassRhs,
1125  *M_massRhsCFE,
1126  fun, t,
1127  fieldDim);
1128 
1129  // Here add in the global rhs
1130  for (UInt iterFDim (0); iterFDim < fieldDim; ++iterFDim)
1131  {
1132  assembleVector ( rhs,
1133  iterElement,
1134  *M_localMassRhs,
1135  nbFEDof,
1136  M_uFESpace->dof(),
1137  iterFDim,
1138  iterFDim * M_uFESpace->dof().numTotalDof() );
1139  }
1140  }
1141 
1142 }
1143 
1144 template< typename meshType, typename matrixType, typename vectorType>
1145 void
1146 OseenAssembler<meshType, matrixType, vectorType>::
1147 addFluxTerms ( vectorType& vector,
1148  BCHandler const& bcHandler)
1149 {
1150 
1151  for ( ID hCounter = 0; hCounter < bcHandler.size(); ++hCounter )
1152  {
1153  ASSERT ( bcHandler[ hCounter ].type() == Flux, "Works only with Flux BC type!");
1154  ASSERT ( bcHandler.bcUpdateDone () , " Please call bcHandler::Update() before calling this method!");
1155 
1156  const BCBase& boundaryCond (bcHandler[ hCounter ]);
1157 
1158  // Number of local DOF in this facet
1159  UInt nDofF = M_uFESpace->feBd().nbFEDof();
1160 
1161  // Number of total scalar Dof
1162  UInt totalDof = M_uFESpace->dof().numTotalDof();
1163 
1164  // Number of components involved in this boundary condition
1165  UInt nComp = boundaryCond.numberOfComponents();
1166 
1167  Real sum;
1168 
1169  const BCIdentifierNatural* pId;
1170  ID ibF, idDof;
1171 
1172  if ( !boundaryCond.isDataAVector() )
1173  {
1174  for ( ID i = 0; i < boundaryCond.list_size(); ++i )
1175  {
1176  pId = static_cast< const BCIdentifierNatural* > ( boundaryCond[ i ] );
1177 
1178  // Number of the current boundary facet
1179  ibF = pId->id();
1180  // Updating facet stuff
1181  M_uFESpace->feBd().update ( M_uFESpace->mesh()->boundaryFacet ( ibF ), UPDATE_W_ROOT_DET_METRIC | UPDATE_NORMALS | UPDATE_QUAD_NODES );
1182 
1183  for ( ID idofF = 0; idofF < nDofF; ++idofF )
1184  {
1185  for ( int ic = 0; ic < (int) nComp; ++ic)
1186  {
1187  idDof = pId->boundaryLocalToGlobalMap ( idofF ) + ic * totalDof;
1188 
1189  sum = 0.;
1190  for ( int iq = 0; iq < (int) M_uFESpace->feBd().nbQuadPt(); ++iq )
1191  {
1192  sum += M_uFESpace->feBd().phi ( int ( idofF ), iq ) *
1193  M_uFESpace->feBd().normal (ic , iq) *
1194  M_uFESpace->feBd().wRootDetMetric (iq);
1195  }
1196 
1197  vector.sumIntoGlobalValues (idDof, sum);
1198  }
1199  }
1200  }
1201  }
1202 
1203  }
1204  vector.globalAssemble();
1205 }
1206 
1207 
1208 
1209 
1210 
1211 } // Namespace LifeV
1212 
1213 #endif /* OSEENASSEMBLER_H */
VectorElemental localVector_Type
const BCBase & operator[](const ID &) const
Extract a BC in the list, const.
Definition: BCHandler.cpp:98
std::unique_ptr< currentFE_Type > currentFEPtr_Type
void addConvectionRhs(vectorType &rhs, const Real &coefficient, const vectorType &velocity)
Add an explicit convection term to the right hand side.
fespacePtr_Type M_uFESpace
void setup(const fespacePtr_Type &uFESpace, const fespacePtr_Type &pFESpace)
Setup method for the FESpaces.
localMatrixPtr_Type M_localMass
void addConvection(matrixType &matrix, const Real &coefficient, const vectorType &beta, const UInt &offsetLeft, const UInt offsetUp)
Add the convective term with the given offsets.
std::unique_ptr< localVector_Type > localVectorPtr_Type
void addSymmetricConvection(matrixType &matrix, const Real &coefficient, const vectorType &beta, const UInt &offsetLeft, const UInt offsetUp)
Add the symmetric convective term with the given offset.
OseenAssembler(const OseenAssembler &)
void addPressureMass(matrixType &matrix, const Real &coefficient, const UInt &offsetLeft, const UInt offsetUp)
Add the mass using offsets.
void setQuadRuleForMassRhs(const QuadratureRule &qr)
Setter for the quadrature used for the right hand side.
std::shared_ptr< fespace_Type > fespacePtr_Type
BCHandler - class for handling boundary conditions.
Definition: BCHandler.hpp:100
currentFEPtr_Type M_massPressureCFE
void addGradientTranspose(matrixType &matrix, const Real &coefficient=1.0)
Add the term corresponding to the divergence free constraint.
void addGradientTranspose(matrixType &matrix, const UInt &offsetLeft, const UInt &offsetUp, const Real &coefficient=1.0)
Add the divergence free constraint in a given position of the matrix using the grad calls...
currentFEPtr_Type M_convectionUCFE
currentFEPtr_Type M_viscousCFE
currentFEPtr_Type M_massRhsCFE
currentFEPtr_Type M_massCFE
bool isDataAVector() const
Returns True if a FE BCVector has been provided to the class, False otherwise.
Definition: BCBase.cpp:774
localMatrixPtr_Type M_localGradPressure
void addViscousStress(matrixType &matrix, const Real &viscosity)
Add the viscous stress in the standard block.
OseenAssembler()
Empty Constructor.
localMatrixPtr_Type M_localDivergence
MatrixElemental localMatrix_Type
UInt numberOfComponents() const
Returns the number of components involved in this boundary condition.
Definition: BCBase.cpp:727
Epetra_Import const & importer()
Getter for the Epetra_Import.
Definition: MapEpetra.cpp:394
void addDivergence(matrixType &matrix, const UInt &offsetLeft, const UInt &offsetUp, const Real &coefficient=1.0)
Add the divergence free constraint in a given position of the matrix.
void addMassDivW(matrixType &matrix, const Real &coefficient, const vectorType &beta, const UInt &offsetLeft, const UInt offsetUp)
Add a consistent stabilizing term with the given offsets.
#define ASSERT(X, A)
Definition: LifeAssert.hpp:90
uint32_type ID
IDs.
Definition: LifeV.hpp:194
fespacePtr_Type M_betaFESpace
void addDivergence(matrixType &matrix, const Real &coefficient=1.0)
Add the term corresponding to the divergence free constraint.
localMatrixPtr_Type M_localConvection
localMatrixPtr_Type M_localMassPressure
void addFluxTerms(vectorType &vector, BCHandler const &bcHandler)
currentFEPtr_Type M_convectionBetaCFE
void addStiffStrain(matrixType &matrix, const Real &viscosity)
Add the stiff strain in the standard block.
ID boundaryLocalToGlobalMap(const ID &i) const
Return the global DOF corresponding tho the i-th local DOF in the face.
void addNewtonConvection(matrixType &matrix, const vectorType &beta, const UInt &offsetLeft, const UInt offsetUp)
Add the convective term necessary to build the Newton method.
currentFEPtr_Type M_gradPressureUCFE
currentFEPtr_Type M_gradPressurePCFE
void addMassDivW(matrixType &matrix, const Real &coefficient, const vectorType &beta)
Add a consistent stabilizing term.
std::shared_ptr< matrixType > matrixPtr_Type
double Real
Generic real data.
Definition: LifeV.hpp:175
void addGradPressure(matrixType &matrix)
Add the term involved in the gradient of the pressure term.
OseenAssembler - Assembly class for the Oseen problem.
CurrentFE - A primordial class for the assembly of the local matrices/vectors retaining the values on...
Definition: CurrentFE.hpp:243
localMatrixPtr_Type M_localViscous
localVectorPtr_Type M_localMassRhs
currentFEPtr_Type M_divergenceUCFE
FESpace< meshType, map_Type > fespace_Type
void setup(const fespacePtr_Type &uFESpace, const fespacePtr_Type &pFESpace, const fespacePtr_Type &betaFESpace)
Setup method for the FESpace with a different space for the convective field.
const BCIdentifierBase * operator[](const ID &i) const
Returns a pointer to the (i)-th element of the list of identifiers.
Definition: BCBase.cpp:638
void addNewtonConvection(matrixType &matrix, const vectorType &beta)
Add the convective term necessary to build the Newton method.
const UInt nDimensions(NDIM)
void addViscousStress(matrixType &matrix, const Real &viscosity, const UInt &offsetLeft, const UInt &offsetUp)
Add the viscous stress using the given offsets.
currentFEPtr_Type M_massBetaCFE
localVectorPtr_Type M_localConvectionRhs
void addMass(matrixType &matrix, const Real &coefficient)
Add the mass.
void addPressureMass(matrixType &matrix, const Real &coefficient)
Add the Pressure mass.
void addGradPressure(matrixType &matrix, const UInt &offsetLeft, const UInt &offsetUp)
Add the term involved in the gradient of the pressure term using the given offsets.
fespacePtr_Type M_pFESpace
BCIdentifierNatural - Idenifier for Natural and Robin Boundary Condiions.
void addSymmetricConvection(matrixType &matrix, const Real &coefficient, const vectorType &beta)
Add the convective term.
UInt size() const
Number of the stored boundary conditions.
Definition: BCHandler.hpp:482
QuadratureRule - The basis class for storing and accessing quadrature rules.
UInt list_size() const
Returns the size of the identifiers list.
Definition: BCBase.cpp:551
void addMass(matrixType &matrix, const Real &coefficient, const UInt &offsetLeft, const UInt offsetUp)
Add the mass using offsets.
currentFEPtr_Type M_convectionRhsUCFE
void addStiffStrain(matrixType &matrix, const Real &viscosity, const UInt &offsetLeft, const UInt &offsetUp)
Add the stiff strain using the given offsets.
std::vector< std::shared_ptr< BCIdentifierBase > > M_idVector
container for id&#39;s when the list is finalized
Definition: BCBase.hpp:647
std::unique_ptr< localMatrix_Type > localMatrixPtr_Type
currentFEPtr_Type M_divergencePCFE
virtual ~OseenAssembler()
Destructor.
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191
void addConvection(matrixType &matrix, const Real &coefficient, const vectorType &beta)
Add the convective term.
void addMassRhs(vectorType &rhs, const function_Type &fun, const Real &t)