LifeV
CurrentFE.hpp
Go to the documentation of this file.
1 //@HEADER
2 /*
3 *******************************************************************************
4 
5  Copyright (C) 2004, 2005, 2007 EPFL, Politecnico di Milano, INRIA
6  Copyright (C) 2010 EPFL, Politecnico di Milano, Emory University
7 
8  This file is part of LifeV.
9 
10  LifeV is free software; you can redistribute it and/or modify
11  it under the terms of the GNU Lesser General Public License as published by
12  the Free Software Foundation, either version 3 of the License, or
13  (at your option) any later version.
14 
15  LifeV is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public License
21  along with LifeV. If not, see <http://www.gnu.org/licenses/>.
22 
23 *******************************************************************************
24 */
25 //@HEADER
26 
27 /*!
28  @file
29  @brief File containing the CurrentFE class
30 
31  @author Jean-Frederic Gerbeau
32  @date 00-04-2002
33 
34  @contributor V. Martin
35  Samuel Quinodoz <samuel.quinodoz@epfl.ch>
36  @mantainer Samuel Quinodoz <samuel.quinodoz@epfl.ch>
37  */
38 
39 
40 #ifndef CURRENTFE_H
41 #define CURRENTFE_H 1
42 
43 
44 #include <lifev/core/LifeV.hpp>
45 
46 #include <lifev/core/fem/GeometricMap.hpp>
47 
48 #include <lifev/core/fem/ReferenceFEScalar.hpp>
49 #include <lifev/core/fem/ReferenceFEHdiv.hpp>
50 
51 #include <lifev/core/fem/QuadratureRule.hpp>
52 
53 #include <boost/multi_array.hpp>
54 
55 #include <iostream>
56 #include <fstream>
57 
58 namespace LifeV
59 {
60 
61 /*! \page update_procedure Update of the current finite element
62 
63  \section general_section General issues
64 
65  When the update method of the LifeV::CurrentFE class is called, several arrays of values are updated with respect to the current cell (and the current quadrature). However, in order to avoid redundant computations, intermediate values are also computed. The next figure shows all the possible values that can be updated.
66 
67  \image html update_complete_scheme.png "Complete tree of the values. The arrow between two values means that the first value require the second value to be already computed."
68 
69  However, one could want only a part of the values to be updated (we maybe do not want the second derivative for a simple elliptic problem). This is why a set of flag has been set up. With this flags, one selects the values that he needs (represented on the top of the last figure) and all the needed values are updated, without redundancy. For example, if one calles the update method with the flag UPDATE_DPHI, only the values visible on the next figure will be updated.
70 
71  \image html update_dphi_scheme.png "Values updated when only the derivatives of the basis functions are required."
72 
73 
74  Of course, it is possible to combine the different flags to update several values in the same time.
75 
76  \section flags_section Flags explaination
77 
78  In this section, we explain how flags work. This can be of interest if one wants to add a new flag.
79 
80  \subsection flag_sub1 What is a flag?
81 
82  At first sight, we might think that a flag is a complicated class implemented to do exaclty what we want, with overloaded operators... Actually, it is much simpler: a LifeV::flag_Type is just an unsigned integer.
83 
84  \subsection How to define a flag?
85 
86  The flags use the binary representation of the integers to work. This enables a very fast definition and use of the flags. To understand it, let us make a simple example. Suppose that we can update three quantities A,B and C.
87 
88  The first step is to define a "primitive" flag for each of these quantities. These flags are defined as powers of 2. Here, we will define
89 
90  \code
91  flag_Type UPDATE_A(1);
92  flag_Type UPDATE_B(2);
93  flag_Type UPDATE_C(4);
94  \endcode
95 
96  We need here powers of 2 because this makes the binary representation of the "primitive" flags simple: UPDATE_A is 001, UPDATE_B is 010 and UPDATE_C is 100 (if the integers are coded on 3 bits, otherwise there are many zeros before). The fact that we want A to be update is then represented by a 1 in the third position, for B it is the second position and for C the first position.
97 
98  So now, if we want to build a flag that updates A and C, we want it to be in binary 101, that is 5. So, the flag UPDATE_AC will be defined as:
99 
100  \code
101  flag_Type UPDATE_AC(5);
102  \endcode
103 
104  \subsection flag_sub2 How to combine flags?
105 
106  With the last example, one could think that is it just a matter of addition, but it is not. Suppose that we want to combine the flags UPDATE_A and UPDATE_AC. If we add the corresponding values, we will get 1+5=6 that is represented in binary by 110. This would mean update B and C, what is not what we want!
107 
108  To combine flags, we use the binary operator | that do exactly the job that we want: 1|5=5.
109 
110  \subsection flag_sub3 How to detect flags?
111 
112  Now that we can build every flag that we want, we want to detect quickly the different flags. This is achievied by using the binary operator & and the "primitive" flags.
113 
114  Suppose that we want to know if A has to be updated. Then, we perform that operation "& UPDATE_A" on the incoming flag. If the result is zero, then we do not need to update it: for example, UPDATE_B & UPDATE_A = 0 . Otherwise, we have to update it: for example, UPDATE_AC & UPDATE_A = 1.
115 
116 
117  \section list_section Possible flags
118 
119  There are several flags defined for you. Here is a list of the possible flags that are usually used:
120 
121  <table>
122  <tr>
123  <th> Flag name </th> <th> Effect </th>
124  </tr>
125  <tr>
126  <td> UPDATE_QUAD_NODES </td> <td> Update everything needed to know the position of the quadrature nodes in the current cell </td>
127  </tr>
128  <tr>
129  <td> UPDATE_DPHI </td> <td> Update everything needed to know the values of the derivatives of the basis functions in the quadrature nodes (in the current cell) </td>
130  </tr>
131  <tr>
132  <td> UPDATE_D2PHI </td> <td> Update everything needed to know the values of the second derivatives of the basis functions in the quadrature nodes (in the current cell) </td>
133  </tr>
134  <tr>
135  <td> UPDATE_WDET </td> <td> Update everything needed to know the determinant of the transformation multiplied by the weights of the quadrature. </td>
136  </tr>
137 
138  </table>
139 
140  Note: in the old versions there was also the flag UPDATE_PHI. This flag (together with UPDATE_ONLY_PHI) has been removed, since the values of the basis functions in the quadrature nodes are always the same, so they do not need to be updated.
141  Besides this usual flags, there are a couple of "primitive" flags, that update only a particular element in the currentFE structure. Be sure to know what you are doing before using them.
142 
143 */
144 
152 const flag_Type UPDATE_ONLY_DPHI (128);
153 const flag_Type UPDATE_ONLY_D2PHI_REF (256);
154 const flag_Type UPDATE_ONLY_D2PHI (512);
155 const flag_Type UPDATE_ONLY_PHI_VECT (1024);
158 
159 
162 
170 
178 
184 
190 
192 
193 
194 
195 //! CurrentFE - A primordial class for the assembly of the local matrices/vectors retaining the values on the real cells.
196 /*!
197  This class is an essential piece of any finite element solver implemented in LifeV, as it is used each time one wants to assemble the matrix or the right hand side associated to a given discrete problem (in variational form). The role of the class is, given a cell (or similar data), to compute the values of the basis function, their derivatives, the location of the quadrature nodes,...
198 
199  During the assembly procedure, the code of the solver will typically loops on the cells of a given mesh. Each time a cell is selected, a local matrix is built (using only the degrees of freedom of that cell). This local matrix represents a local contribution that is added in the global matrix (concerning all the degrees of freedom of the problem).
200 
201  <b>Example</b>: suppose that we are assembling the local matrix of a Laplacian problem. The local contributions are given by \f$ \int_{K} \nabla \phi_i \cdot \nabla \phi_j \f$ where \f$K\f$ is the considered cell. As we use numerical quadrature, to build the local matrix, we have to provide:
202 
203  <ol>
204  <li> The values of the <b>derivatives</b> of the basis functions in the quadrature nodes
205  <li> The <b>weights</b> associated to the quadrature and adapted to the considered cell
206  </ol>
207 
208  The CurrentFE has then to compute these values. To precise that we want to be able to access these values, we use flags. Here we need the two flags (see \ref update_procedure "this page" for more informations on the flags)
209 
210  <ol>
211  <li> For the derivative of the basis functions : UPDATE_DPHI
212  <li> For the modified weights : UPDATE_WDET
213  </ol>
214 
215  The code that we would typically use is:
216 
217  \code
218  my_currentFE.update(my_mesh.volumeList(i), UPDATE_DPHI | UPDATE_WDET);
219  \endcode
220 
221  This line of code asks the CurrentFE to compute the values specified with the flags and corresponding to the cell given by the i-th volume of the desired mesh. Now, these values are accessible using simple calls:
222 
223  \code
224  Real my_value = my_currentFE.dphi(0,0,1);
225  Real my_weight = my_currentFE.wDetJacobian(1);
226  \endcode
227 
228  These two lines just get some values already stored in the CurrentFE (so it is quite cheap!). Usually, one here uses the elementary operation already defined in the file lifefem/elemOper.hpp.
229 
230 
231  <b>Note</b>: One can change the quadrature of the CurrentFE at any moment, but this is a quite expensive operation and all updates previously done are lost. Use this feature only when it is really needed!
232 
233  @author Samuel Quinodoz <samuel.quinodoz@epfl.ch>
234  @date 13 Apr 2010
235  @version 2.0
236 
237  \todo Put all the remaining public member in private
238  \todo Put ifdef for the checks (definition of the booleans)
239  \todo Change the old update for wrappers to the new update
240  \todo CXXFLAG to disable the boost asserts: -DBOOST_DISABLE_ASSERTS?
241 
242 */
244 {
245 
246 public:
247 
248  //! @name Constructor & Destructor
249  //@{
250 
251  //! Full constructor with default quadrature
252  /*!
253  @param refFE Reference finite element used
254  @param geoMap Geometric mapping used
255  @param qr Quadrature rule for the computations
256  */
257  CurrentFE ( const ReferenceFE& refFE, const GeometricMap& geoMap, const QuadratureRule& qr );
258 
259  //! Constructor without quadrature specification
260  /*!
261  If you use this constructor, you have to use the method CurrentFE::setQuadRule before
262  using any update method!
263 
264  @param refFE Reference finite element used
265  @param geoMap Geometric mapping used
266  */
267  CurrentFE ( const ReferenceFE& refFE, const GeometricMap& geoMap);
268 
269  //! Destructor
270  virtual ~CurrentFE()
271  {
272  delete M_quadRule;
273  }
274 
275  //@}
276 
277 
278  //! @name Methods
279  //@{
280 
281  //! Update method using a given element.
282  /*!
283  This method is the most important one in this class. It allows the user to update different values on
284  the selected cell, like the values of the derivatives of the basis functions,...
285  @param geoele The cell that we are looking at
286  @param upFlag The flag to explain the quantities that we want to update
287  */
288  template<typename MeshElementMarkedType>
289  void update (const MeshElementMarkedType& geoele, flag_Type upFlag);
290 
291  //! Update method using only point coordinates. It used the flags, as defined in \ref update_procedure "this page".
292  virtual void update (const std::vector<std::vector<Real> >& pts, flag_Type upFlag);
293 
294  //! Update method using only point coordinates. It used the flags, as defined in \ref update_procedure "this page".
295  void update (const std::vector<GeoVector>& pts, flag_Type upFlag);
296 
297  //! Return the measure of the current element
298  virtual Real measure() const;
299 
300  //! return the barycenter of the element
301  void barycenter ( Real& x, Real& y, Real& z ) const;
302 
303  //! return the diameter of the element in the 1-norm
304  Real diameter() const;
305 
306  //! return the diameter of the element in the 2-norm
307  Real diameter2() const;
308 
309  /*!
310  compute the coordinate (x,y,z)= F(xi,eta,zeta), (F: geo mappping)
311  where (xi,eta,zeta) are the coor in the ref element
312  and (x,y,z) the coor in the current element
313  (if the code is compiled in 2D mode then z=0 and zeta is disgarded)
314  */
315  void coorMap ( Real& x, Real& y, Real& z, Real xi, Real eta, Real zeta ) const;
316 
317  /*!
318  return the coordinates in the current element of the point
319  P given in the reference frame.
320  */
321  GeoVector coorMap (const GeoVector& P) const;
322 
323  //! Export the quadrature rule on the current FE
324  /*!
325  This method can be used to position of the quadrature nodes in the
326  considered element using VTK format. The quadrature point must be updated.
327  It differs from the quadRule::VTKexport in the sens that here, the quadrature
328  is mapped on the current element, while it is still in the reference element
329  for quadRule::VTKexport.
330  */
331  void quadRuleVTKexport ( const std::string& filename) const;
332 
333  //@}
334 
335 
336  //! @name Set Methods
337  //@{
338 
339  //! Setter for the quadrature rule
340  /*! This method can be used to change the quadrature rule used. Notice that it is an
341  expensive method. Use it only when it is really needed.
342  @param newQuadRule The new quadrature rule
343  */
344  void setQuadRule (const QuadratureRule& newQuadRule);
345 
346  //@}
347 
348 
349  //! @name Get Methods
350  //@{
351 
352  //! Getter for the ID of the current cell
353  inline UInt currentId() const
354  {
355  return M_currentId;
356  }
357 
358  //! Getter for the local ID of the current cell
359  inline UInt currentLocalId() const
360  {
361  return M_currentLocalId;
362  }
363 
364  //! Getter for the number of quadrature nodes
365  inline UInt nbQuadPt() const
366  {
367  return M_nbQuadPt;
368  }
369 
370  //! Getter for the number of geometrical nodes
371  inline UInt nbGeoNode() const
372  {
373  return M_nbGeoNode;
374  }
375 
376  //! Getter for the number of nodes
377  inline UInt nbFEDof() const
378  {
379  return M_nbNode;
380  }
381 
382  //! Getter for the reference FE
383  inline const ReferenceFE& refFE() const
384  {
385  return *M_refFE;
386  };
387 
388  //! Getter for the GeometricMap reference
389  inline const GeometricMap& geoMap() const
390  {
391  return *M_geoMap;
392  }
393 
394  //! Getter for the quadrature rule
395  inline const QuadratureRule& quadRule() const
396  {
397  return *M_quadRule;
398  };
399 
400  //! Getter for the number of entries in the pattern
401  inline UInt nbPattern() const
402  {
403  return M_nbPattern;
404  };
405 
406  //! Getter for the diagonal entries in the pattern
407  inline UInt nbDiag() const
408  {
409  return M_nbDiag;
410  };
411 
412  //! Getter for the number of entries in the pattern
413  inline UInt nbUpper() const
414  {
415  return M_nbUpper;
416  };
417 
418  //! Old getter for the number of local coordinates
419  inline LIFEV_DEPRECATED ( UInt ) nbCoor() const
420  {
421  return M_nbLocalCoor;
422  };
423 
424  //! Getter for the number of local coordinates
425  UInt nbLocalCoor () const
426  {
427  return M_nbLocalCoor;
428  };
429 
430  //@}
431 
432 
433  //! @name Get Methods for the FE values
434  //@{
435 
436  //! Getter for the nodes of the cell
437  inline Real cellNode (UInt node, UInt coordinate) const
438  {
439  ASSERT (M_cellNodesUpdated, "Cell nodes are not updated!");
440  return M_cellNodes[node][coordinate];
441  };
442 
443  //! Getter for the quadrature nodes
444  inline Real quadNode (UInt node, UInt coordinate) const
445  {
446  ASSERT (M_quadNodesUpdated, "Quad nodes are not updated!");
447  return M_quadNodes[node][coordinate];
448  };
449 
450  //! Getter for the determinant of the jacobian in a given quadrature node
451  inline Real detJacobian (UInt quadNode) const
452  {
453  ASSERT (M_detJacobianUpdated, "Jacobian determinant is not updated!");
454  return M_detJacobian[quadNode];
455  };
456 
457  //! Getter for the weighted jacobian determinant
458  inline Real wDetJacobian (UInt quadNode) const
459  {
460  ASSERT (M_wDetJacobianUpdated, "Weighted jacobian determinant is not updated!");
461  return M_wDetJacobian[quadNode];
462  };
463 
464  //! Getter for the inverse of the jacobian
465  inline Real tInverseJacobian (UInt element1, UInt element2, UInt quadNode) const
466  {
467  ASSERT (M_tInverseJacobianUpdated, "Inverse jacobian is not updated!");
468  return M_tInverseJacobian[element1][element2][quadNode];
469  };
470 
471  //! Getter for basis function values (scalar FE case)
472  inline Real phi (UInt node, UInt quadNode) const
473  {
474  ASSERT (M_phiUpdated, "Function values are not updated!");
475  return M_phi[node][0][quadNode];
476  };
477 
478  //! Getter for basis function values (vectorial FE case)
479  inline Real phi (UInt node, UInt component, UInt quadNode) const
480  {
481  ASSERT (M_phiVectUpdated, "Function values are not updated!");
482  return M_phiVect[node][component][quadNode];
483  };
484 
485  //! Getter for the derivatives of the basis functions
486  inline Real dphi (UInt node, UInt derivative, UInt quadNode) const
487  {
488  ASSERT (M_dphiUpdated, "Basis derivatives are not updated!");
489  return M_dphi[node][derivative][quadNode];
490  };
491 
492  //! Getter for the second derivatives of the basis functions
493  inline Real d2phi (UInt node, UInt derivative1, UInt derivative2, UInt quadNode) const
494  {
495  ASSERT (M_d2phiUpdated, "Basis second derivatives are not updated!");
496  return M_d2phi[node][derivative1][derivative2][quadNode];
497  };
498 
499  //! Getter for the divergence of a vectorial FE in the reference frame.
500  inline Real divPhiRef (UInt node, UInt quadNode) const
501  {
502  ASSERT (M_divPhiRefUpdated, "Basis divergence are not updated!");
503  return M_divPhiRef[node][quadNode];
504  };
505  //@}
506 
507 
508 
509  //! @name Old methods (for backward compatibility, avoid using them)
510  //@{
511 
512  //! Old accessor, use cellNode instead.
513  inline Real point (UInt node, UInt coordinate) const
514  {
515  ASSERT (M_cellNodesUpdated, "Cell nodes are not updated!");
516  return M_cellNodes[node][coordinate];
517  };
518 
519  //! Old accessor, use quadNode instead
520  inline Real quadPt (UInt node, UInt coordinate) const
521  {
522  ASSERT (M_quadNodesUpdated, "Quad nodes are not updated!");
523  return M_quadNodes[node][coordinate];
524  };
525 
526  //! Old accessor, use wDetJacobian instead
527  inline Real weightDet (UInt quadNode) const
528  {
529  ASSERT (M_wDetJacobianUpdated, "Weighted jacobian determinant is not updated!");
530  return M_wDetJacobian[quadNode];
531  };
532 
533  //! Getter for the determinant of the jacobian in a given quadrature node
534  inline Real detJac (UInt quadNode) const
535  {
536  ASSERT (M_detJacobianUpdated, "Jacobian determinant is not updated!");
537  return M_detJacobian[quadNode];
538  };
539 
540  //! Old accessor, use iInverseJacobian instead
541  inline Real tInvJac (UInt element1, UInt element2, UInt quadNode) const
542  {
543  ASSERT (M_tInverseJacobianUpdated, "Inverse jacobian is not updated!");
544  return M_tInverseJacobian[element1][element2][quadNode];
545  };
546 
547  //! Old accessor, use dphi instead
548  inline Real phiDer (UInt node, UInt derivative, UInt quadNode) const
549  {
550  ASSERT (M_dphiUpdated, "Basis derivatives are not updated!");
551  return M_dphi[node][derivative][quadNode];
552  };
553 
554  //! Old accessor, use d2phi instead
555  inline Real phiDer2 (UInt node, UInt derivative1, UInt derivative2, UInt quadNode) const
556  {
557  ASSERT (M_d2phiUpdated, "Basis second derivatives are not updated!");
558  return M_d2phi[node][derivative1][derivative2][quadNode];
559  };
560 
561  //@}
562 
563 protected:
564  // Default constructor is NOT implemented
565  CurrentFE( );
566 
567  // Copy constructor possibly used only in derived classes
568  CurrentFE ( const CurrentFE& );
569 
570  //! Update the nodes of the cell to the current one.
571  template<typename MeshElementMarkedType>
572  void computeCellNodes (const MeshElementMarkedType& geoele);
573 
574  //! Update only the nodes of the cells to the current one.
575  void computeCellNodes (const std::vector<std::vector< Real> >& pts);
576 
577  //! Update the location of the quadrature in the current cell.
578  void computeQuadNodes();
579 
580  //! Compute the values of the derivatives of the mapping in the quadrature nodes
582 
583  //! Compute the jacobian in the quadrature nodes
584  void computeJacobian();
585 
586  //! Compute the transposed inverse of the jacobian in the quadrature nodes
588 
589  //! Compute the determinant of the jacobian
590  void computeDetJacobian();
591 
592  //! Compute the determinant of the jacobian in the quadrature nodes
593  void computeWDetJacobian();
594 
595  //! Compute the value of the derivatives in the reference frame
596  void computeDphiRef();
597 
598  //! Compute the value of the derivatives in the current element
599  void computeDphi();
600 
601  //! Compute the value of the second derivatives in the reference frame
602  void computeD2phiRef();
603 
604  //! Compute the value of the derivatives in the current element
605  void computeD2phi();
606 
607  //! Compute the value of the vectorial FE using Piola transform
608  void computePhiVect();
609 
610  // Constants
611  const UInt M_nbNode;
613  const UInt M_nbDiag;
616 
619 
622 
623  // Important structures
624 
628 
629 
630  // Internal storage for the data
631 
632  // Nodes of the current cell
635 
641 
646 
647  // M_phiRef is useless because M_phi is already the same.
651 
652  // Check
653 
656 
662 
667 
671 
672  // OLD FUNCTIONS
673 
674 public:
675 
676  //! @name Old methods (for backward compatibility, avoid using them)
677  //@{
678 
679  /*!
680  compute the coordinate (xi,eta,zeta)=inv(F)(x,y,z)
681  */
682  void coorBackMap (Real x, Real y, Real z,
683  Real& xi, Real& eta, Real& zeta) const;
684 
685  /*!
686  compute the jacobian at a given point : d x_compx / d zeta_compzeta
687  */
688  Real pointJacobian (Real hat_x, Real hat_y, Real hat_z,
689  int compx, int compzeta) const;
690 
691  /*!
692  compute the inverse jacobian
693  */
694 
695  Real pointInverseJacobian (Real hat_x, Real hat_y, Real hat_z,
696  int compx, int compzeta) const;
697 
698  /*!
699  compute the determinant of the Jacobian at a given point
700  */
701  Real pointDetJacobian (Real hat_x, Real hat_y, Real hat_z) const;
702 
703  /*! return (x,y,z) = the global coordinates of the quadrature point ig
704  in the current element. \warning this function is almost obsolete since if
705  you call the function updateFirstDerivQuadPt rather than updateFirstDeriv
706  (for example), the coordinates of the quadrature points have already
707  been computed and may be obtained via quadPt(ig,icoor). This is usually
708  much less expensive since it avoids many calls to coorQuadPt
709  */
710  inline void coorQuadPt (Real& x, Real& y, Real& z, int ig ) const
711  {
714  }
715  //! patternFirst(i): row index in the element matrix of the i-th term of the pattern
716  inline int patternFirst ( int i ) const
717  {
718  return M_refFE->patternFirst ( i );
719  }
720  //! patternSecond(i): column index in the element matrix of the i-th term of the pattern
721  inline int patternSecond ( int i ) const
722  {
723  return M_refFE->patternSecond ( i );
724  }
725 
726 
727  //---------------------------------------
728  //! DECLARATION of the update methods
729  //---------------------------------------
730  /*!
731  minimal update: we just identify the id of the current element
732  */
733  template <class MeshElementMarkedType>
734  void update ( const MeshElementMarkedType& geoele );
735  /*!
736  compute the arrays detJac, weightDet, jacobian on
737  the current element
738  */
739  template <class MeshElementMarkedType>
740  void updateJac ( const MeshElementMarkedType& geoele );
741  /*!
742  compute the arrays detJac, weightDet, jacobian and quadPt
743  on the current element
744  */
745  template <class MeshElementMarkedType>
746  void updateJacQuadPt ( const MeshElementMarkedType& geoele );
747  /*!
748  compute the arrays detJac, weightDet, jacobian,
749  tInvJac, phiDer on the current element
750  */
751  template <class MeshElementMarkedType>
752  void updateFirstDeriv ( const MeshElementMarkedType& geoele );
753  /*!
754  compute the arrays detJac, weightDet, jacobian,
755  tInvJac, phiDer and quadPt on the current element
756  */
757  template <class MeshElementMarkedType>
758  void updateFirstDerivQuadPt ( const MeshElementMarkedType& geoele );
759  /*!
760  compute the arrays detJac, weightDet, jacobian,
761  tInvJac, phiDer2 on the current element
762  */
763  template <class MeshElementMarkedType>
764  void updateSecondDeriv ( const MeshElementMarkedType& geoele );
765  /*!
766  compute the arrays detJac, weightDet, jacobian,
767  tInvJac, phiDer2 on the current element
768  */
769  template <class MeshElementMarkedType>
770  void updateSecondDerivQuadPt ( const MeshElementMarkedType& geoele );
771  /*!
772  compute the arrays detJac, weightDet, jacobian,
773  tInvJac, phiDer, phiDer2 on the current element
774  */
775  template <class MeshElementMarkedType>
776  void updateFirstSecondDeriv ( const MeshElementMarkedType& geoele );
777  /*!
778  compute the arrays detJac, weightDet, jacobian,
779  tInvJac, phiDer, phiDer2 on the current element
780  */
781  template <class MeshElementMarkedType>
782  void updateFirstSecondDerivQuadPt ( const MeshElementMarkedType& geoele );
783 
784  //@}
785 
786 };
787 
788 // ==================================================== IMPLEMENTATION ====================================================== //
789 
790 template<typename MeshElementMarked>
791 void CurrentFE::update (const MeshElementMarked& geoele, flag_Type upFlag)
792 {
793  M_currentId = geoele.id();
794  M_currentLocalId = geoele.localId();
795 
796  std::vector< std::vector <Real> > pts (M_nbGeoNode, std::vector<Real> (nDimensions) );
797 
798  for ( UInt i (0); i < M_nbGeoNode; ++i )
799  {
800  for ( UInt icoor (0); icoor < nDimensions; ++icoor)
801  {
802  pts[i][icoor] = geoele.point (i).coordinate (icoor);
803  }
804  }
805  update (pts, upFlag);
806 }
807 
808 template<typename MeshElementMarked>
809 void CurrentFE::computeCellNodes (const MeshElementMarked& geoele)
810 {
811  std::vector< std::vector <Real> > pts (M_nbGeoNode, std::vector<Real> (nDimensions) );
812 
813  for ( UInt i (0); i < M_nbGeoNode; ++i )
814  {
815  for ( UInt icoor (0); icoor < nDimensions; ++icoor)
816  {
817  pts[i][icoor] = geoele.point (i).coordinate (icoor);
818  }
819 
820  }
821  computeCellNodes (pts);
822 }
823 
824 //---------------------------------------
825 //! IMPLEMENTATION of the CurrentFE::update methods
826 //---------------------------------------
827 
828 /*!
829  minimal update: we just identify the id of the current element
830  */
831 template <class MeshElementMarkedType>
832 void CurrentFE::update ( const MeshElementMarkedType& geoele )
833 {
834  M_currentId = geoele.id();
835  M_currentLocalId = geoele.localId();
836 }
837 
838 /*!
839  compute the arrays detJac, weightDet, jacobian on
840  the current element
841 */
842 template <class MeshElementMarkedType>
843 void CurrentFE::updateJac ( const MeshElementMarkedType& geoele )
844 {
845  ASSERT (M_nbQuadPt != 0, " No quadrature rule defined, cannot update!");
846  M_currentId = geoele.id();
847  M_currentLocalId = geoele.localId();
848  //! compute the jacobian and its determinant...
849  computeCellNodes (geoele);
854 }
855 
856 /*!
857  compute the arrays detJac, weightDet, jacobian and quadPt
858  on the current element
859 */
860 template <class MeshElementMarkedType>
861 void CurrentFE::updateJacQuadPt ( const MeshElementMarkedType& geoele )
862 {
863  ASSERT (M_nbQuadPt != 0, " No quadrature rule defined, cannot update!");
864  M_currentId = geoele.id();
865  M_currentLocalId = geoele.localId();
866  // compute the jacobian and its determinant...
867  computeCellNodes (geoele);
872  // and the coordinates of the quadrature points
874 }
875 
876 /*!
877  compute the arrays detJac, weightDet, jacobian,
878  tInvJac, phiDer on the current element
879 */
880 template <class MeshElementMarkedType>
881 void CurrentFE::updateFirstDeriv ( const MeshElementMarkedType& geoele )
882 {
883  ASSERT (M_nbQuadPt != 0, " No quadrature rule defined, cannot update!");
884  M_currentId = geoele.id();
885  M_currentLocalId = geoele.localId();
886  //! compute the inverse jacobian...
887  computeCellNodes (geoele);
893  //! product InvJac by dPhiRef to compute phiDer
896 }
897 
898 /*!
899  compute the arrays detJac, weightDet, jacobian,
900  tInvJac, phiDer and quadPt on the current element
901 */
902 template <class MeshElementMarkedType>
903 void CurrentFE::updateFirstDerivQuadPt ( const MeshElementMarkedType& geoele )
904 {
905  ASSERT (M_nbQuadPt != 0, " No quadrature rule defined, cannot update!");
906  M_currentId = geoele.id();
907  M_currentLocalId = geoele.localId();
908  //! compute the inverse jacobian...
909  computeCellNodes (geoele);
915  //! product InvJac by dPhiRef to compute phiDer
918  //! and the coordinates of the quadrature points
920 }
921 
922 // A. Veneziani, October 30, 2002
923 /*!
924  compute the arrays detJac, weightDet, jacobian,
925  tInvJac, phiDer2 on the current element
926 */
927 template <class MeshElementMarkedType>
928 void CurrentFE::updateSecondDeriv ( const MeshElementMarkedType& geoele )
929 {
930  ASSERT (M_nbQuadPt != 0, " No quadrature rule defined, cannot update!");
931  M_currentId = geoele.id();
932  M_currentLocalId = geoele.localId();
933  //! compute the inverse jacobian...
934  computeCellNodes (geoele);
940  //! compute the second derivative
943 }
944 
945 /*!
946  compute the arrays detJac, weightDet, jacobian,
947  tInvJac, phiDer2 on the current element
948  */
949 template <class MeshElementMarkedType>
950 void CurrentFE::updateSecondDerivQuadPt ( const MeshElementMarkedType& geoele )
951 {
952  ASSERT (M_nbQuadPt != 0, " No quadrature rule defined, cannot update!");
953  M_currentId = geoele.id();
954  M_currentLocalId = geoele.localId();
955  //! compute the inverse jacobian...
956  computeCellNodes (geoele);
962  //! compute the second derivative
965  //! and the coordinates of the quadrature points
967 }
968 /*!
969  compute the arrays detJac, weightDet, jacobian,
970  tInvJac, phiDer, phiDer2 on the current element
971  */
972 template <class MeshElementMarkedType>
973 void CurrentFE::updateFirstSecondDeriv ( const MeshElementMarkedType& geoele )
974 {
975  ASSERT (M_nbQuadPt != 0, " No quadrature rule defined, cannot update!");
976  M_currentId = geoele.id();
977  M_currentLocalId = geoele.localId();
978  //! compute the inverse jacobian...
979  computeCellNodes (geoele);
985  //! compute phiDer and phiDer2
990 }
991 /*!
992  compute the arrays detJac, weightDet, jacobian,
993  tInvJac, phiDer, phiDer2 on the current element
994  */
995 template <class MeshElementMarkedType>
996 void CurrentFE::updateFirstSecondDerivQuadPt ( const MeshElementMarkedType& geoele )
997 {
998  ASSERT (M_nbQuadPt != 0, " No quadrature rule defined, cannot update!");
999  M_currentId = geoele.id();
1000  M_currentLocalId = geoele.localId();
1001  //! compute the inverse jacobian...
1002  computeCellNodes (geoele);
1008  //! compute phiDer and phiDer2
1011  computeDphi();
1013  //! and the coordinates of the quadrature points
1015 }
1016 
1017 } // Namespace LifeV
1018 
1019 #endif /* CURRENTFE_H */
boost::multi_array< Real, 3 > M_dphiGeometricMap
Definition: CurrentFE.hpp:636
void computeDphiRef()
Compute the value of the derivatives in the reference frame.
Definition: CurrentFE.cpp:1043
GeometricMap - Structure for the geometrical mapping.
Real point(UInt node, UInt coordinate) const
Old accessor, use cellNode instead.
Definition: CurrentFE.hpp:513
Real d2phi(UInt node, UInt derivative1, UInt derivative2, UInt quadNode) const
Getter for the second derivatives of the basis functions.
Definition: CurrentFE.hpp:493
void computeDetJacobian()
Compute the determinant of the jacobian.
Definition: CurrentFE.cpp:973
UInt nbGeoNode() const
Getter for the number of geometrical nodes.
Definition: CurrentFE.hpp:371
void computeWDetJacobian()
Compute the determinant of the jacobian in the quadrature nodes.
Definition: CurrentFE.cpp:1031
int patternFirst(int i) const
patternFirst(i): row index in the element matrix of the i-th term of the pattern
Definition: CurrentFE.hpp:716
Real pointInverseJacobian(Real hat_x, Real hat_y, Real hat_z, int compx, int compzeta) const
Definition: CurrentFE.cpp:424
UInt currentId() const
Getter for the ID of the current cell.
Definition: CurrentFE.hpp:353
const UInt M_nbNode
Definition: CurrentFE.hpp:611
const flag_Type UPDATE_ONLY_PHI_VECT(1024)
const flag_Type UPDATE_ONLY_W_DET_JACOBIAN(32)
uint32_type flag_Type
bit-flag with up to 32 different flags
Definition: LifeV.hpp:197
QuadratureRule * M_quadRule
Definition: CurrentFE.hpp:627
boost::multi_array< Real, 3 > M_jacobian
Definition: CurrentFE.hpp:637
bool M_wDetJacobianUpdated
Definition: CurrentFE.hpp:660
const flag_Type UPDATE_ONLY_JACOBIAN(8)
const flag_Type UPDATE_ONLY_DPHI(128)
void update(const MeshElementMarkedType &geoele)
DECLARATION of the update methods.
Definition: CurrentFE.hpp:832
const flag_Type UPDATE_DPHI(UPDATE_ONLY_CELL_NODES|UPDATE_ONLY_DPHI_GEO_MAP|UPDATE_ONLY_JACOBIAN|UPDATE_ONLY_T_INVERSE_JACOBIAN|UPDATE_ONLY_DPHI_REF|UPDATE_ONLY_DPHI|UPDATE_ONLY_DET_JACOBIAN)
Real diameter2() const
return the diameter of the element in the 2-norm
Definition: CurrentFE.cpp:620
void computePhiVect()
Compute the value of the vectorial FE using Piola transform.
Definition: CurrentFE.cpp:1138
void coorBackMap(Real x, Real y, Real z, Real &xi, Real &eta, Real &zeta) const
Definition: CurrentFE.cpp:244
void computeCellNodes(const std::vector< std::vector< Real > > &pts)
Update only the nodes of the cells to the current one.
Definition: CurrentFE.cpp:829
Real detJac(UInt quadNode) const
Getter for the determinant of the jacobian in a given quadrature node.
Definition: CurrentFE.hpp:534
Real phi(UInt node, UInt component, UInt quadNode) const
Getter for basis function values (vectorial FE case)
Definition: CurrentFE.hpp:479
const ReferenceFE * M_refFE
Definition: CurrentFE.hpp:625
CurrentFE(const CurrentFE &)
Definition: CurrentFE.cpp:193
void computeDphiGeometricMap()
Compute the values of the derivatives of the mapping in the quadrature nodes.
Definition: CurrentFE.cpp:855
void updateSecondDeriv(const MeshElementMarkedType &geoele)
Definition: CurrentFE.hpp:928
const flag_Type UPDATE_ONLY_DPHI_REF(64)
boost::multi_array< Real, 2 > M_quadNodes
Definition: CurrentFE.hpp:634
void computeQuadNodes()
Update the location of the quadrature in the current cell.
Definition: CurrentFE.cpp:840
boost::numeric::ublas::vector< Real > GeoVector
UInt nbUpper() const
Getter for the number of entries in the pattern.
Definition: CurrentFE.hpp:413
const GeometricMap * M_geoMap
Definition: CurrentFE.hpp:626
GeoVector coorMap(const GeoVector &P) const
Definition: CurrentFE.cpp:671
UInt nbDiag() const
Getter for the diagonal entries in the pattern.
Definition: CurrentFE.hpp:407
Real phiDer2(UInt node, UInt derivative1, UInt derivative2, UInt quadNode) const
Old accessor, use d2phi instead.
Definition: CurrentFE.hpp:555
Real cellNode(UInt node, UInt coordinate) const
Getter for the nodes of the cell.
Definition: CurrentFE.hpp:437
void updateInverseJacobian(const UInt &iQuadPt)
const flag_Type UPDATE_WDET(UPDATE_ONLY_CELL_NODES|UPDATE_ONLY_DPHI_GEO_MAP|UPDATE_ONLY_JACOBIAN|UPDATE_ONLY_DET_JACOBIAN|UPDATE_ONLY_W_DET_JACOBIAN)
void update(const std::vector< GeoVector > &pts, flag_Type upFlag)
Update method using only point coordinates. It used the flags, as defined in this page...
Definition: CurrentFE.cpp:548
const flag_Type UPDATE_ONLY_DPHI_GEO_MAP(4)
void computeD2phiRef()
Compute the value of the second derivatives in the reference frame.
Definition: CurrentFE.cpp:1085
const UInt M_nbLocalCoor
Definition: CurrentFE.hpp:612
virtual ~CurrentFE()
Destructor.
Definition: CurrentFE.hpp:270
void updateFirstSecondDerivQuadPt(const MeshElementMarkedType &geoele)
Definition: CurrentFE.hpp:996
void computeD2phi()
Compute the value of the derivatives in the current element.
Definition: CurrentFE.cpp:1105
boost::multi_array< Real, 2 > M_divPhiRef
Definition: CurrentFE.hpp:650
const flag_Type UPDATE_DIV_PHI(UPDATE_ONLY_DIV_PHI_REF)
void update(const MeshElementMarked &geoele, flag_Type upFlag)
Definition: CurrentFE.hpp:791
const UInt M_nbPattern
Definition: CurrentFE.hpp:615
UInt nbLocalCoor() const
Getter for the number of local coordinates.
Definition: CurrentFE.hpp:425
Real phiDer(UInt node, UInt derivative, UInt quadNode) const
Old accessor, use dphi instead.
Definition: CurrentFE.hpp:548
const flag_Type UPDATE_ONLY_DET_JACOBIAN(4096)
const flag_Type UPDATE_ONLY_QUAD_NODES(2)
Real dphi(UInt node, UInt derivative, UInt quadNode) const
Getter for the derivatives of the basis functions.
Definition: CurrentFE.hpp:486
void updateJacQuadPt(const MeshElementMarkedType &geoele)
Definition: CurrentFE.hpp:861
#define ASSERT(X, A)
Definition: LifeAssert.hpp:90
const ReferenceFE & refFE() const
Getter for the reference FE.
Definition: CurrentFE.hpp:383
void updateSecondDerivQuadPt(const MeshElementMarkedType &geoele)
Definition: CurrentFE.hpp:950
Real tInverseJacobian(UInt element1, UInt element2, UInt quadNode) const
Getter for the inverse of the jacobian.
Definition: CurrentFE.hpp:465
void coorQuadPt(Real &x, Real &y, Real &z, int ig) const
Definition: CurrentFE.hpp:710
boost::multi_array< Real, 4 > M_d2phi
Definition: CurrentFE.hpp:644
void updateFirstDerivQuadPt(const MeshElementMarkedType &geoele)
Definition: CurrentFE.hpp:903
void updateFirstSecondDeriv(const MeshElementMarkedType &geoele)
Definition: CurrentFE.hpp:973
bool M_detJacobianUpdated
Definition: CurrentFE.hpp:659
bool M_tInverseJacobianUpdated
Definition: CurrentFE.hpp:661
const QuadratureRule & quadRule() const
Getter for the quadrature rule.
Definition: CurrentFE.hpp:395
void computeTInverseJacobian()
Compute the transposed inverse of the jacobian in the quadrature nodes.
Definition: CurrentFE.cpp:896
const UInt M_nbUpper
Definition: CurrentFE.hpp:614
virtual Real measure() const
Return the measure of the current element.
Definition: CurrentFE.cpp:563
Real tInvJac(UInt element1, UInt element2, UInt quadNode) const
Old accessor, use iInverseJacobian instead.
Definition: CurrentFE.hpp:541
Real diameter() const
return the diameter of the element in the 1-norm
Definition: CurrentFE.cpp:595
void computeDphi()
Compute the value of the derivatives in the current element.
Definition: CurrentFE.cpp:1059
Real quadNode(UInt node, UInt coordinate) const
Getter for the quadrature nodes.
Definition: CurrentFE.hpp:444
const flag_Type UPDATE_ONLY_D2PHI(512)
const UInt M_nbDiag
Definition: CurrentFE.hpp:613
boost::multi_array< Real, 3 > M_tInverseJacobian
Definition: CurrentFE.hpp:640
double Real
Generic real data.
Definition: LifeV.hpp:175
boost::multi_array< Real, 3 > M_phi
Definition: CurrentFE.hpp:642
boost::multi_array< Real, 1 > M_detJacobian
Definition: CurrentFE.hpp:638
CurrentFE - A primordial class for the assembly of the local matrices/vectors retaining the values on...
Definition: CurrentFE.hpp:243
UInt nbPattern() const
Getter for the number of entries in the pattern.
Definition: CurrentFE.hpp:401
boost::multi_array< Real, 2 > M_cellNodes
Definition: CurrentFE.hpp:633
boost::multi_array< Real, 4 > M_d2phiRef
Definition: CurrentFE.hpp:649
void computeJacobian()
Compute the jacobian in the quadrature nodes.
Definition: CurrentFE.cpp:871
UInt nbFEDof() const
Getter for the number of nodes.
Definition: CurrentFE.hpp:377
const flag_Type UPDATE_ONLY_T_INVERSE_JACOBIAN(16)
const flag_Type UPDATE_ONLY_DIV_PHI_REF(2048)
The class for a reference Lagrangian finite element.
void barycenter(Real &x, Real &y, Real &z) const
return the barycenter of the element
Definition: CurrentFE.cpp:575
boost::multi_array< Real, 3 > M_dphi
Definition: CurrentFE.hpp:643
const flag_Type UPDATE_QUAD_NODES(UPDATE_ONLY_CELL_NODES|UPDATE_ONLY_QUAD_NODES)
Real wDetJacobian(UInt quadNode) const
Getter for the weighted jacobian determinant.
Definition: CurrentFE.hpp:458
Real detJacobian(UInt quadNode) const
Getter for the determinant of the jacobian in a given quadrature node.
Definition: CurrentFE.hpp:451
const UInt nDimensions(NDIM)
Real phi(UInt node, UInt quadNode) const
Getter for basis function values (scalar FE case)
Definition: CurrentFE.hpp:472
boost::multi_array< Real, 3 > M_phiVect
Definition: CurrentFE.hpp:645
void updateJac(const MeshElementMarkedType &geoele)
Definition: CurrentFE.hpp:843
void updateFirstDeriv(const MeshElementMarkedType &geoele)
Definition: CurrentFE.hpp:881
#define LIFEV_DEPRECATED(func)
Definition: LifeV.hpp:117
CurrentFE(const ReferenceFE &refFE, const GeometricMap &geoMap)
Constructor without quadrature specification.
Definition: CurrentFE.cpp:157
int patternSecond(int i) const
patternSecond(i): column index in the element matrix of the i-th term of the pattern ...
Definition: CurrentFE.hpp:721
Real pointJacobian(Real hat_x, Real hat_y, Real hat_z, int compx, int compzeta) const
Definition: CurrentFE.cpp:350
CurrentFE(const ReferenceFE &refFE, const GeometricMap &geoMap, const QuadratureRule &qr)
Full constructor with default quadrature.
Definition: CurrentFE.cpp:43
const flag_Type UPDATE_D2PHI(UPDATE_ONLY_CELL_NODES|UPDATE_ONLY_DPHI_GEO_MAP|UPDATE_ONLY_JACOBIAN|UPDATE_ONLY_T_INVERSE_JACOBIAN|UPDATE_ONLY_D2PHI_REF|UPDATE_ONLY_D2PHI|UPDATE_ONLY_DET_JACOBIAN)
UInt currentLocalId() const
Getter for the local ID of the current cell.
Definition: CurrentFE.hpp:359
const GeometricMap & geoMap() const
Getter for the GeometricMap reference.
Definition: CurrentFE.hpp:389
void setQuadRule(const QuadratureRule &newQuadRule)
Setter for the quadrature rule.
Definition: CurrentFE.cpp:719
Real weightDet(UInt quadNode) const
Old accessor, use wDetJacobian instead.
Definition: CurrentFE.hpp:527
QuadratureRule - The basis class for storing and accessing quadrature rules.
const flag_Type UPDATE_PHI_VECT(UPDATE_ONLY_CELL_NODES|UPDATE_ONLY_DPHI_GEO_MAP|UPDATE_ONLY_JACOBIAN|UPDATE_ONLY_DET_JACOBIAN|UPDATE_ONLY_PHI_VECT)
boost::multi_array< Real, 1 > M_wDetJacobian
Definition: CurrentFE.hpp:639
Real divPhiRef(UInt node, UInt quadNode) const
Getter for the divergence of a vectorial FE in the reference frame.
Definition: CurrentFE.hpp:500
void computeCellNodes(const MeshElementMarked &geoele)
Definition: CurrentFE.hpp:809
const flag_Type UPDATE_ONLY_D2PHI_REF(256)
bool M_dphiGeometricMapUpdated
Definition: CurrentFE.hpp:657
Real pointDetJacobian(Real hat_x, Real hat_y, Real hat_z) const
Definition: CurrentFE.cpp:368
UInt nbQuadPt() const
Getter for the number of quadrature nodes.
Definition: CurrentFE.hpp:365
void quadRuleVTKexport(const std::string &filename) const
Export the quadrature rule on the current FE.
Definition: CurrentFE.cpp:689
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191
boost::multi_array< Real, 3 > M_dphiRef
Definition: CurrentFE.hpp:648
const Real & quadPointCoor(const UInt &ig, const UInt &icoor) const
quadPointCoor(ig,icoor) is the coordinate icoor of the quadrature point ig
void coorMap(Real &x, Real &y, Real &z, Real xi, Real eta, Real zeta) const
Definition: CurrentFE.cpp:648
Real quadPt(UInt node, UInt coordinate) const
Old accessor, use quadNode instead.
Definition: CurrentFE.hpp:520
const flag_Type UPDATE_ONLY_CELL_NODES(1)