LifeV
BCManage.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 Functions for prescribing boundary conditions
30 
31  @author Miguel Fernandez <miguel.fernandez@inria.fr>
32  @contributor Mauro Perego <perego.mauro@gmail.com>
33  @maintainer Mauro Perego <perego.mauro@gmail.com>
34 
35  @date 7-2002
36  *///@HEADER
37 
38 #ifndef BCMANAGE_H
39 #define BCMANAGE_H 1
40 
41 #include <lifev/core/array/MatrixEpetra.hpp>
42 #include <lifev/core/LifeV.hpp>
43 #include <lifev/core/fem/FESpace.hpp>
44 #include <lifev/core/fem/BCManageNormal.hpp>
45 
46 
47 namespace LifeV
48 {
49 
50 // ===================================================
51 //!@name Boundary conditions treatment
52 //@{
53 // ===================================================
54 
55 //! Prescribe boundary conditions.
56 /*!
57  The matrix and the right hand side are modified to take into account the boundary conditions
58  @param matrix The system matrix
59  @param rightHandSide The system right hand side
60  @param mesh The mesh
61  @param dof Container of the local to global map of DOFs
62  @param bcHandler The boundary conditions handler
63  @param currentBdFE Current finite element on boundary
64  @parma diagonalizeCoef The coefficient used during the system diagonalization
65  @param time The time
66  */
67 template <typename MatrixType, typename VectorType, typename MeshType, typename DataType>
68 void
69 bcManage ( MatrixType& matrix,
70  VectorType& rightHandSide,
71  MeshType const& mesh,
72  DOF const& dof,
73  BCHandler const& bcHandler,
74  CurrentFEManifold& currentBdFE,
75  DataType const& diagonalizeCoef,
76  DataType const& time = 0 );
77 
78 
79 
80 //! Prescribe boundary conditions. Case in which the user defined function depends on the FE vector feVec
81 /*!
82  The matrix and the right hand side are modified to take into account the boundary conditions
83  @param mu User defined function
84  @param matrix The system matrix
85  @param rightHandSide The system right hand side
86  @param mesh The mesh
87  @param dof Container of the local to global map of DOFs
88  @param bcHandler The boundary conditions handler
89  @param currentBdFE Current finite element on boundary
90  @parma diagonalizeCoef The coefficient used during the system diagonalization
91  @param time The time
92  @param feVec The finite element vector
93  */
94 template <typename MatrixType, typename VectorType, typename MeshType, typename DataType>
95 void
96 bcManage ( Real (*mu) (Real time, Real x, Real y, Real z, Real u),
97  MatrixType& matrix,
98  VectorType& rightHandSide,
99  const MeshType& mesh,
100  const DOF& dof,
101  const BCHandler& bcHandler,
102  CurrentFEManifold& currentBdFE,
103  const DataType diagonalizeCoef,
104  const DataType& time,
105  VectorType& feVec );
106 
107 
108 
109 //! Prescribe boundary conditions. Case in which only the matrix is modified
110 /*!
111  The matrix and the right hand side are modified to take into account the boundary conditions
112  @param matrix The system matrix
113  @param rightHandSide The system right hand side
114  @param mesh The mesh
115  @param dof Container of the local to global map of DOFs
116  @param bcHandler The boundary conditions handler
117  @param currentBdFE Current finite element on boundary
118  @parma diagonalizeCoef The coefficient used during the system diagonalization
119  @param time The time
120  */
121 template <typename MatrixType, typename MeshType, typename DataType>
122 void
123 bcManageMatrix ( MatrixType& matrix,
124  const MeshType& mesh,
125  const DOF& dof,
126  const BCHandler& bcHandler,
127  CurrentFEManifold& currentBdFE,
128  const DataType& diagonalizeCoef,
129  const DataType& time = 0 );
130 
131 
132 
133 //! Prescribe boundary conditions. Case in which only the right hand side is modified
134 /*! This method is deprecated since the order of diagonalizeCoef and time are switched wrt to bcManage.
135  * Use instead bcManageRhs ad be careful to use the correct order.
136  *
137  * The right hand side is modified to take into account the boundary conditions
138  * @param rightHandSide The system right hand side
139  * @param mesh The mesh
140  * @param dof Container of the local to global map of DOFs
141  * @param bcHandler The boundary conditions handler
142  * @param currentBdFE Current finite element on boundary
143  * @param time The time
144  * @parma diagonalizeCoef The coefficient used during the system diagonalization
145  */
146 template <typename VectorType, typename MeshType, typename DataType>
147 LIFEV_DEPRECATED ( void )
148 bcManageVector ( VectorType& rightHandSide,
149  const MeshType& mesh,
150  const DOF& dof,
151  const BCHandler& bcHandler,
152  CurrentFEManifold& currentBdFE,
153  const DataType& time,
154  const DataType& diagonalizeCoef );
155 
156 
157 //! Prescribe boundary conditions. Case in which only the right hand side is modified
158 /*!
159  * The right hand side is modified to take into account the boundary conditions
160  * @param rightHandSide The system right hand side
161  * @param mesh The mesh
162  * @param dof Container of the local to global map of DOFs
163  * @param bcHandler The boundary conditions handler
164  * @param currentBdFE Current finite element on boundary
165  * @parma diagonalizeCoef The coefficient used during the system diagonalization
166  * @param time The time
167  */
168 template <typename VectorType, typename MeshType, typename DataType>
169 void
170 bcManageRhs ( VectorType& rightHandSide,
171  const MeshType& mesh,
172  const DOF& dof,
173  const BCHandler& bcHandler,
174  CurrentFEManifold& currentBdFE,
175  const DataType& diagonalizeCoef,
176  const DataType& time );
177 
178 
179 
180 //! Prescribe boundary conditions. Case in which only the right hand side is modified
181 /*! This method is deprecated since the order of diagonalizeCoef and time are switched wrt to bcManage.
182  * Use instead bcManageRhs ad be careful to use the correct order.
183  *
184  * The Right hand side is modified to take into account the boundary conditions
185  * @param rightHandSide The system right hand side
186  * @param feSpace The finite element space
187  * @param bcHandler The boundary conditions handler
188  * @param time The time
189  * @parma diagonalizeCoef The coefficient used during the system diagonalization
190  */
191 template <typename VectorType, typename DataType, typename Mesh, typename MapEpetra>
192 LIFEV_DEPRECATED ( void )
193 bcManageVector ( VectorType& rightHandSide,
194  FESpace<Mesh, MapEpetra>& feSpace,
195  const BCHandler& bcHandler,
196  const DataType& time,
197  const DataType& diagonalizeCoef );
198 
199 //! Prescribe boundary conditions. Case in which only the residual is available
200 /*
201 The residual and the right hand side are modified to take into account the boundary conditions
202 @param res residual vector
203 @param rhs right hand side
204 @param sol the solution vector used to compute the residual. It must be a Unique VectorEpetra
205 @param feSpace the finite element space
206 @param bcHandler the boundary condition handler
207 @param time the current time level
208 @param diagonalizeCoef the coefficient put in the diagonal entry (of a matrix) when applying Dirichlet boundary conditions
209  */
210 template <typename VectorType, typename DataType, typename Mesh, typename MapEpetra>
211 void
212 bcManageResidual ( VectorType& res,
213  VectorType& rhs,
214  const VectorType& sol,
215  FESpace<Mesh, MapEpetra>& feSpace,
216  const BCHandler& bcHandler,
217  const DataType& time,
218  const DataType& diagonalizeCoef );
219 
220 
221 //! Prescribe boundary conditions. Case in which only the right hand side is modified
222 /*!
223  * The Right hand side is modified to take into account the boundary conditions
224  * @param rightHandSide The system right hand side
225  * @param feSpace The finite element space
226  * @param bcHandler The boundary conditions handler
227  * @param time The time
228  * @parma diagonalizeCoef The coefficient used during the system diagonalization
229  */
230 template <typename VectorType, typename DataType, typename Mesh, typename MapEpetra>
231 void
232 bcManageRhs ( VectorType& rightHandSide,
233  FESpace<Mesh, MapEpetra>& feSpace,
234  const BCHandler& bcHandler,
235  const DataType& diagonalizeCoef,
236  const DataType& time );
237 
238 //@}
239 
240 
241 // ===================================================
242 //! @name Essential BC
243 // @{
244 // ===================================================
245 
246 //! Prescribe Essential boundary conditions. Case in which the user defined function depends on the FE vector feVec
247 /*!
248  * The matrix and the right hand side are modified to take into account the Essential boundary conditions
249  * @param matrix The system matrix
250  * @param rightHandSide The system right hand side
251  * @param mesh The mesh
252  * @param dof Container of the local to global map of DOFs
253  * @param boundaryCond The boundary condition (@c BCBase)
254  * @param currentBdFE Current finite element on boundary
255  * @parma diagonalizeCoef The coefficient used during the system diagonalization
256  * @param time The time
257  * @param offset The boundary condition offset
258  */
259 template <typename MatrixType, typename VectorType, typename MeshType, typename DataType>
260 void
261 bcEssentialManage ( MatrixType& matrix,
262  VectorType& rightHandSide,
263  const MeshType& /*mesh*/,
264  const DOF& dof,
265  const BCBase& boundaryCond,
266  const CurrentFEManifold& /*currentBdFE*/,
267  const DataType& diagonalizeCoef,
268  const DataType& time,
269  UInt offset );
270 
271 
272 
273 //! Prescribe Essential boundary conditions. Case in which the user defined function depends on the FE vector feVec
274 /*!
275  * The matrix and the right hand side are modified to take into account the Essential boundary conditions
276  * @param matrix The system matrix
277  * @param rightHandSide The system right hand side
278  * @param mesh The mesh
279  * @param dof Container of the local to global map of DOFs
280  * @param boundaryCond The boundary condition (@c BCBase)
281  * @param currentBdFE Current finite element on boundary
282  * @parma diagonalizeCoef The coefficient used during the system diagonalization
283  * @param time The time
284  * @param feVec The finite element vector
285  * @param offset The bcCond offset
286  */
287 template <typename MatrixType, typename VectorType, typename MeshType, typename DataType>
288 void
289 bcEssentialManageUDep ( MatrixType& matrix,
290  VectorType& rightHandSide,
291  const MeshType& /*mesh*/,
292  const DOF& dof,
293  const BCBase& boundaryCond,
294  const CurrentFEManifold& /*currentBdFE*/,
295  const DataType& diagonalizeCoef,
296  const DataType& time,
297  const VectorType& feVec ,
298  UInt offset = 0 );
299 
300 
301 
302 //! Prescribe Essential boundary conditions diagonalizing the matrix
303 /*!
304  * The matrix is modified to take into account the Essential boundary conditions
305  * @param matrix The system matrix
306  * @param dof Container of the local to global map of DOFs
307  * @param boundaryCond The boundary condition (@c BCBase)
308  * @parma diagonalizeCoef The coefficient used during the system diagonalization
309  * @param offset The boundary condition offset
310  */
311 template <typename MatrixType, typename DataType>
312 void
313 bcEssentialManageMatrix ( MatrixType& matrix,
314  const DOF& dof,
315  const BCBase& boundaryCond,
316  const DataType& diagonalizeCoef,
317  UInt offset );
318 
319 
320 
321 //! Prescribe Essential boundary conditions on the right hand side
322 /*! This method is deprecated since the order of diagonalizeCoef and time are switched wrt to bcManage.
323  * Use instead bcManageRhs ad be careful to use the correct order.
324  *
325  * The right hand side is modified to take into account the Essential boundary conditions
326  * @param rightHandSide The system rightHandSide
327  * @param dof Container of the local to global map of DOFs
328  * @param boundaryCond The boundary condition (@c BCBase)
329  * @parma diagonalizeCoef The coefficient used during the system diagonalization
330  * @param offset The boundary condition offset
331  */
332 template <typename VectorType, typename DataType>
333 LIFEV_DEPRECATED ( void )
334 bcEssentialManageVector ( VectorType& rightHandSide,
335  const DOF& dof,
336  const BCBase& boundaryCond,
337  const DataType& time,
338  const DataType& diagonalizeCoef,
339  UInt offset );
340 
341 //! Prescribe Essential boundary conditions on the right hand side
342 /*!
343  * The right hand side is modified to take into account the Essential boundary conditions
344  * @param rightHandSide The system rightHandSide
345  * @param dof Container of the local to global map of DOFs
346  * @param boundaryCond The boundary condition (@c BCBase)
347  * @parma diagonalizeCoef The coefficient used during the system diagonalization
348  * @param offset The boundary condition offset
349  */
350 template <typename VectorType, typename DataType>
351 void
352 bcEssentialManageRhs ( VectorType& rightHandSide,
353  const DOF& dof,
354  const BCBase& boundaryCond,
355  const DataType& diagonalizeCoef,
356  const DataType& time,
357  UInt offset );
358 
359 //! Prescribe all the Essential boundary conditions on the right hand side and forgetting about the other BCs.
360 /*!
361  * The right hand side is modified to take into account the Essential boundary conditions
362  * This is useful when imposing homogeneous BC, in conjuction with coeff = 0.
363  * @param rightHandSide The system rightHandSide
364  * @param dof Container of the local to global map of DOFs
365  * @param bcHandler The boundary conditions handler
366  * @parma diagonalizeCoef The coefficient used during the system diagonalization
367  * @param offset The boundary condition offset
368  * Remark: another possible name would be bcManageHomogeneousRhs and set diagonalizeCoef = 0.
369  */
370 template <typename VectorType, typename DataType>
371 void
372 bcEssentialManageRhs ( VectorType& rightHandSide,
373  const DOF& dof,
374  const BCHandler& bcHandler,
375  const DataType& diagonalizeCoef,
376  const DataType& time);
377 
378 
379 
380 //! Prescribe essential boundary conditions. Case in which only the residual is available
381 /*
382 The residual and the right hand side are modified to take into account the boundary conditions
383 @param res residual vector
384 @param rhs right hand side
385 @param sol the solution vector used to compute the residual. It must be a Unique VectorEpetra
386 @param dof the DOF instance
387 @param boundaryCond the specific boundary condition (BCBase)
388 @param time the current time level
389 @param diagonalizeCoef the coefficient put in the diagonal entry (of a matrix) when applying Dirichlet boundary conditions
390 @param offset the UInt offset for the boundary condition
391  */
392 template <typename VectorType, typename DataType>
393 void
394 bcEssentialManageResidual (VectorType& res,
395  VectorType& rhs,
396  const VectorType& sol,
397  const DOF& dof,
398  const BCBase& boundaryCond,
399  const DataType& time,
400  const DataType& diagonalizeCoef,
401  UInt offset );
402 
403 
404 ///! Prescribe Essential boundary conditions.
405 /*!
406  * The matrix and the right hand side are modified to take into account the Essential boundary conditions
407  * @param matrix The system matrix
408  * @param dof Container of the local to global map of DOFs
409  * @param bcHandler The boundary condition handler
410  * @parma diagonalizeCoef The coefficient used during the system diagonalization
411  */
412 template <typename MatrixType, typename DataType>
413 void
414 bcManageMtimeUDep ( MatrixType& matrix,
415  const DOF& dof,
416  const BCHandler& bcHandler,
417  const DataType diagonalizeCoef);
418 
419 // @}
420 
421 // ===================================================
422 //! @name Natural BC
423 // @{
424 // ===================================================
425 
426 //! Prescribe Natural boundary condition
427 /*!
428  * The right hand side is modified to take into account the Natural boundary condition
429  * @param rightHandSide The system right hand side
430  * @param mesh The mesh
431  * @param dof Container of the local to global map of DOFs
432  * @param boundaryCond The boundary condition (@c BCBase)
433  * @param currentBdFE Current finite element on boundary
434  * @param time The time
435  * @param offset The boundary condition offset
436  */
437 template <typename VectorType, typename MeshType, typename DataType>
438 void
439 bcNaturalManage ( VectorType& rightHandSide,
440  const MeshType& mesh,
441  const DOF& dof, const
442  BCBase& boundaryCond,
443  CurrentFEManifold& currentBdFE,
444  const DataType& time,
445  UInt offset );
446 
447 
448 
449 
450 //! Prescribe Natural boundary condition. Case in which the user defined function depends on the FE vector feVec
451 /*!
452  * The right hand side is modified to take into account the Natural boundary condition
453  * @param mu User defined function
454  * @param rightHandSide The system right hand side
455  * @param mesh The mesh
456  * @param dof Container of the local to global map of DOFs
457  * @param boundaryCond The boundary condition (@c BCBase)
458  * @param currentBdFE Current finite element on boundary
459  * @param time The time
460  * @param offset The boundary condition offset
461  */
462 template <typename VectorType, typename MeshType, typename DataType>
463 void
464 bcNaturalManageUDep ( Real (*mu) (Real time, Real x, Real y, Real z, Real u),
465  VectorType& rightHandSide,
466  const MeshType& mesh,
467  const DOF& dof,
468  const BCBase& boundaryCond,
469  CurrentFEManifold& currentBdFE,
470  const DataType& time,
471  const VectorType& feVec,
472  UInt offset );
473 
474 // @}
475 
476 // ===================================================
477 //! @name Robin BC
478 // @{
479 // ===================================================
480 
481 //! Prescribe Robin boundary condition
482 /*!
483  * The matrix and the right hand side are modified to take into account the Robin boundary condition
484  * @param matrix The system matrix
485  * @param rightHandSide The system right hand side
486  * @param mesh The mesh
487  * @param dof Container of the local to global map of DOFs
488  * @param boundaryCond The boundary condition (@c BCBase)
489  * @param currentBdFE Current finite element on boundary
490  * @param time The time
491  * @param offset The boundary condition offset
492  */
493 template <typename MatrixType, typename VectorType, typename DataType, typename MeshType>
494 void
495 bcRobinManage ( MatrixType& matrix,
496  VectorType& rightHandSide,
497  const MeshType& mesh,
498  const DOF& dof,
499  const BCBase& boundaryCond,
500  CurrentFEManifold& currentBdFE,
501  const DataType& time,
502  UInt offset );
503 
504 
505 //! Prescribe Robin boundary condition only on the matrix
506 /*!
507  * The matrix is modified to take into account the Robin boundary condition
508  * @param matrix The system matrix
509  * @param mesh The mesh
510  * @param dof Container of the local to global map of DOFs
511  * @param boundaryCond The boundary condition (@c BCBase)
512  * @param currentBdFE Current finite element on boundary
513  * @param time The time
514  * @param offset The boundary condition offset
515  */
516 template <typename MatrixType, typename DataType, typename MeshType>
517 void
518 bcRobinManageMatrix ( MatrixType& matrix,
519  const MeshType& mesh,
520  const DOF& dof,
521  const BCBase& boundaryCond,
522  CurrentFEManifold& currentBdFE,
523  const DataType& time,
524  UInt offset );
525 
526 
527 
528 
529 //! Prescribe Robin boundary conditions. Case in which only the residual is available
530 /*
531 
532 The residual and the right hand side are modified to take into account the boundary conditions
533 @param res residual vector
534 @param rhs right hand side
535 @param sol the solution vector used to compute the residual. It must be a Unique VectorEpetra
536 @param dof the DOF instance
537 @param currentBdFE the current boundary finite element
538 @param boundaryCond the specific boundary condition (BCBase)
539 @param time the current time level
540 @param diagonalizeCoef the coefficient put in the diagonal entry (of a matrix) when applying Dirichlet boundary conditions
541 @param offset the UInt offset for the boundary condition
542  */
543 template <typename VectorType, typename DataType, typename MeshType>
544 void
545 bcRobinManageResidual ( VectorType& residual,
546  VectorType& rightHandSide,
547  const VectorType& solution,
548  const MeshType& mesh,
549  const DOF& dof,
550  const BCBase& boundaryCond,
551  CurrentFEManifold& currentBdFE,
552  const DataType& time,
553  UInt offset );
554 
555 
556  ////////////////////// Paolo Tricerri/////////////////////
557 //! Prescribe Robin boundary conditions. Case in which only the residual is available
558 /*
559 
560 The residual and the right hand side are modified to take into account the boundary conditions
561 @param res residual vector
562 @param rhs right hand side
563 @param sol the solution vector used to compute the residual. It must be a Unique VectorEpetra
564 @param dof the DOF instance
565 @param currentBdFE the current boundary finite element
566 @param boundaryCond the specific boundary condition (BCBase)
567 @param time the current time level
568 @param diagonalizeCoef the coefficient put in the diagonal entry (of a matrix) when applying Dirichlet boundary conditions
569 @param offset the UInt offset for the boundary condition
570  */
571 template <typename VectorType, typename DataType, typename MeshType>
572 void
573 bcResistanceManageResidual ( VectorType& residual,
574  VectorType& rightHandSide,
575  const VectorType& solution,
576  const MeshType& mesh,
577  const DOF& dof,
578  const BCBase& boundaryCond,
579  CurrentFEManifold& currentBdFE,
580  const DataType& time,
581  UInt offset );
582  ////////////////////// Paolo Tricerri/////////////////////
583 
584 //! Prescribe Robin boundary condition only on the rightHandSide
585 /*!
586  * The matrix is modified to take into account the Robin boundary condition
587  * @param rightHandSide The system right hand side
588  * @param mesh The mesh
589  * @param dof Container of the local to global map of DOFs
590  * @param boundaryCond The boundary condition (@c BCBase)
591  * @param currentBdFE Current finite element on boundary
592  * @param time The time
593  * @param offset The boundary condition offset
594  */
595 template <typename VectorType, typename DataType, typename MeshType>
596 void
597 bcRobinManageVector ( VectorType& rightHandSide,
598  const MeshType& mesh,
599  const DOF& dof,
600  const BCBase& boundaryCond,
601  CurrentFEManifold& currentBdFE,
602  const DataType& time,
603  UInt offset );
604 
605 // @}
606 
607 // ===================================================
608 //!@name Flux BC
609 //@{
610 // ===================================================
611 
612 //! Prescribe Flux boundary condition only on the matrix
613 /*!
614  * The matrix is modified to take into account the Flux boundary condition
615  * @param matrix The system matrix
616  * @param rightHandSide The system right hand side
617  * @param mesh The mesh
618  * @param dof Container of the local to global map of DOFs
619  * @param boundaryCond The boundary condition (@c BCBase)
620  * @param currentBdFE Current finite element on boundary
621  * @param time The time
622  * @param offset The boundary condition offset
623  */
624 template < typename MatrixType,
625  typename VectorType,
626  typename MeshType,
627  typename DataType >
628 void
629 bcFluxManage ( MatrixType& matrix,
630  VectorType& rightHandSide,
631  const MeshType& mesh,
632  const DOF& dof,
633  const BCBase& boundaryCond,
634  CurrentFEManifold& currentBdFE,
635  const DataType& time,
636  UInt offset);
637 
638 
639 //! Prescribe Flux boundary condition only on the right hand side
640 /*!
641  * The matrix is modified to take into account the Flux boundary condition
642  * @param rightHandSide The system right hand side
643  * @param mesh The mesh
644  * @param dof Container of the local to global map of DOFs
645  * @param boundaryCond The boundary condition (@c BCBase)
646  * @param currentBdFE Current finite element on boundary
647  * @param time The time
648  * @param offset The boundary condition offset
649  */
650 template < typename VectorType, typename DataType >
651 void
653  VectorType& rightHandSide,
654  const BCBase& boundaryCond,
655  const DataType& time,
656  UInt offset);
657 
658 
659 //! Prescribe Flux boundary condition only on the matrix
660 /*!
661  * The matrix is modified to take into account the Flux boundary condition
662  * @param matrix The system matrix
663  * @param mesh The mesh
664  * @param dof Container of the local to global map of DOFs
665  * @param boundaryCond The boundary condition (@c BCBase)
666  * @param currentBdFE Current finite element on boundary
667  * @param time The time
668  * @param offset The boundary condition offset
669  */
670 template < typename MatrixType,
671  typename MeshType,
672  typename DataType >
673 void
674 bcFluxManageMatrix ( MatrixType& matrix,
675  const MeshType& mesh,
676  const DOF& dof,
677  const BCBase& boundaryCond,
678  CurrentFEManifold& currentBdFE,
679  const DataType& /*time*/,
680  UInt offset );
681 
682 
683 //! Prescribe Flux boundary conditions. Case in which only the residual is available
684 /*
685 The residual and the right hand side are modified to take into account the boundary conditions
686 @param res residual vector
687 @param rhs right hand side
688 @param sol the solution vector used to compute the residual. It must be a Unique VectorEpetra
689 @param dof the DOF instance
690 @param currentBdFE the current boundary finite element
691 @param boundaryCond the specific boundary condition (BCBase)
692 @param time the current time level
693 @param diagonalizeCoef the coefficient put in the diagonal entry (of a matrix) when applying Dirichlet boundary conditions
694 @param offset the UInt offset for the boundary condition
695  */
696 template < typename VectorType,
697  typename MeshType,
698  typename DataType >
699 void
700 bcFluxManageResidual ( VectorType& residual,
701  VectorType& rightHandSide,
702  const VectorType& solution,
703  const MeshType& mesh,
704  const DOF& dof,
705  const BCBase& boundaryCond,
706  CurrentFEManifold& currentBdFE,
707  const DataType& /*time*/,
708  UInt offset );
709 // @}
710 
711 // ===================================================
712 //!@name Resistance BC
713 // @{
714 // ===================================================
715 
716 //! Prescribe Resistance boundary condition
717 /*!
718  * The matrix and the right hand side are modified to take into account the Resistance boundary condition
719  * @param rightHandSide The system right hand side
720  * @param mesh The mesh
721  * @param dof Container of the local to global map of DOFs
722  * @param boundaryCond The boundary condition (@c BCBase)
723  * @param currentBdFE Current finite element on boundary
724  * @param time The time
725  * @param offset The boundary condition offset
726  */
727 template <typename MatrixType, typename VectorType, typename DataType, typename MeshType>
728 void
729 bcResistanceManage ( MatrixType& matrix,
730  VectorType& rightHandSide,
731  const MeshType& mesh,
732  const DOF& dof,
733  const BCBase& boundaryCond,
734  CurrentFEManifold& currentBdFE,
735  const DataType& /*time*/,
736  UInt offset );
737 template <typename VectorType, typename DataType, typename MeshType>
738 void
739 bcResistanceManageVector ( VectorType& rightHandSide,
740  const MeshType& mesh,
741  const DOF& dof,
742  const BCBase& boundaryCond,
743  CurrentFEManifold& currentBdFE,
744  const DataType& /*time*/,
745  UInt offset );
746 template <typename MatrixType, typename DataType, typename MeshType>
747 void
748 bcResistanceManageMatrix ( MatrixType& matrix,
749  const MeshType& mesh,
750  const DOF& dof,
751  const BCBase& boundaryCond,
752  CurrentFEManifold& currentBdFE,
753  const DataType& /*time*/,
754  UInt offset );
755 
756 // @}
757 
758 // ===================================================
759 // Implementation
760 // ===================================================
761 
762 
763 // ===================================================
764 // Boundary conditions treatment
765 // ===================================================
766 
767 template <typename MatrixType, typename VectorType, typename MeshType, typename DataType>
768 void
769 bcManage ( MatrixType& matrix,
770  VectorType& rightHandSide,
771  MeshType const& mesh,
772  DOF const& dof,
773  BCHandler const& bcHandler,
774  CurrentFEManifold& currentBdFE,
775  DataType const& diagonalizeCoef,
776  DataType const& time )
777 {
778 
779  bool globalassemble = false;
780 
781  BCManageNormal<MatrixType> bcManageNormal;
782 
783  // Loop on boundary conditions
784  for ( ID i = 0; i < bcHandler.size(); ++i )
785  {
786  switch ( bcHandler[ i ].type() )
787  {
788  case Essential: // Essential boundary conditions (Dirichlet)
789  //Normal, Tangential or Directional boundary conditions
790  if ( (bcHandler[ i ].mode() == Tangential) || (bcHandler[ i ].mode() == Normal) || (bcHandler[ i ].mode() == Directional) )
791  {
792  bcManageNormal.init (bcHandler[ i ], time); //initialize bcManageNormal
793  }
794  case EssentialEdges:
795  case EssentialVertices:
796  globalassemble = true;
797  break;
798  case Natural: // Natural boundary conditions (Neumann)
799  bcNaturalManage ( rightHandSide, mesh, dof, bcHandler[ i ], currentBdFE, time, bcHandler.offset() );
800  break;
801  case Robin: // Robin boundary conditions (Robin)
802  bcRobinManage ( matrix, rightHandSide, mesh, dof, bcHandler[ i ], currentBdFE, time, bcHandler.offset() );
803  globalassemble = true;
804  break;
805  case Flux: // Flux boundary condition
806  bcFluxManage ( matrix, rightHandSide, mesh, dof, bcHandler[ i ], currentBdFE, time, bcHandler.offset() + bcHandler[i].offset() );
807  globalassemble = true;
808  break;
809  case Resistance: // Resistance boundary condition
810  bcResistanceManage ( matrix, rightHandSide, mesh, dof, bcHandler[ i ], currentBdFE, time, bcHandler.offset() );
811  globalassemble = true;
812  break;
813  default:
814  ERROR_MSG ( "This BC type is not yet implemented" );
815  }
816  }
817 
818  if (globalassemble)
819  {
820  matrix.globalAssemble();
821  }
822 
823  //Build the internal structure, if needed
824  bcManageNormal.build (mesh, dof, currentBdFE, matrix.map(), bcHandler.offset() );
825  bcManageNormal.exportToParaview ("normalAndTangents");
826 
827  //Applying the basis change, if needed
828  bcManageNormal.bcShiftToNormalTangentialCoordSystem (matrix, rightHandSide);
829 
830  // Loop on boundary conditions
831  for ( ID i = 0; i < bcHandler.size(); ++i )
832  {
833  switch ( bcHandler[ i ].type() )
834  {
835  case Essential: // Essential boundary conditions (Dirichlet)
836  case EssentialEdges:
837  case EssentialVertices:
838  bcEssentialManage ( matrix, rightHandSide, mesh, dof, bcHandler[ i ], currentBdFE, diagonalizeCoef, time, bcHandler.offset() );
839  break;
840  case Natural: // Natural boundary conditions (Neumann)
841  case Robin: // Robin boundary conditions (Robin)
842  case Flux: // Flux boundary condition
843  case Resistance: // Resistance boundary conditions
844  break;
845  default:
846  ERROR_MSG ( "This BC type is not yet implemented" );
847  }
848  }
849 
850  //Return back to the initial basis
851  bcManageNormal.bcShiftToCartesianCoordSystem (matrix, rightHandSide);
852 }
853 
854 template <typename MatrixType, typename VectorType, typename MeshType, typename DataType>
855 void
856 bcManage ( Real (*mu) (Real time, Real x, Real y, Real z, Real u),
857  MatrixType& matrix,
858  VectorType& rightHandSide,
859  const MeshType& mesh,
860  const DOF& dof,
861  const BCHandler& bcHandler,
862  CurrentFEManifold& currentBdFE,
863  const DataType diagonalizeCoef,
864  const DataType& time,
865  VectorType& feVec )
866 {
867 
868  bool globalassemble = false;
869  // Loop on boundary conditions
870  for ( ID i = 0; i < bcHandler.size(); ++i )
871  {
872  switch ( bcHandler[ i ].type() )
873  {
874  case Essential: // Essential boundary conditions (Dirichlet)
875  if ( (bcHandler[ i ].mode() == Tangential) || (bcHandler[ i ].mode() == Normal) || (bcHandler[ i ].mode() == Directional) )
876  {
877  ERROR_MSG ( "This BC mode is not yet implemented for this setting" );
878  }
879  case EssentialEdges:
880  case EssentialVertices:
881  globalassemble = true;
882  break;
883  case Natural: // Natural boundary conditions (Neumann)
884  if (bcHandler[ i ].isUDep() )
885  {
886  bcNaturalManageUDep (mu, rightHandSide, mesh, dof, bcHandler[ i ], currentBdFE, time, feVec, bcHandler.offset() );
887  }
888  else
889  //in this case mu must be a constant, think about (not still implemented)
890  {
891  bcNaturalManage ( rightHandSide, mesh, dof, bcHandler[ i ], currentBdFE, time, bcHandler.offset() );
892  }
893  break;
894  case Robin: // Robin boundary conditions (Robin)
895 
896  if (bcHandler[ i ].isUDep() )
897  {
898  ERROR_MSG ( "This BC mode is not yet implemented for this setting" ); //not implemented yet
899  }
900  else
901  {
902  bcRobinManage ( matrix, rightHandSide, mesh, dof, bcHandler[ i ], currentBdFE, time, bcHandler.offset() );
903  }
904  break;
905  default:
906  ERROR_MSG ( "This BC type is not yet implemented" );
907  }
908  }
909 
910 
911  if (globalassemble)
912  {
913  matrix.GlobalAssemble();
914  }
915 
916 
917  // Loop on boundary conditions
918  for ( ID i = 0; i < bcHandler.size(); ++i )
919  {
920 
921  switch ( bcHandler[ i ].type() )
922  {
923  case Essential: // Essential boundary conditions (Dirichlet)
924  case EssentialEdges:
925  case EssentialVertices:
926  if (bcHandler[ i ].isUDep() )
927  {
928  bcEssentialManageUDep (matrix, rightHandSide, mesh, dof, bcHandler[ i ], currentBdFE, diagonalizeCoef, time, feVec, bcHandler.offset() );
929  }
930  else
931  {
932  bcEssentialManage ( matrix, rightHandSide, mesh, dof, bcHandler[ i ], currentBdFE, diagonalizeCoef, time, bcHandler.offset() );
933  }
934  break;
935  case Natural:// Natural boundary conditions (Neumann)
936  break;
937  case Robin: // Robin boundary conditions (Robin)
938  break;
939  default:
940  ERROR_MSG ( "This BC type is not yet implemented" );
941  }
942  }
943 }
944 
945 template <typename MatrixType, typename MeshType, typename DataType>
946 void
947 bcManageMatrix ( MatrixType& matrix,
948  const MeshType& mesh,
949  const DOF& dof,
950  const BCHandler& bcHandler,
951  CurrentFEManifold& currentBdFE,
952  const DataType& diagonalizeCoef,
953  const DataType& time )
954 {
955 
956  bool globalassemble = false;
957  // Loop on boundary conditions
958  for ( ID i = 0; i < bcHandler.size(); ++i )
959  {
960 
961  switch ( bcHandler[ i ].type() )
962  {
963  case Essential: // Essential boundary conditions (Dirichlet)
964  case EssentialEdges:
965  case EssentialVertices:
966  globalassemble = true;
967  if ( (bcHandler[ i ].mode() == Tangential) || (bcHandler[ i ].mode() == Normal) || (bcHandler[ i ].mode() == Directional) )
968  {
969  ERROR_MSG ( "This BC mode is not yet implemented for this setting" );
970  }
971  break;
972  case Natural: // Natural boundary conditions (Neumann)
973  break;
974  case Robin: // Robin boundary conditions (Robin)
975  bcRobinManageMatrix ( matrix, mesh, dof, bcHandler[ i ], currentBdFE, time, bcHandler.offset() );
976  globalassemble = true;
977  break;
978  case Flux: // Flux boundary conditions
979  bcFluxManageMatrix ( matrix, mesh, dof, bcHandler[ i ], currentBdFE, time, bcHandler.offset() + bcHandler[i].offset() );
980  globalassemble = true;
981  break;
982  case Resistance:
983  bcResistanceManageMatrix ( matrix, mesh, dof, bcHandler[ i ], currentBdFE, time, bcHandler.offset() );
984  globalassemble = true;
985  break;
986  default:
987  ERROR_MSG ( "This BC type is not yet implemented" );
988  }
989  }
990  if (globalassemble)
991  {
992  matrix.globalAssemble();
993  }
994 
995  // Loop on boundary conditions
996  for ( ID i = 0; i < bcHandler.size(); ++i )
997  {
998 
999  switch ( bcHandler[ i ].type() )
1000  {
1001  case Essential: // Essential boundary conditions (Dirichlet)
1002  case EssentialEdges:
1003  case EssentialVertices:
1004  bcEssentialManageMatrix ( matrix, dof, bcHandler[ i ], diagonalizeCoef, bcHandler.offset() ); //! Bug here???
1005  break;
1006  case Natural: // Natural boundary conditions (Neumann)
1007  // Do nothing
1008  break;
1009  case Robin: // Robin boundary conditions (Robin)
1010  break;
1011  case Flux: // Robin boundary conditions (Robin)
1012  break;
1013  case Resistance:
1014  break;
1015  default:
1016  ERROR_MSG ( "This BC type is not yet implemented" );
1017  }
1018  }
1019 }
1020 
1021 template <typename VectorType, typename MeshType, typename DataType>
1022 void
1023 bcManageVector ( VectorType& rightHandSide,
1024  const MeshType& mesh,
1025  const DOF& dof,
1026  const BCHandler& bcHandler,
1027  CurrentFEManifold& currentBdFE,
1028  const DataType& time,
1029  const DataType& diagonalizeCoef )
1030 {
1031  bcManageRhs ( rightHandSide,
1032  mesh,
1033  dof,
1034  bcHandler,
1035  currentBdFE,
1036  diagonalizeCoef,
1037  time );
1038 }
1039 
1040 template <typename VectorType, typename MeshType, typename DataType>
1041 void
1042 bcManageRhs ( VectorType& rightHandSide,
1043  const MeshType& mesh,
1044  const DOF& dof,
1045  const BCHandler& bcHandler,
1046  CurrentFEManifold& currentBdFE,
1047  const DataType& diagonalizeCoef,
1048  const DataType& time )
1049 {
1050 
1051  // Loop on boundary conditions
1052  for ( ID i = 0; i < bcHandler.size(); ++i )
1053  {
1054 
1055  switch ( bcHandler[ i ].type() )
1056  {
1057  case Essential: // Essential boundary conditions (Dirichlet)
1058  case EssentialEdges:
1059  case EssentialVertices:
1060  if ( (bcHandler[ i ].mode() == Tangential) || (bcHandler[ i ].mode() == Normal) || (bcHandler[ i ].mode() == Directional) )
1061  {
1062  ERROR_MSG ( "This BC mode is not yet implemented for this setting" );
1063  }
1064  bcEssentialManageRhs ( rightHandSide, dof, bcHandler[ i ], diagonalizeCoef, time, bcHandler.offset() );
1065  break;
1066  case Natural: // Natural boundary conditions (Neumann)
1067  bcNaturalManage ( rightHandSide, mesh, dof, bcHandler[ i ], currentBdFE, time, bcHandler.offset() );
1068  break;
1069  case Robin: // Robin boundary conditions (Robin)
1070  bcRobinManageVector ( rightHandSide, mesh, dof, bcHandler[ i ], currentBdFE, time, bcHandler.offset() );
1071  break;
1072  case Flux: // Flux boundary conditions
1073  bcFluxManageVector ( rightHandSide, bcHandler[ i ], time, bcHandler.offset() + bcHandler[i].offset() );
1074  break;
1075  case Resistance:
1076  bcResistanceManageVector ( rightHandSide, mesh, dof, bcHandler[ i ], currentBdFE, time, bcHandler.offset() );
1077  break;
1078  default:
1079  ERROR_MSG ( "This BC type is not yet implemented" );
1080  }
1081  }
1082 
1083 }
1084 
1085 
1086 template <typename VectorType, typename MeshType, typename DataType>
1087 void
1088 bcManageResidual ( VectorType& res,
1089  VectorType& rhs,
1090  const VectorType& sol,
1091  const MeshType& mesh,
1092  const DOF& dof,
1093  const BCHandler& bcHandler,
1094  CurrentFEManifold& currentBdFE,
1095  const DataType& time,
1096  const DataType& diagonalizeCoef )
1097 {
1098  VectorType rhsRepeated (rhs.map(), Repeated);
1099 
1100  // Loop on boundary conditions
1101  for ( ID i = 0; i < bcHandler.size(); ++i )
1102  {
1103 
1104  switch ( bcHandler[ i ].type() )
1105  {
1106  case Essential: // Essential boundary conditions (Dirichlet)
1107  case EssentialEdges:
1108  case EssentialVertices:
1109  if ( (bcHandler[ i ].mode() == Tangential) || (bcHandler[ i ].mode() == Normal) || (bcHandler[ i ].mode() == Directional) )
1110  {
1111  ERROR_MSG ( "This BC mode is not yet implemented for this setting" );
1112  }
1113  bcEssentialManageResidual ( res, rhs, sol, dof, bcHandler[ i ], time, diagonalizeCoef, bcHandler.offset() );
1114  break;
1115  case Natural: // Natural boundary conditions (Neumann)
1116  bcNaturalManage ( rhs, mesh, dof, bcHandler[ i ], currentBdFE, time, bcHandler.offset() );
1117  break;
1118  case Robin: // Robin boundary conditions (Robin) to be implemented
1119  bcRobinManageResidual ( res, rhs, sol, mesh, dof, bcHandler[ i ], currentBdFE, time, bcHandler.offset() );
1120  break;
1121  case Resistance: // Resistance boundary conditions
1122  bcResistanceManageResidual ( res, rhs, sol, mesh, dof, bcHandler[ i ], currentBdFE, time, bcHandler.offset() );
1123  break;
1124  case Flux: // Flux boundary conditions to be implemented
1125  bcFluxManageResidual ( res, rhs, sol, mesh, dof, bcHandler[ i ], currentBdFE, time, bcHandler.offset() + bcHandler[i].offset() );
1126  break;
1127  default:
1128  ERROR_MSG ( "This BC type is not yet implemented" );
1129  }
1130  }
1131 
1132  // rhsRepeated.globalAssemble();
1133 
1134  //rhs += rhsRepeated;
1135 }
1136 
1137 
1138 template <typename VectorType, typename DataType, typename Mesh, typename MapEpetra>
1139 void
1140 bcManageVector ( VectorType& rightHandSide,
1141  FESpace<Mesh, MapEpetra>& feSpace,
1142  const BCHandler& bcHandler,
1143  const DataType& time,
1144  const DataType& diagonalizeCoef )
1145 {
1146  bcManageRhs ( rightHandSide,
1147  feSpace,
1148  bcHandler,
1149  diagonalizeCoef,
1150  time );
1151 }
1152 
1153 template <typename VectorType, typename DataType, typename Mesh, typename MapEpetra>
1154 void
1155 bcManageRhs ( VectorType& rightHandSide,
1156  FESpace<Mesh, MapEpetra>& feSpace,
1157  const BCHandler& bcHandler,
1158  const DataType& diagonalizeCoef,
1159  const DataType& time )
1160 {
1161  // Loop on boundary conditions
1162  for ( ID i = 0; i < bcHandler.size(); ++i )
1163  {
1164 
1165  switch ( bcHandler[ i ].type() )
1166  {
1167  case Essential: // Essential boundary conditions (Dirichlet)
1168  case EssentialEdges:
1169  case EssentialVertices:
1170  if ( (bcHandler[ i ].mode() == Tangential) || (bcHandler[ i ].mode() == Normal) || (bcHandler[ i ].mode() == Directional) )
1171  {
1172  ERROR_MSG ( "This BC mode is not yet implemented for this setting" );
1173  }
1174  bcEssentialManageRhs ( rightHandSide, feSpace.dof(), bcHandler[ i ], diagonalizeCoef, time, bcHandler.offset() );
1175  break;
1176  case Natural: // Natural boundary conditions (Neumann)
1177  bcNaturalManage ( rightHandSide, *feSpace.mesh(), feSpace.dof(), bcHandler[ i ], feSpace.feBd(), time, bcHandler.offset() );
1178  break;
1179  case Robin: // Robin boundary conditions (Robin)
1180  bcRobinManageVector ( rightHandSide, *feSpace.mesh(), feSpace.dof(), bcHandler[ i ], feSpace.feBd(), time, bcHandler.offset() );
1181  break;
1182  case Flux: // Flux boundary conditions
1183  bcFluxManageVector ( rightHandSide, bcHandler[ i ], time, bcHandler.offset() + bcHandler[i].offset() );
1184  break;
1185  default:
1186  ERROR_MSG ( "This BC type is not yet implemented" );
1187  }
1188  }
1189 
1190 }
1191 
1192 // ===================================================
1193 // Essential BC
1194 // ===================================================
1195 
1196 template <typename MatrixType, typename VectorType, typename MeshType, typename DataType>
1197 void
1198 bcEssentialManage ( MatrixType& matrix,
1199  VectorType& rightHandSide,
1200  const MeshType& /*mesh*/,
1201  const DOF& dof,
1202  const BCBase& boundaryCond,
1203  const CurrentFEManifold& /*currentBdFE*/,
1204  const DataType& diagonalizeCoef,
1205  const DataType& time,
1206  UInt offset )
1207 {
1208 
1209  ID idDof;
1210 
1211  // Number of components involved in this boundary condition
1212  UInt nComp = boundaryCond.numberOfComponents();
1213 
1214  // Number of total scalar Dof
1215  UInt totalDof = dof.numTotalDof();
1216 
1217 
1218  std::vector<ID> idDofVec (0);
1219  std::vector<Real> datumVec (0);
1220 
1221  idDofVec.reserve (boundaryCond.list_size() *nComp);
1222  datumVec.reserve (boundaryCond.list_size() *nComp);
1223 
1224  if ( boundaryCond.isDataAVector() )
1225  {
1226  //! If BC is given under a vectorial form
1227 
1228  assert ( static_cast< const BCVectorInterface* > (boundaryCond.pointerToBCVector() ) != 0 );
1229 
1230  // Loop on BC identifiers
1231  for ( ID i = 0; i < boundaryCond.list_size(); ++i )
1232  {
1233 
1234  // Loop on components involved in this boundary condition
1235  for ( ID j = 0; j < nComp; ++j )
1236  {
1237  // Global Dof
1238  idDof = boundaryCond[ i ]->id() + boundaryCond.component ( j ) * totalDof + offset;
1239  datumVec.push_back (boundaryCond ( boundaryCond[ i ] ->id(), boundaryCond.component ( j ) ) );
1240  idDofVec.push_back (idDof);
1241  }
1242  }
1243  }
1244  else
1245  {
1246  //! If BC is given under a functional form
1247 
1248  DataType x, y, z;
1249  // Loop on BC identifiers
1250  for ( ID i = 0; i < boundaryCond.list_size(); ++i )
1251  {
1252  // Coordinates of the node where we impose the value
1253  x = static_cast< const BCIdentifierEssential* > ( boundaryCond[ i ] ) ->x();
1254  y = static_cast< const BCIdentifierEssential* > ( boundaryCond[ i ] ) ->y();
1255  z = static_cast< const BCIdentifierEssential* > ( boundaryCond[ i ] ) ->z();
1256 
1257  // Loop on components involved in this boundary condition
1258  for ( ID j = 0; j < nComp; ++j )
1259  {
1260  // Global Dof
1261  idDof = boundaryCond[ i ] ->id() + boundaryCond.component ( j ) * totalDof + offset;
1262 
1263  datumVec.push_back (boundaryCond ( time, x, y, z, boundaryCond.component ( j ) ) );
1264  idDofVec.push_back (idDof);
1265 
1266  }
1267  }
1268  }
1269 
1270  // If there is an offset than there is a Lagrange multiplier (flux BC)
1271  if (boundaryCond.offset() > 0)
1272  {
1273  // bcType has been changed Flux -> Essential, need to diagonalize also the Lagrange multiplier
1274  idDofVec.push_back (offset + boundaryCond.offset() );
1275  datumVec.push_back ( 0. );
1276  }
1277 
1278  // Modifying matrix and right hand side
1279  matrix.diagonalize ( idDofVec, diagonalizeCoef, rightHandSide, datumVec);
1280 
1281 }
1282 
1283 
1284 template <typename MatrixType, typename VectorType, typename MeshType, typename DataType>
1285 void
1286 bcEssentialManageUDep ( MatrixType& matrix,
1287  VectorType& rightHandSide,
1288  const MeshType& /*mesh*/,
1289  const DOF& dof,
1290  const BCBase& boundaryCond,
1291  const CurrentFEManifold& /*currentBdFE*/,
1292  const DataType& diagonalizeCoef,
1293  const DataType& time,
1294  const VectorType& feVec ,
1295  UInt offset )
1296 {
1297 
1298  ID idDof;
1299 
1300  // Number of components involved in this boundary condition
1301  UInt nComp = boundaryCond.numberOfComponents();
1302 
1303  // Number of total scalar Dof
1304  UInt totalDof = dof.numTotalDof();
1305 
1306  if ( boundaryCond.isDataAVector() )
1307  {
1308  //! If BC is given under a vectorial form
1309 
1310  //not possible
1311  ERROR_MSG ( "This type of BCVector does not exists on bc depentent on solution" );
1312  }
1313  else
1314  {
1315  //! If BC is given under a functional form
1316 
1317  std::vector<ID> idDofVec (0);
1318  std::vector<Real> datumVec (0);
1319 
1320  idDofVec.reserve (boundaryCond.list_size() *nComp);
1321  datumVec.reserve (boundaryCond.list_size() *nComp);
1322 
1323  DataType x, y, z;
1324  // Loop on BC identifiers
1325  for ( ID i = 0; i < boundaryCond.list_size(); ++i )
1326  {
1327  // Coordinates of the node where we impose the value
1328  x = static_cast< const BCIdentifierEssential* > ( boundaryCond[ i ] ) ->x();
1329  y = static_cast< const BCIdentifierEssential* > ( boundaryCond[ i ] ) ->y();
1330  z = static_cast< const BCIdentifierEssential* > ( boundaryCond[ i ] ) ->z();
1331 
1332  // Loop on components involved in this boundary condition
1333  for ( ID j = 0; j < nComp; ++j )
1334  {
1335  // Global Dof
1336  idDof = boundaryCond[ i ] ->id() + boundaryCond.component ( j ) * totalDof + offset;
1337 
1338  Real datum = boundaryCond ( time, x, y, z, boundaryCond.component ( j ) , feVec[idDof]);
1339 
1340  datumVec.push_back (datum);
1341  idDofVec.push_back (idDof);
1342 
1343  }
1344  }
1345 
1346  // If there is an offset than there is a Lagrange multiplier (flux BC)
1347  if (boundaryCond.offset() > 0)
1348  {
1349  // bcType has been changed Flux -> Essential, need to diagonalize also the Lagrange multiplier
1350  idDofVec.push_back (offset + boundaryCond.offset() );
1351  }
1352 
1353  // Modifying matrix and right hand side
1354  matrix.diagonalize ( idDofVec, diagonalizeCoef, rightHandSide, datumVec);
1355  }
1356 }
1357 
1358 
1359 template <typename MatrixType, typename DataType>
1360 void
1361 bcEssentialManageMatrix ( MatrixType& matrix,
1362  const DOF& dof,
1363  const BCBase& boundaryCond,
1364  const DataType& diagonalizeCoef,
1365  UInt offset )
1366 {
1367  ID idDof;
1368  UInt totalDof;
1369 
1370  // Number of total scalar Dof
1371  totalDof = dof.numTotalDof();
1372 
1373  // Number of components involved in this boundary condition
1374  UInt nComp = boundaryCond.numberOfComponents();
1375 
1376  std::vector<ID> idDofVec (0);
1377  idDofVec.reserve (boundaryCond.list_size() *nComp);
1378 
1379  // Loop on BC identifiers
1380  for ( ID i = 0; i < boundaryCond.list_size(); ++i )
1381  {
1382  // Loop on components involved in this boundary condition
1383  for ( ID j = 0; j < nComp; ++j )
1384  {
1385  // Global Dof
1386  idDof = boundaryCond[ i ] ->id() + boundaryCond.component ( j ) * totalDof;
1387  idDofVec.push_back (idDof);
1388  }
1389  }
1390 
1391  // If there is an offset than there is a Lagrange multiplier (flux BC)
1392  if (boundaryCond.offset() > 0)
1393  {
1394  // bcType has been changed Flux -> Essential, need to diagonalize also the Lagrange multiplier
1395  idDofVec.push_back (offset + boundaryCond.offset() );
1396  }
1397 
1398  // Modifying ONLY matrix
1399  matrix.diagonalize ( idDofVec, diagonalizeCoef, offset);
1400 }
1401 
1402 
1403 template <typename VectorType, typename DataType>
1404 void
1405 bcEssentialManageVector ( VectorType& rightHandSide,
1406  const DOF& dof,
1407  const BCBase& boundaryCond,
1408  const DataType& time,
1409  const DataType& diagonalizeCoef,
1410  UInt offset )
1411 {
1412  bcEssentialManageRhs ( rightHandSide,
1413  dof,
1414  boundaryCond,
1415  diagonalizeCoef,
1416  time,
1417  offset );
1418 
1419 }
1420 
1421 template <typename VectorType, typename DataType>
1422 void
1423 bcEssentialManageRhs ( VectorType& rightHandSide,
1424  const DOF& dof,
1425  const BCHandler& bcHandler,
1426  const DataType& diagonalizeCoef,
1427  const DataType& time)
1428 {
1429  // Loop on boundary conditions
1430  for ( ID i = 0; i < bcHandler.size(); ++i )
1431  {
1432 
1433  switch ( bcHandler[ i ].type() )
1434  {
1435  case Essential: // Essential boundary conditions (Dirichlet)
1436  case EssentialEdges:
1437  case EssentialVertices:
1438  if ( (bcHandler[ i ].mode() == Tangential) ||
1439  (bcHandler[ i ].mode() == Normal) || (bcHandler[ i ].mode() == Directional) )
1440  {
1441  ERROR_MSG ( "This BC mode is not yet implemented for this setting" );
1442  }
1443  bcEssentialManageRhs ( rightHandSide, dof, bcHandler[ i ], diagonalizeCoef, time, bcHandler.offset() );
1444  break;
1445  // Not considering the other cases.
1446  case Natural: // Natural boundary conditions (Neumann)
1447  case Robin: // Robin boundary conditions (Robin)
1448  case Flux: // Flux boundary conditions
1449  break;
1450  default:
1451  ERROR_MSG ( "This BC type is not yet implemented" );
1452  }
1453  }
1454 
1455 }
1456 
1457 template <typename VectorType, typename DataType>
1458 void
1459 bcEssentialManageRhs ( VectorType& rightHandSide,
1460  const DOF& dof,
1461  const BCBase& boundaryCond,
1462  const DataType& diagonalizeCoef,
1463  const DataType& time,
1464  UInt offset )
1465 {
1466  ID idDof;
1467  UInt totalDof;
1468 
1469  // Number of total scalar Dof
1470  totalDof = dof.numTotalDof();
1471 
1472  // Number of components involved in this boundary condition
1473  UInt nComp = boundaryCond.numberOfComponents();
1474 
1475  std::vector<int> idDofVec (0);
1476  idDofVec.reserve (boundaryCond.list_size() *nComp);
1477  std::vector<Real> datumVec (0);
1478  datumVec.reserve (boundaryCond.list_size() *nComp);
1479 
1480  if ( boundaryCond.isDataAVector() )
1481  {
1482  //! If BC is given under a vectorial form
1483 
1484  // Loop on BC identifiers
1485  for ( ID i = 0; i < boundaryCond.list_size(); ++i )
1486  {
1487  // Loop on components involved in this boundary condition
1488  for ( ID j = 0; j < nComp; ++j )
1489  {
1490 
1491  // Global Dof
1492  idDof = boundaryCond[ i ] ->id() + boundaryCond.component ( j ) * totalDof + offset;
1493 
1494  idDofVec.push_back ( idDof );
1495  datumVec.push_back ( diagonalizeCoef * boundaryCond ( boundaryCond[ i ] ->id(), boundaryCond.component ( j ) ) );
1496  }
1497  }
1498  }
1499  else
1500  {
1501  //! If BC is given under a functional form
1502 
1503  DataType x, y, z;
1504  // Loop on BC identifiers
1505  for ( ID i = 0; i < boundaryCond.list_size(); ++i )
1506  {
1507  // Coordinates of the node where we impose the value
1508  x = static_cast< const BCIdentifierEssential* > ( boundaryCond[ i ] ) ->x();
1509  y = static_cast< const BCIdentifierEssential* > ( boundaryCond[ i ] ) ->y();
1510  z = static_cast< const BCIdentifierEssential* > ( boundaryCond[ i ] ) ->z();
1511 
1512  // Loop on components involved in this boundary condition
1513  for ( ID j = 0; j < nComp; ++j )
1514  {
1515  // Global Dof
1516 
1517  idDof = boundaryCond[ i ] ->id() + boundaryCond.component ( j ) * totalDof + offset;
1518  // Modifying right hand side
1519  idDofVec.push_back (idDof);
1520  datumVec.push_back ( diagonalizeCoef * boundaryCond ( time, x, y, z, boundaryCond.component ( j ) ) );
1521  }
1522  }
1523  }
1524 
1525  rightHandSide.setCoefficients ( idDofVec, datumVec);
1526 }
1527 
1528 
1529 template <typename VectorType, typename DataType>
1530 void
1531 bcEssentialManageResidual (VectorType& res,
1532  VectorType& rhs,
1533  const VectorType& sol,
1534  const DOF& dof,
1535  const BCBase& boundaryCond,
1536  const DataType& time,
1537  const DataType& diagonalizeCoef,
1538  UInt offset )
1539 {
1540 
1541  if (sol.mapType() == Unique)
1542  {
1543  std::cout << "pass me a repeated solution" << std::endl;
1544  VectorType repeatedSolution (sol, Repeated);
1545  bcEssentialManageResidual ( res,
1546  rhs,
1547  repeatedSolution,
1548  dof,
1549  boundaryCond,
1550  time,
1551  diagonalizeCoef,
1552  offset );
1553  return;
1554  }
1555 
1556  ID idDof;
1557  UInt totalDof;
1558 
1559  // Number of total scalar Dof
1560  totalDof = dof.numTotalDof();
1561 
1562  // Number of components involved in this boundary condition
1563  UInt nComp = boundaryCond.numberOfComponents();
1564 
1565  std::vector<int> idDofVec (0);
1566  idDofVec.reserve (boundaryCond.list_size() *nComp);
1567  std::vector<Real> datumVec (0);
1568  datumVec.reserve (boundaryCond.list_size() *nComp);
1569  std::vector<Real> rhsVec (0);
1570  rhsVec.reserve (boundaryCond.list_size() *nComp);
1571 
1572  if ( boundaryCond.isDataAVector() )
1573  {
1574  //! If BC is given under a vectorial form
1575  // Loop on BC identifiers
1576  for ( ID i = 0; i < boundaryCond.list_size(); ++i )
1577  {
1578  // Loop on components involved in this boundary condition
1579  for ( ID j = 0; j < nComp; ++j )
1580  {
1581  // Global Dof
1582  idDof = boundaryCond[ i ] ->id() + boundaryCond.component ( j ) * totalDof + offset;
1583  idDofVec.push_back ( idDof );
1584  datumVec.push_back ( diagonalizeCoef * sol (idDof) );
1585  rhsVec.push_back (diagonalizeCoef * boundaryCond ( boundaryCond[ i ] ->id(), boundaryCond.component ( j ) ) );
1586  }
1587  }
1588  }
1589  else
1590  {
1591  //! If BC is given under a functional form
1592  DataType x, y, z;
1593  // Loop on BC identifiers
1594  for ( ID i = 0; i < boundaryCond.list_size(); ++i )
1595  {
1596  // Coordinates of the node where we impose the value
1597  x = static_cast< const BCIdentifierEssential* > ( boundaryCond[ i ] ) ->x();
1598  y = static_cast< const BCIdentifierEssential* > ( boundaryCond[ i ] ) ->y();
1599  z = static_cast< const BCIdentifierEssential* > ( boundaryCond[ i ] ) ->z();
1600 
1601  // Loop on components involved in this boundary condition
1602  for ( ID j = 0; j < nComp; ++j )
1603  {
1604  // Global Dof
1605 
1606  idDof = boundaryCond[ i ] ->id() + boundaryCond.component ( j ) * totalDof + offset;
1607  // Modifying right hand side
1608  idDofVec.push_back (idDof);
1609  datumVec.push_back ( diagonalizeCoef * sol (idDof) );
1610  rhsVec.push_back (diagonalizeCoef * boundaryCond ( time, x, y, z, boundaryCond.component ( j ) ) );
1611  }
1612  }
1613  }
1614 
1615  res.setCoefficients ( idDofVec, datumVec);
1616  rhs.setCoefficients ( idDofVec, rhsVec);
1617 }
1618 
1619 // ===================================================
1620 // Natural BC
1621 // ===================================================
1622 
1623 template <typename VectorType, typename MeshType, typename DataType>
1624 void
1625 bcNaturalManage ( VectorType& rightHandSide,
1626  const MeshType& mesh,
1627  const DOF& dof, const
1628  BCBase& boundaryCond,
1629  CurrentFEManifold& currentBdFE,
1630  const DataType& time,
1631  UInt offset )
1632 {
1633 
1634  // Number of local DOF (i.e. nodes) in this face
1635  UInt nDofF = currentBdFE.nbFEDof();
1636 
1637  // Number of total scalar Dof
1638  UInt totalDof = dof.numTotalDof();
1639 
1640  // Number of components involved in this boundary condition
1641  UInt nComp = boundaryCond.numberOfComponents();
1642 
1643  const BCIdentifierNatural* pId;
1644  ID ibF, idDof, icDof, gDof;
1645  Real sum;
1646 
1647  if ( boundaryCond.isDataAVector() )
1648  {
1649  //! If BC is given under a vectorial form
1650  switch ( boundaryCond.pointerToBCVector()->type() )
1651  {
1652  case 0: // if the BC is a vector which values don'time need to be integrated
1653  {
1654  VectorType bUnique (rightHandSide.map(), Unique);
1655 
1656  std::vector<int> idDofVec (0);
1657  idDofVec.reserve (boundaryCond.list_size() *nComp);
1658  std::vector<Real> datumVec (0);
1659  datumVec.reserve (boundaryCond.list_size() *nComp);
1660  // double datum;
1661 
1662  // Loop on BC identifiers
1663  for ( ID i = 0; i < boundaryCond.list_size(); ++i )
1664  {
1665  // Loop on components involved in this boundary condition
1666  for ( ID j = 0; j < nComp; ++j )
1667  {
1668  ID id = boundaryCond[i]->id();
1669 
1670  // Global Dof
1671  idDof = id + boundaryCond.component ( j ) * totalDof + offset;
1672 
1673  idDofVec.push_back ( idDof);
1674 
1675  // Modifying right hand side (assuming BCvector is a flux)
1676  datumVec.push_back ( boundaryCond ( id , boundaryCond.component ( j ) ) );
1677  }
1678  }
1679 
1680  bUnique.setCoefficients (idDofVec, datumVec);
1681  bUnique.globalAssemble (Insert);
1682 
1683  ASSERT ( rightHandSide.mapType() == Unique , "rightHandSide must have unique map, otherwise data will be multiply added on cpu interfaces." );
1684  rightHandSide += bUnique;
1685 
1686  }
1687  break;
1688 
1689  case 1: // if the BC is a vector of values to be integrated
1690  {
1691  VectorType rhsRepeated (rightHandSide.map(), Repeated);
1692 
1693  // Loop on BC identifiers
1694  for ( ID i = 0; i < boundaryCond.list_size(); ++i )
1695  {
1696  // Pointer to the i-th itdentifier in the list
1697  pId = static_cast< const BCIdentifierNatural* > ( boundaryCond[ i ] );
1698 
1699  // Number of the current boundary face
1700  ibF = pId->id();
1701 
1702  // Updating face stuff
1703  currentBdFE.update ( mesh.boundaryFacet ( ibF ), UPDATE_W_ROOT_DET_METRIC | UPDATE_NORMALS );
1704 
1705  // Loop on total DOF per Face
1706  for ( ID l = 0; l < nDofF; ++l )
1707  {
1708 
1709  gDof = pId->boundaryLocalToGlobalMap ( l );
1710 
1711  // Loop on components involved in this boundary condition
1712  for ( UInt ic = 0; ic < nComp; ++ic )
1713  {
1714  icDof = gDof + ic * totalDof + offset;
1715 
1716  // Loop on quadrature points
1717  for ( UInt iq = 0; iq < currentBdFE.nbQuadPt(); ++iq )
1718  {
1719  sum = 0.0;
1720  // data on quadrature point
1721  for ( ID m = 0; m < nDofF; ++m )
1722  {
1723  sum += boundaryCond ( pId->boundaryLocalToGlobalMap ( m ) , 0 ) * currentBdFE.phi ( m, iq );
1724  }
1725  // Adding right hand side contribution
1726  rhsRepeated[ icDof ] += sum * currentBdFE.phi ( l, iq ) * currentBdFE.normal ( ic, iq )
1727  * currentBdFE.wRootDetMetric ( iq );
1728  }
1729  }
1730  }
1731  }
1732 
1733  rhsRepeated.globalAssemble();
1734  ASSERT ( rightHandSide.mapType() == Unique , "here rightHandSide should passed as repeated, otherwise not sure of what happens at the cpu interfaces ." );
1735  rightHandSide += rhsRepeated;
1736  }
1737  break;
1738  case 2: // if the BC is a vector of values with components to be integrated
1739  {
1740  VectorType rhsRepeated (rightHandSide.map(), Repeated);
1741 
1742  // Loop on BC identifiers
1743  for ( ID i = 0; i < boundaryCond.list_size(); ++i )
1744  {
1745  // Pointer to the i-th itdentifier in the list
1746  pId = static_cast< const BCIdentifierNatural* > ( boundaryCond[ i ] );
1747 
1748  // Number of the current boundary face
1749  ibF = pId->id();
1750 
1751  // Updating face stuff
1752  currentBdFE.update ( mesh.boundaryFacet ( ibF ), UPDATE_W_ROOT_DET_METRIC );
1753 
1754  // Loop on total DOF per Face
1755  for ( ID idofF = 0; idofF < nDofF; ++idofF )
1756  {
1757 
1758  gDof = pId->boundaryLocalToGlobalMap ( idofF );
1759 
1760  // Loop on space dimensions
1761  for ( ID ic = 0; ic < nComp; ++ic )
1762  // for ( UInt ic = 0; ic < nDimensions; ++ic )
1763  {
1764  icDof = gDof + boundaryCond.component ( ic ) * totalDof + offset; //Components passed separately
1765 
1766  // Loop on quadrature points
1767  for ( UInt iq = 0; iq < currentBdFE.nbQuadPt(); ++iq )
1768  {
1769  sum = 0;
1770  // data on quadrature point
1771  for ( ID m = 0; m < nDofF; ++m )
1772  {
1773  sum += boundaryCond ( pId->boundaryLocalToGlobalMap ( m ) , boundaryCond.component ( ic ) ) * currentBdFE.phi ( m, iq ); //Components passed separatedly
1774  }
1775 
1776  // Adding right hand side contribution
1777  rhsRepeated[ icDof ] += sum * currentBdFE.phi ( idofF, iq ) *
1778  currentBdFE.wRootDetMetric ( iq );
1779  }
1780  }
1781  }
1782  }
1783  rhsRepeated.globalAssemble();
1784  ASSERT ( rightHandSide.mapType() == Unique , "here rightHandSide should passed as unique, otherwise not sure of what happens at the cpu interfaces ." );
1785  rightHandSide += rhsRepeated;
1786  }
1787  break;
1788  default:
1789  ERROR_MSG ( "This type of BCVector does not exist" );
1790  }
1791  }
1792 
1793  else
1794  {
1795  //! If BC is given under a functional form
1796 
1797  DataType x, y, z;
1798  VectorType rhsRepeated (rightHandSide.map(), Repeated);
1799 
1800  // Loop on BC identifiers
1801  for ( ID i = 0; i < boundaryCond.list_size(); ++i )
1802  {
1803  // Pointer to the i-th identifier in the list
1804  pId = static_cast< const BCIdentifierNatural* > ( boundaryCond[ i ] );
1805  // Number of the current boundary face
1806  ibF = pId->id();
1807  // Updating face stuff
1808  currentBdFE.update ( mesh.boundaryFacet ( ibF ), UPDATE_W_ROOT_DET_METRIC | UPDATE_NORMALS | UPDATE_QUAD_NODES );
1809  // Loop on total DOF per Face
1810  for ( ID idofF = 0; idofF < nDofF; ++idofF )
1811  {
1812  for ( ID j = 0; j < nComp; ++j )
1813  {
1814  //global Dof
1815  idDof = pId->boundaryLocalToGlobalMap ( idofF ) + boundaryCond.component ( j ) * totalDof + offset;
1816  // Loop on quadrature points
1817  for ( UInt iq = 0; iq < currentBdFE.nbQuadPt(); ++iq )
1818  {
1819  // quadrature point coordinates
1820  x = currentBdFE.quadPt (iq, 0);
1821  y = currentBdFE.quadPt (iq, 1);
1822  z = currentBdFE.quadPt (iq, 2);
1823 
1824  switch (boundaryCond.mode() )
1825  {
1826  case Full:
1827  rhsRepeated[ idDof ] += currentBdFE.phi ( idofF, iq ) * boundaryCond ( time, x, y, z, boundaryCond.component ( j ) ) *
1828  currentBdFE.wRootDetMetric ( iq );
1829  break;
1830  case Component:
1831  rhsRepeated[ idDof ] += currentBdFE.phi ( idofF, iq ) * boundaryCond ( time, x, y, z, boundaryCond.component ( j ) ) *
1832  currentBdFE.wRootDetMetric ( iq );
1833  break;
1834  case Normal:
1835  rhsRepeated[ idDof ] += boundaryCond ( time, x, y, z, boundaryCond.component ( j ) ) *
1836  currentBdFE.phi ( idofF, iq ) *
1837  currentBdFE.wRootDetMetric ( iq ) * currentBdFE.normal ( j, iq );
1838  break;
1839  default:
1840  ERROR_MSG ( "This BC mode is not (yet) implemented" );
1841 
1842  }
1843  }
1844  }
1845  }
1846  }
1847  rhsRepeated.globalAssemble();
1848  ASSERT ( rightHandSide.mapType() == Unique , "here rightHandSide should passed as unique, otherwise not sure of what happens at the cpu interfaces ." );
1849  rightHandSide += rhsRepeated;
1850  }
1851 } // bcNaturalManage
1852 
1853 template <typename VectorType, typename MeshType, typename DataType>
1854 void
1855 bcNaturalManageUDep ( Real (*mu) (Real time, Real x, Real y, Real z, Real u),
1856  VectorType& rightHandSide,
1857  const MeshType& mesh,
1858  const DOF& dof,
1859  const BCBase& boundaryCond,
1860  CurrentFEManifold& currentBdFE,
1861  const DataType& time,
1862  const VectorType& feVec,
1863  UInt offset )
1864 {
1865 
1866  // Number of local DOF (i.e. nodes) in this face
1867  UInt nDofF = currentBdFE.nbFEDof();
1868 
1869  // Number of total scalar Dof
1870  UInt totalDof = dof.numTotalDof();
1871 
1872  // Number of components involved in this boundary condition
1873  UInt nComp = boundaryCond.numberOfComponents();
1874 
1875  const BCIdentifierNatural* pId;
1876  ID ibF, idDof ;
1877 
1878  if ( boundaryCond.isDataAVector() )
1879  {
1880  //! If BC is given under a vectorial form
1881  ERROR_MSG ( "This type of BCVector does not exists on bc depentent on solution\n" );
1882  }
1883  else
1884  {
1885  //! If BC is given under a functional form
1886 
1887  DataType x, y, z;
1888  VectorType rhsRepeated (rightHandSide.map(), Repeated);
1889 
1890  if (nComp != 0)
1891  {
1892  ERROR_MSG ("For now bcNaturalManageUDep cannot handle non scalar solutions\n");
1893  }
1894 
1895  // Loop on BC identifiers
1896  for ( ID i = 0; i < boundaryCond.list_size(); ++i )
1897  {
1898 
1899  // Pointer to the i-th itdentifier in the list
1900  pId = static_cast< const BCIdentifierNatural* > ( boundaryCond[ i ] );
1901 
1902  // Number of the current boundary face
1903  ibF = pId->id();
1904 
1905  // Updating face stuff
1906  currentBdFE.update ( mesh.boundaryFacet ( ibF ), UPDATE_W_ROOT_DET_METRIC | UPDATE_QUAD_NODES );
1907 
1908  std::vector<Real> locU (nDofF); //assumes feVec is a vec of reals, TODO: deal with more comp
1909  Real uPt; //value in the point
1910  for (ID idofLocU = 0; idofLocU < nDofF; idofLocU++)
1911  {
1912  ID idGDofU = pId->boundaryLocalToGlobalMap (idofLocU) + boundaryCond.component ( 0 ) * totalDof + offset;
1913  locU[idofLocU] = feVec[idGDofU];
1914  }
1915 
1916 
1917  // Loop on total Dof per Face
1918  for ( ID idofF = 0; idofF < nDofF; ++idofF )
1919  {
1920  // Loop on components involved in this boundary condition
1921  for ( ID j = 0; j < nComp; ++j )
1922  {
1923 
1924  //global Dof
1925  idDof = pId->boundaryLocalToGlobalMap ( idofF ) + boundaryCond.component ( j ) * totalDof + offset;
1926 
1927  // Loop on quadrature points
1928  for (UInt l = 0; l < currentBdFE.nbQuadPt(); ++l )
1929  {
1930  // quadrature point coordinates
1931  x = currentBdFE.quadPt (l, 0);
1932  y = currentBdFE.quadPt (l, 1);
1933  z = currentBdFE.quadPt (l, 2);
1934 
1935  uPt = 0.0;
1936  for (ID idofLocU = 0; idofLocU < nDofF; idofLocU++)
1937  {
1938  uPt += locU[idofLocU] * currentBdFE.phi ( idofLocU , l );
1939  }
1940 
1941  // Adding right hand side contribution
1942  rhsRepeated[ idDof ] += currentBdFE.phi ( idofF, l ) * boundaryCond ( time, x, y, z, boundaryCond.component ( j ), uPt ) *
1943  mu (time, x, y, z, uPt) * currentBdFE.wRootDetMetric ( l );
1944  }
1945  }
1946  }
1947  }
1948 
1949  rhsRepeated.globalAssemble();
1950  ASSERT ( rightHandSide.mapType() == Unique , "here rightHandSide should passed as unique, otherwise not sure of what happens at the cpu interfaces ." );
1951  rightHandSide += rhsRepeated;
1952  }
1953 }
1954 
1955 // ===================================================
1956 // Robin BC
1957 // ===================================================
1958 
1959 template <typename MatrixType, typename VectorType, typename DataType, typename MeshType>
1960 void
1961 bcRobinManage ( MatrixType& matrix,
1962  VectorType& rightHandSide,
1963  const MeshType& mesh,
1964  const DOF& dof,
1965  const BCBase& boundaryCond,
1966  CurrentFEManifold& currentBdFE,
1967  const DataType& time,
1968  UInt offset )
1969 {
1970  bcRobinManageMatrix ( matrix, mesh, dof, boundaryCond, currentBdFE, time, offset );
1971  bcRobinManageVector ( rightHandSide, mesh, dof, boundaryCond, currentBdFE, time, offset );
1972 } //bcRobinManage
1973 
1974 
1975 template <typename MatrixType, typename DataType, typename MeshType>
1976 void
1977 bcRobinManageMatrix ( MatrixType& matrix,
1978  const MeshType& mesh,
1979  const DOF& dof,
1980  const BCBase& boundaryCond,
1981  CurrentFEManifold& currentBdFE,
1982  const DataType& time,
1983  UInt offset )
1984 {
1985  // Open the matrix if it is closed
1986  if ( matrix.matrixPtr()->Filled() )
1987  {
1988  matrix.openCrsMatrix();
1989  }
1990 
1991  // Number of local DOF in this face
1992  UInt nDofF = currentBdFE.nbFEDof();
1993 
1994  // Number of total scalar Dof
1995  UInt totalDof = dof.numTotalDof();
1996 
1997  // Number of components involved in this boundary condition
1998  UInt nComp = boundaryCond.numberOfComponents();
1999 
2000  DataType sum;
2001 
2002  const BCIdentifierNatural* pId;
2003  ID ibF, idDof, jdDof, kdDof;
2004 
2005  if ( boundaryCond.isDataAVector() )
2006  {
2007  //! If BC is given under a vectorial form
2008 
2009  //! for the moment, only one coefficient per BCvector.
2010  DataType mcoef;
2011 
2012  // Loop on BC identifiers
2013  for ( ID i = 0; i < boundaryCond.list_size(); ++i )
2014  {
2015 
2016  // Pointer to the i-th identifier in the list
2017  pId = static_cast< const BCIdentifierNatural* > ( boundaryCond[ i ] );
2018 
2019  // Number of the current boundary face
2020  ibF = pId->id();
2021 
2022  // Updating face stuff
2023  currentBdFE.update ( mesh.boundaryFacet ( ibF ), UPDATE_W_ROOT_DET_METRIC );
2024 
2025  // Loop on total DOF per Face
2026  for ( ID idofF = 0; idofF < nDofF; ++idofF )
2027  {
2028  // Loop on components invoved in this boundary condition
2029  for ( ID j = 0; j < nComp; ++j )
2030  {
2031 
2032  sum = 0;
2033 
2034  // Global Dof
2035  idDof = pId->boundaryLocalToGlobalMap ( idofF ) + boundaryCond.component ( j ) * totalDof + offset;
2036 
2037  // Loop on quadrature points
2038  for ( UInt l = 0; l < currentBdFE.nbQuadPt(); ++l )
2039  {
2040  mcoef = 0.0;
2041  for ( UInt n = 0; n < nDofF; ++n )
2042  {
2043  kdDof = pId->boundaryLocalToGlobalMap ( n );
2044  if (boundaryCond.isRobinCoeffAVector() )
2045  {
2046  mcoef += boundaryCond.robinCoeffVector ( kdDof, boundaryCond.component ( j ) ) * currentBdFE.phi ( n, l );
2047  }
2048  else
2049  {
2050  mcoef += boundaryCond.robinCoeff() * currentBdFE.phi ( n, l );
2051  }
2052  }
2053 
2054  // Contribution to the diagonal entry of the elementary boundary mass matrix
2055  sum += mcoef * currentBdFE.phi ( idofF, l ) * currentBdFE.phi ( idofF, l ) * currentBdFE.wRootDetMetric ( l );
2056  }
2057 
2058  // Assembling diagonal entry
2059  matrix.addToCoefficient ( idDof, idDof, sum );
2060  }
2061 
2062  // Upper diagonal columns of the elementary boundary mass matrix
2063  for ( ID k = idofF + 1 ; k < nDofF ; ++k )
2064  {
2065 
2066  // Loop on components invoved in this boundary condition
2067  for ( ID j = 0; j < nComp; ++j )
2068  {
2069 
2070  sum = 0;
2071 
2072  // Loop on quadrature points
2073  for ( UInt l = 0; l < currentBdFE.nbQuadPt(); ++l )
2074  {
2075  mcoef = 0.0;
2076  for ( UInt n = 0; n < nDofF; ++n)
2077  {
2078  kdDof = pId->boundaryLocalToGlobalMap ( n );
2079  if (boundaryCond.isRobinCoeffAVector() )
2080  {
2081  mcoef += boundaryCond.robinCoeffVector ( kdDof, boundaryCond.component ( j ) ) * currentBdFE.phi ( n, l );
2082  }
2083 
2084  else
2085  {
2086  mcoef += boundaryCond.robinCoeff() * currentBdFE.phi ( n, l );
2087  }
2088  }
2089 
2090  // Upper diagonal entry of the elementary boundary mass matrix
2091  sum += mcoef * currentBdFE.phi ( idofF, l ) * currentBdFE.phi ( k, l ) *
2092  currentBdFE.wRootDetMetric ( l );
2093  }
2094 
2095  // Globals DOF: row and columns
2096  idDof = pId->boundaryLocalToGlobalMap ( idofF ) + boundaryCond.component ( j ) * totalDof + offset;
2097  jdDof = pId->boundaryLocalToGlobalMap ( k ) + boundaryCond.component ( j ) * totalDof + offset;
2098 
2099  // Assembling upper entry. The boundary mass matrix is symetric
2100  matrix.addToCoefficient ( idDof, jdDof, sum );
2101  matrix.addToCoefficient ( jdDof, idDof, sum );
2102  }
2103  }
2104  }
2105  }
2106  }
2107 
2108  else
2109  {
2110  //! If BC is given under a functional form
2111 
2112  DataType x, y, z;
2113 
2114  const BCFunctionRobin* pBcF = static_cast<const BCFunctionRobin*> ( boundaryCond.pointerToFunctor() );
2115 
2116  // Loop on BC identifiers
2117  for ( ID i = 0; i < boundaryCond.list_size(); ++i )
2118  {
2119 
2120  // Pointer to the i-th identifier in the list
2121  pId = static_cast< const BCIdentifierNatural* > ( boundaryCond[ i ] );
2122 
2123  // Number of the current boundary face
2124  ibF = pId->id();
2125 
2126  // Updating face stuff
2127  currentBdFE.update ( mesh.boundaryFacet ( ibF ), UPDATE_W_ROOT_DET_METRIC | UPDATE_QUAD_NODES );
2128 
2129  // Loop on total DOF per Face
2130  for ( ID idofF = 0; idofF < nDofF; ++idofF )
2131  {
2132  // Loop on components involved in this boundary condition
2133  for ( ID j = 0; j < nComp; ++j )
2134  {
2135  sum = 0;
2136 
2137  // Global DOF (outside the quad point loop. V. Martin)
2138  idDof = pId->boundaryLocalToGlobalMap ( idofF ) + boundaryCond.component ( j ) * totalDof + offset;
2139 
2140  // Loop on quadrature points
2141  for ( UInt l = 0; l < currentBdFE.nbQuadPt(); ++l )
2142  {
2143  // quadrature point coordinates
2144  x = currentBdFE.quadPt (l, 0);
2145  y = currentBdFE.quadPt (l, 1);
2146  z = currentBdFE.quadPt (l, 2);
2147 
2148  // Contribution to the diagonal entry of the elementary boundary mass matrix
2149  sum += pBcF->coef ( time, x, y, z, boundaryCond.component (j) ) * currentBdFE.phi ( idofF, l ) * currentBdFE.phi ( idofF, l ) *
2150  currentBdFE.wRootDetMetric ( l );
2151  }
2152 
2153 
2154  // Assembling diagonal entry
2155  matrix.addToCoefficient ( idDof, idDof, sum );
2156  }
2157 
2158  // Upper diagonal columns of the elementary boundary mass matrix
2159  for ( ID k = idofF + 1 ; k < nDofF ; ++k )
2160  {
2161 
2162  // Loop on components involved in this boundary condition
2163  for ( ID j = 0; j < nComp; ++j )
2164  {
2165  sum = 0;
2166 
2167  // Loop on quadrature points
2168  for ( UInt l = 0; l < currentBdFE.nbQuadPt(); ++l )
2169  {
2170 
2171  // quadrature point coordinates
2172  x = currentBdFE.quadPt (l, 0);
2173  y = currentBdFE.quadPt (l, 1);
2174  z = currentBdFE.quadPt (l, 2);
2175 
2176  // Upper diagonal entry of the elementary boundary mass matrix
2177  sum += pBcF->coef ( time, x, y, z, boundaryCond.component ( j ) ) * currentBdFE.phi ( idofF, l ) * currentBdFE.phi ( k, l ) *
2178  currentBdFE.wRootDetMetric ( l );
2179  }
2180 
2181  // Globals DOF: row and columns
2182  idDof = pId->boundaryLocalToGlobalMap ( idofF ) + boundaryCond.component ( j ) * totalDof + offset;
2183  jdDof = pId->boundaryLocalToGlobalMap ( k ) + boundaryCond.component ( j ) * totalDof + offset;
2184 
2185  // Assembling upper entry. The boundary mas matrix is symetric
2186  matrix.addToCoefficient ( idDof, jdDof, sum );
2187  matrix.addToCoefficient ( jdDof, idDof, sum );
2188  }
2189  }
2190  }
2191  }
2192  }
2193 } //bcRobinManageMatrix
2194 
2195 template <typename VectorType, typename DataType, typename MeshType>
2196 void
2197 bcRobinManageVector ( VectorType& rightHandSide,
2198  const MeshType& mesh,
2199  const DOF& dof,
2200  const BCBase& boundaryCond,
2201  CurrentFEManifold& currentBdFE,
2202  const DataType& time,
2203  UInt offset )
2204 {
2205 
2206  // Number of local DOF in this face
2207  UInt nDofF = currentBdFE.nbFEDof();
2208 
2209  // Number of total scalar Dof
2210  UInt totalDof = dof.numTotalDof();
2211 
2212  // Number of components involved in this boundary condition
2213  UInt nComp = boundaryCond.numberOfComponents();
2214 
2215  const BCIdentifierNatural* pId;
2216  ID ibF, idDof, kdDof;
2217 
2218  if ( boundaryCond.isDataAVector() )
2219  {
2220  //! If BC is given under a vectorial form
2221 
2222  VectorType rhsRepeated (rightHandSide.map(), Repeated);
2223 
2224  //! Defining the coefficients
2225  DataType mbcb;
2226 
2227  // Loop on BC identifiers
2228  for ( ID i = 0; i < boundaryCond.list_size(); ++i )
2229  {
2230 
2231  // Pointer to the i-th identifier in the list
2232  pId = static_cast< const BCIdentifierNatural* > ( boundaryCond[ i ] );
2233 
2234  // Number of the current boundary face
2235  ibF = pId->id();
2236 
2237  // Updating face stuff
2238  currentBdFE.update ( mesh.boundaryFacet ( ibF ), UPDATE_W_ROOT_DET_METRIC );
2239 
2240  // Loop on total DOF per Face
2241  for ( ID idofF = 0; idofF < nDofF; ++idofF )
2242  {
2243  // Loop on components invoved in this boundary condition
2244  for ( ID j = 0; j < nComp; ++j )
2245  {
2246  // Global Dof
2247  idDof = pId->boundaryLocalToGlobalMap ( idofF ) + boundaryCond.component ( j ) * totalDof + offset;
2248 
2249  // Loop on quadrature points
2250  for ( UInt l = 0; l < currentBdFE.nbQuadPt(); ++l )
2251  {
2252  mbcb = 0.0;
2253  for ( UInt n = 0; n < nDofF; ++n )
2254  {
2255  kdDof = pId->boundaryLocalToGlobalMap ( n );
2256 
2257  if ( boundaryCond.isBetaCoeffAVector() )
2258  mbcb += boundaryCond.betaCoeffVector ( kdDof, boundaryCond.component ( j ) )
2259  * boundaryCond ( kdDof, boundaryCond.component ( j ) ) * currentBdFE.phi ( n, l );
2260  else
2261  {
2262  mbcb += boundaryCond.betaCoeff() * boundaryCond ( kdDof, boundaryCond.component ( j ) ) * currentBdFE.phi ( n, l );
2263  }
2264  }
2265 
2266  // Adding right hand side contribution
2267  rhsRepeated[ idDof ] += currentBdFE.phi ( idofF, l ) * mbcb * currentBdFE.wRootDetMetric ( l );
2268  }
2269  }
2270  }
2271  }
2272  rhsRepeated.globalAssemble();
2273  ASSERT ( rightHandSide.mapType() == Unique, "here rightHandSide should passed as unique, otherwise not sure of what happens at the cpu interfaces ." );
2274  rightHandSide += rhsRepeated;
2275  }
2276 
2277  else
2278  {
2279  //! If BC is given under a functional form
2280 
2281  VectorType rhsRepeated (rightHandSide.map(), Repeated);
2282 
2283  DataType x, y, z;
2284 
2285  // Loop on BC identifiers
2286  for ( ID i = 0; i < boundaryCond.list_size(); ++i )
2287  {
2288 
2289  // Pointer to the i-th identifier in the list
2290  pId = static_cast< const BCIdentifierNatural* > ( boundaryCond[ i ] );
2291 
2292  // Number of the current boundary face
2293  ibF = pId->id();
2294 
2295  // Updating face stuff
2296  currentBdFE.update ( mesh.boundaryFacet ( ibF ), UPDATE_W_ROOT_DET_METRIC | UPDATE_QUAD_NODES );
2297 
2298  // Loop on total DOF per Face
2299  for ( ID idofF = 0; idofF < nDofF; ++idofF )
2300  {
2301  // Loop on components involved in this boundary condition
2302  for ( ID j = 0; j < nComp; ++j )
2303  {
2304 
2305  // Global DOF (outside the quad point loop. V. Martin)
2306  idDof = pId->boundaryLocalToGlobalMap ( idofF ) + boundaryCond.component ( j ) * totalDof + offset;
2307 
2308  // Loop on quadrature points
2309  for ( UInt l = 0; l < currentBdFE.nbQuadPt(); ++l )
2310  {
2311  // quadrature point coordinates
2312  x = currentBdFE.quadPt (l, 0);
2313  y = currentBdFE.quadPt (l, 1);
2314  z = currentBdFE.quadPt (l, 2);
2315 
2316  // Adding right hand side contribution
2317  rhsRepeated[ idDof ] += currentBdFE.phi ( idofF, l ) * boundaryCond ( time, x, y, z, boundaryCond.component ( j ) ) *
2318  currentBdFE.wRootDetMetric ( l );
2319  }
2320  }
2321  }
2322  }
2323  rhsRepeated.globalAssemble();
2324  ASSERT ( rightHandSide.mapType() == Unique, "here rightHandSide should passed as unique, otherwise not sure of what happens at the cpu interfaces ." );
2325  rightHandSide += rhsRepeated;
2326  }
2327 } //bcRobinManageVector
2328 
2329 
2330 
2331 
2332 template <typename VectorType, typename DataType, typename MeshType>
2333 void bcRobinManageResidual ( VectorType& residual,
2334  VectorType& rightHandSide,
2335  const VectorType& solution, //solution must not be repeated
2336  const MeshType& mesh,
2337  const DOF& dof,
2338  const BCBase& boundaryCond,
2339  CurrentFEManifold& currentBdFE,
2340  const DataType& time,
2341  UInt offset )
2342 {
2343 
2344  if (solution.mapType() == Repeated)
2345  {
2346  std::cout << "pass me a non-repeated solution" << std::endl;
2347  VectorType uniqueSolution (solution, Unique, Zero);
2348  bcRobinManageResidual ( residual,
2349  rightHandSide,
2350  uniqueSolution,
2351  mesh,
2352  dof,
2353  boundaryCond,
2354  currentBdFE,
2355  time,
2356  offset );
2357  return;
2358  }
2359 
2360  MatrixEpetra<Real> matrix (solution.map() );
2361  bcRobinManage ( matrix, rightHandSide, mesh, dof, boundaryCond, currentBdFE, time, offset );
2362  matrix.globalAssemble();
2363  residual += matrix * solution;
2364 } //bcRobinManageResidual
2365 
2366 
2367 template <typename VectorType, typename DataType, typename MeshType>
2368 void bcResistanceManageResidual ( VectorType& residual,
2369  VectorType& rightHandSide,
2370  const VectorType& solution, //solution must not be repeated
2371  const MeshType& mesh,
2372  const DOF& dof,
2373  const BCBase& boundaryCond,
2374  CurrentFEManifold& currentBdFE,
2375  const DataType& time,
2376  UInt offset )
2377 {
2378 
2379  if (solution.mapType() == Repeated)
2380  {
2381  std::cout << "pass me a non-repeated solution" << std::endl;
2382  VectorType uniqueSolution (solution, Unique, Zero);
2383  bcResistanceManageResidual ( residual,
2384  rightHandSide,
2385  uniqueSolution,
2386  mesh,
2387  dof,
2388  boundaryCond,
2389  currentBdFE,
2390  time,
2391  offset );
2392  return;
2393  }
2394 
2395  MatrixEpetra<Real> matrix (solution.map() );
2396  bcResistanceManage ( matrix, rightHandSide, mesh, dof, boundaryCond, currentBdFE, time, offset );
2397  matrix.globalAssemble();
2398  residual += matrix * solution;
2399 } //bcRobinManageResidual
2400 
2401 
2402 
2403 
2404 
2405 
2406 // ===================================================
2407 // Flux BC
2408 // ===================================================
2409 
2410 
2411 template < typename MatrixType,
2412  typename VectorType,
2413  typename MeshType,
2414  typename DataType >
2415 void
2416 bcFluxManage ( MatrixType& matrix,
2417  VectorType& rightHandSide,
2418  const MeshType& mesh,
2419  const DOF& dof,
2420  const BCBase& boundaryCond,
2421  CurrentFEManifold& currentBdFE,
2422  const DataType& time,
2423  UInt offset)
2424 
2425 {
2426  bcFluxManageVector (rightHandSide, boundaryCond, time, offset);
2427  bcFluxManageMatrix (matrix, mesh, dof, boundaryCond, currentBdFE, time, offset);
2428 } //bcFluxManage
2429 
2430 
2431 template < typename VectorType,
2432  typename DataType >
2433 void
2435  VectorType& rightHandSide,
2436  const BCBase& boundaryCond,
2437  const DataType& time,
2438  UInt offset)
2439 
2440 {
2441  rightHandSide.setCoefficient (offset, boundaryCond (time, 0., 0., 0., 0) );
2442 } //bcFluxManageVector
2443 
2444 
2445 template < typename MatrixType,
2446  typename MeshType,
2447  typename DataType >
2448 void
2449 bcFluxManageMatrix ( MatrixType& matrix,
2450  const MeshType& mesh,
2451  const DOF& dof,
2452  const BCBase& boundaryCond,
2453  CurrentFEManifold& currentBdFE,
2454  const DataType& /*time*/,
2455  UInt offset )
2456 {
2457  if ( matrix.matrixPtr()->Filled() )
2458  {
2459  matrix.openCrsMatrix();
2460  }
2461 
2462  // Number of local DOF in this face
2463  UInt nDofF = currentBdFE.nbFEDof();
2464 
2465  // Number of total scalar Dof
2466  UInt totalDof = dof.numTotalDof();
2467 
2468  // Number of components involved in this boundary condition
2469  UInt nComp = boundaryCond.numberOfComponents();
2470 
2471  DataType sum;
2472 
2473  const BCIdentifierNatural* pId;
2474  ID ibF, idDof, jdDof/*, kdDof*/;
2475 
2476  if ( !boundaryCond.isDataAVector() )
2477  {
2478  for ( ID i = 0; i < boundaryCond.list_size(); ++i )
2479  {
2480  pId = static_cast< const BCIdentifierNatural* > ( boundaryCond[ i ] );
2481 
2482  // Number of the current boundary face
2483  ibF = pId->id();
2484  // Updating face stuff
2485  currentBdFE.update ( mesh.boundaryFacet ( ibF ), UPDATE_W_ROOT_DET_METRIC | UPDATE_NORMALS );
2486 
2487  for ( ID idofF = 0; idofF < nDofF; ++idofF )
2488  {
2489  for ( UInt ic = 0; ic < nComp; ++ic)
2490  {
2491  idDof = pId->boundaryLocalToGlobalMap ( idofF ) + ic * totalDof;
2492 
2493  sum = 0.;
2494  for ( UInt iq = 0; iq < currentBdFE.nbQuadPt(); ++iq )
2495  {
2496  sum += currentBdFE.phi ( idofF, iq ) *
2497  currentBdFE.normal (ic , iq) *
2498  currentBdFE.wRootDetMetric (iq);
2499  }
2500 
2501  jdDof = offset;
2502 
2503  matrix.addToCoefficient ( idDof , jdDof , sum );
2504  matrix.addToCoefficient ( jdDof , idDof , sum );
2505  }
2506  }
2507  }
2508  }
2509 } // bcFluxManageMatrix
2510 
2511 template < typename VectorType,
2512  typename MeshType,
2513  typename DataType >
2514 void
2515 bcFluxManageResidual ( VectorType& residual,
2516  VectorType& rightHandSide,
2517  const VectorType& solution,
2518  const MeshType& mesh,
2519  const DOF& dof,
2520  const BCBase& boundaryCond,
2521  CurrentFEManifold& currentBdFE,
2522  const DataType& time,
2523  UInt offset )
2524 {
2525  if (solution.mapType() == Repeated)
2526  {
2527  std::cout << "pass me a non-repeated solution" << std::endl;
2528  VectorType uniqueSolution (solution, Unique, Zero);
2529  bcFluxManageResidual ( residual,
2530  rightHandSide,
2531  uniqueSolution,
2532  mesh,
2533  dof,
2534  boundaryCond,
2535  currentBdFE,
2536  time,
2537  offset );
2538  return;
2539  }
2540  MatrixEpetra<Real> matrix (solution.map() );
2541  bcFluxManage (matrix, rightHandSide, mesh, dof, boundaryCond, currentBdFE, time, offset );
2542  matrix.globalAssemble();
2543  residual += matrix * solution;
2544 }
2545 
2546 
2547 
2548 template <typename MatrixType, typename VectorType, typename DataType, typename MeshType>
2549 void
2550 bcResistanceManage ( MatrixType& matrix,
2551  VectorType& rightHandSide,
2552  const MeshType& mesh,
2553  const DOF& dof,
2554  const BCBase& boundaryCond,
2555  CurrentFEManifold& currentBdFE,
2556  const DataType& time,
2557  UInt offset )
2558 {
2559  bcResistanceManageMatrix ( matrix, mesh, dof, boundaryCond, currentBdFE, time, offset );
2560  bcResistanceManageVector ( rightHandSide, mesh, dof, boundaryCond, currentBdFE, time, offset );
2561 } //bcResistanceManage
2562 
2563 template <typename VectorType, typename DataType, typename MeshType>
2564 void
2565 bcResistanceManageVector ( VectorType& rightHandSide,
2566  const MeshType& mesh,
2567  const DOF& dof,
2568  const BCBase& boundaryCond,
2569  CurrentFEManifold& currentBdFE,
2570  const DataType& /*time*/,
2571  UInt offset )
2572 {
2573  // Number of local DOF in this face
2574  UInt nDofF = currentBdFE.nbFEDof();
2575 
2576  // Number of total scalar Dof
2577  UInt totalDof = dof.numTotalDof();
2578 
2579  // Number of components involved in this boundary condition
2580  UInt nComp = boundaryCond.numberOfComponents();
2581 
2582  std::set<ID> resistanceDofs;
2583 
2584  const BCIdentifierNatural* pId;
2585  ID ibF, idDof, kdDof;
2586 
2587  if ( boundaryCond.isDataAVector() )
2588  {
2589  VectorType rhsRepeated (rightHandSide.map(), Repeated);
2590 
2591  DataType mbcb;
2592 
2593  // Loop on BC identifiers
2594  for ( ID i = 0; i < boundaryCond.list_size(); ++i )
2595  {
2596  // Pointer to the i-th identifier in the list
2597  pId = static_cast< const BCIdentifierNatural* > ( boundaryCond[ i ] );
2598 
2599  // Number of the current boundary face
2600  ibF = pId->id();
2601 
2602  currentBdFE.update ( mesh.boundaryFacet ( ibF ), UPDATE_W_ROOT_DET_METRIC | UPDATE_NORMALS );
2603 
2604  // Loop on total DOF per Face
2605  for ( ID idofF = 0; idofF < nDofF; ++idofF )
2606  {
2607  resistanceDofs.insert ( pId->boundaryLocalToGlobalMap ( idofF ) );
2608 
2609  // Loop on components involved in this boundary condition
2610  for ( ID j = 0; j < nComp; ++j )
2611  {
2612  idDof = pId->boundaryLocalToGlobalMap ( idofF ) + boundaryCond.component ( j ) * totalDof + offset;
2613 
2614  // Loop on quadrature points
2615  for ( UInt iq = 0; iq < currentBdFE.nbQuadPt(); ++iq )
2616  {
2617  mbcb = 0;
2618 
2619  // data on quadrature point
2620  for ( ID n = 0; n < nDofF; ++n)
2621  {
2622  kdDof = pId->boundaryLocalToGlobalMap ( n );
2623  mbcb += boundaryCond ( kdDof, boundaryCond.component ( j ) ) * currentBdFE.phi ( n, iq ) ;
2624  }
2625 
2626  rhsRepeated[ idDof ] += mbcb * currentBdFE.phi ( idofF, iq ) * currentBdFE.normal ( j , iq ) *
2627  currentBdFE.wRootDetMetric ( iq );
2628 
2629  }
2630  }
2631  }
2632  }
2633  rhsRepeated.globalAssemble();
2634  ASSERT ( rightHandSide.mapType() == Unique, "here rightHandSide should passed as unique, otherwise not sure of what happens at the cpu interfaces ." );
2635  rightHandSide += rhsRepeated;
2636  }
2637  else
2638  {
2639  ERROR_MSG ( "This BC type is not yet implemented" );
2640  }
2641 } //bcResistanceManageVector
2642 
2643 template <typename MatrixType, typename DataType, typename MeshType>
2644 void
2645 bcResistanceManageMatrix ( MatrixType& matrix,
2646  const MeshType& mesh,
2647  const DOF& dof,
2648  const BCBase& boundaryCond,
2649  CurrentFEManifold& currentBdFE,
2650  const DataType& /*time*/,
2651  UInt offset )
2652 {
2653  // Open the matrix if it is closed:
2654  if ( matrix.matrixPtr()->Filled() )
2655  {
2656  matrix.openCrsMatrix();
2657  }
2658 
2659  // Number of local DOF in this face
2660  UInt nDofF = currentBdFE.nbFEDof();
2661 
2662  // Number of total scalar Dof
2663  UInt totalDof = dof.numTotalDof();
2664 
2665  // Number of components involved in this boundary condition
2666  UInt nComp = boundaryCond.numberOfComponents();
2667 
2668  std::set<ID> resistanceDofs;
2669 
2670  const BCIdentifierNatural* pId;
2671  ID ibF, idDof, jdDof;
2672 
2673  if ( boundaryCond.isDataAVector() )
2674  {
2675  //auxiliary vector
2677  vv *= 0.;
2678 
2679  // Loop on BC identifiers
2680  for ( ID i = 0; i < boundaryCond.list_size(); ++i )
2681  {
2682  // Pointer to the i-th identifier in the list
2683  pId = static_cast< const BCIdentifierNatural* > ( boundaryCond[ i ] );
2684 
2685  // Number of the current boundary face
2686  ibF = pId->id();
2687 
2688  currentBdFE.update ( mesh.boundaryFacet ( ibF ), UPDATE_W_ROOT_DET_METRIC | UPDATE_NORMALS );
2689 
2690  // Loop on total DOF per Face
2691  for ( ID idofF = 0; idofF < nDofF; ++idofF )
2692  {
2693  resistanceDofs.insert ( pId->boundaryLocalToGlobalMap ( idofF ) );
2694 
2695  // Loop on components involved in this boundary condition
2696  for ( ID j = 0; j < nComp; ++j )
2697  {
2698  idDof = pId->boundaryLocalToGlobalMap ( idofF ) + boundaryCond.component ( j ) * totalDof + offset;
2699 
2700  // std::cout << "\nDOF " << idDof << " is involved in Resistance BC" << std::endl;
2701 
2702  // Loop on quadrature points
2703  for ( UInt iq = 0; iq < currentBdFE.nbQuadPt(); ++iq )
2704  {
2705  vv[idDof] += currentBdFE.phi ( idofF, iq ) * currentBdFE.normal ( j , iq ) * currentBdFE.wRootDetMetric ( iq );
2706  }
2707  }
2708  }
2709  }
2710 
2711  // this vector now contains the values needed to modify the matrix
2713 
2714  // I want it on a unique processor (the root processor) that will take care of modifying
2715  // the matrix on the LHS
2716  VectorEpetra vvReduced ( vv, 0 );
2717 
2718  // I need to tell the root processor what are the IDs of the DOFs on the "resistance" boundary.
2719  // Each processor finds numMyResistanceDofs in its own portion of the mesh
2720  Int numMyResistanceDofs ( resistanceDofs.size() );
2721  // Summing together the numMyResistanceDofs values, I obtain the global number of
2722  // resistance DOFs, **including repeated DOFs**
2723  Int numGlobalResistanceDofs (0);
2724  vv.map().comm().SumAll (&numMyResistanceDofs, &numGlobalResistanceDofs, 1);
2725 
2726  // I need to share the list of resistance DOFs, via MPI calls. I will need vectors (arrays), not sets.
2727  // Each process will store its resistance DOFs in a vector
2728  std::vector<Int> myResistanceDofs ( numGlobalResistanceDofs, -1 );
2729  // And each processor will receive the other processors' resistance DOFs in a gathered vector
2730  // i.e. an "array of arrays", the i-th sub-array being a copy of myResistanceDofs from processor i
2731  std::vector<Int> globalResistanceDofs ( numGlobalResistanceDofs * vv.map().comm().NumProc(), 0 );
2732 
2733  // Fill myResistanceDofs with the actual DOF IDs (only the first numMyResistanceDofs will be nonzero)
2734  UInt iCount (0);
2735  for ( std::set<ID>::iterator iDofIt = resistanceDofs.begin();
2736  iDofIt != resistanceDofs.end(); ++iDofIt, ++iCount )
2737  {
2738  myResistanceDofs[iCount] = *iDofIt;
2739  }
2740 
2741  // Gather the lists of resistance DOF IDs from all processors
2742  vv.map().comm().GatherAll (&myResistanceDofs[0], &globalResistanceDofs[0], numGlobalResistanceDofs);
2743 
2744  // Create a unique list of IDs: here I make use of a set
2745  std::set<ID> globalResistanceDofSet;
2746  for ( Int iDof = 0; iDof < numGlobalResistanceDofs * vv.map().comm().NumProc(); ++iDof )
2747  {
2748  if ( globalResistanceDofs[iDof] > -1 )
2749  {
2750  globalResistanceDofSet.insert ( globalResistanceDofs[iDof] );
2751  // std::cout << "\n(after gathering) DOF " << globalResistanceDofs[iDof] << std::endl;
2752  }
2753  }
2754  // std::cout << "\n(after gathering) number of DOFs = " << globalResistanceDofs.size() << std::endl;
2755 
2756  // Only the root processor has the needed values to modify the matrix
2757  if ( ! vv.map().comm().MyPID() )
2758  {
2759  for ( std::set<ID>::iterator iDofIt = globalResistanceDofSet.begin();
2760  iDofIt != globalResistanceDofSet.end(); ++iDofIt )
2761  {
2762  for ( UInt iComp = 0; iComp < nComp; ++iComp )
2763  {
2764  idDof = *iDofIt + boundaryCond.component ( iComp ) * totalDof + offset;
2765  for ( std::set<ID>::iterator jDofIt = globalResistanceDofSet.begin();
2766  jDofIt != globalResistanceDofSet.end(); ++jDofIt )
2767  {
2768  for ( UInt jComp = 0; jComp < nComp; ++jComp )
2769  {
2770  jdDof = *jDofIt + boundaryCond.component ( jComp ) * totalDof + offset;
2771 
2772  matrix.addToCoefficient ( idDof, jdDof, boundaryCond.resistanceCoeff() *
2773  vvReduced[idDof] * vvReduced[jdDof] );
2774  }
2775  }
2776  }
2777  }
2778  }
2779  }
2780  else
2781  {
2782  ERROR_MSG ( "This BC type is not yet implemented" );
2783  }
2784 
2785 } //bcResistanceManageMatrix
2786 
2787 } // end of namespace LifeV
2788 #endif
void bcEssentialManageUDep(MatrixType &matrix, VectorType &rightHandSide, const MeshType &, const DOF &dof, const BCBase &boundaryCond, const CurrentFEManifold &, const DataType &diagonalizeCoef, const DataType &time, const VectorType &feVec, UInt offset=0)
Prescribe Essential boundary conditions. Case in which the user defined function depends on the FE ve...
Definition: BCManage.hpp:1286
const flag_Type UPDATE_NORMALS(UPDATE_ONLY_NORMALS|UPDATE_ONLY_TANGENTS|UPDATE_ONLY_CELL_NODES)
VectorEpetra - The Epetra Vector format Wrapper.
const BCBase & operator[](const ID &) const
Extract a BC in the list, const.
Definition: BCHandler.cpp:98
void bcRobinManageVector(VectorType &rightHandSide, const MeshType &mesh, const DOF &dof, const BCBase &boundaryCond, CurrentFEManifold &currentBdFE, const DataType &time, UInt offset)
Prescribe Robin boundary condition only on the rightHandSide.
Definition: BCManage.hpp:2197
bcType_Type type() const
Returns the boundary condition type.
Definition: BCBase.cpp:717
void bcFluxManage(MatrixType &matrix, VectorType &rightHandSide, const MeshType &mesh, const DOF &dof, const BCBase &boundaryCond, CurrentFEManifold &currentBdFE, const DataType &time, UInt offset)
Prescribe Flux boundary condition only on the matrix.
Definition: BCManage.hpp:2416
void bcManageVector(VectorType &rightHandSide, FESpace< Mesh, MapEpetra > &feSpace, const BCHandler &bcHandler, const DataType &time, const DataType &diagonalizeCoef)
Prescribe boundary conditions. Case in which only the right hand side is modified.
Definition: BCManage.hpp:1140
void bcRobinManageResidual(VectorType &residual, VectorType &rightHandSide, const VectorType &solution, const MeshType &mesh, const DOF &dof, const BCBase &boundaryCond, CurrentFEManifold &currentBdFE, const DataType &time, UInt offset)
Prescribe Robin boundary conditions. Case in which only the residual is available.
Definition: BCManage.hpp:2333
const Real & y() const
Recovering the node&#39;s y-coordinate.
void bcResistanceManageMatrix(MatrixType &matrix, const MeshType &mesh, const DOF &dof, const BCBase &boundaryCond, CurrentFEManifold &currentBdFE, const DataType &, UInt offset)
Definition: BCManage.hpp:2645
const Real & z() const
Recovering the node&#39;s z-coordinate.
A class for a finite element on a manifold.
void importFromHDF5(std::string const &fileName, std::string const &matrixName="matrix")
Read a matrix from a HDF5 (.h5) file.
void bcManage(Real(*mu)(Real time, Real x, Real y, Real z, Real u), MatrixType &matrix, VectorType &rightHandSide, const MeshType &mesh, const DOF &dof, const BCHandler &bcHandler, CurrentFEManifold &currentBdFE, const DataType diagonalizeCoef, const DataType &time, VectorType &feVec)
Prescribe boundary conditions. Case in which the user defined function depends on the FE vector feVec...
Definition: BCManage.hpp:856
void bcEssentialManage(MatrixType &matrix, VectorType &rightHandSide, const MeshType &, const DOF &dof, const BCBase &boundaryCond, const CurrentFEManifold &, const DataType &diagonalizeCoef, const DataType &time, UInt offset)
Prescribe Essential boundary conditions. Case in which the user defined function depends on the FE ve...
Definition: BCManage.hpp:1198
void bcEssentialManageMatrix(MatrixType &matrix, const DOF &dof, const BCBase &boundaryCond, const DataType &diagonalizeCoef, UInt offset)
Prescribe Essential boundary conditions diagonalizing the matrix.
Definition: BCManage.hpp:1361
void bcManageMatrix(MatrixType &matrix, const MeshType &mesh, const DOF &dof, const BCHandler &bcHandler, CurrentFEManifold &currentBdFE, const DataType &diagonalizeCoef, const DataType &time=0)
Prescribe boundary conditions. Case in which only the matrix is modified.
Definition: BCManage.hpp:947
void bcEssentialManageRhs(VectorType &rightHandSide, const DOF &dof, const BCHandler &bcHandler, const DataType &diagonalizeCoef, const DataType &time)
Prescribe all the Essential boundary conditions on the right hand side and forgetting about the other...
Definition: BCManage.hpp:1423
BCHandler - class for handling boundary conditions.
Definition: BCHandler.hpp:100
const vector_Type & rhsVector() const
Return the underlying data structure for the RHS vector.
Definition: BCVector.hpp:183
int32_type Int
Generic integer data.
Definition: LifeV.hpp:188
void bcRobinManage(MatrixType &matrix, VectorType &rightHandSide, const MeshType &mesh, const DOF &dof, const BCBase &boundaryCond, CurrentFEManifold &currentBdFE, const DataType &time, UInt offset)
Prescribe Robin boundary condition.
Definition: BCManage.hpp:1961
void bcManageResidual(VectorType &res, VectorType &rhs, const VectorType &sol, const MeshType &mesh, const DOF &dof, const BCHandler &bcHandler, CurrentFEManifold &currentBdFE, const DataType &time, const DataType &diagonalizeCoef)
Definition: BCManage.hpp:1088
bool isDataAVector() const
Returns True if a FE BCVector has been provided to the class, False otherwise.
Definition: BCBase.cpp:774
VectorEpetra(const MapEpetra &map, const MapEpetraType &mapType=Unique, const combineMode_Type combineMode=Add)
Constructor - Using Maps.
void bcNaturalManage(VectorType &rightHandSide, const MeshType &mesh, const DOF &dof, const BCBase &boundaryCond, CurrentFEManifold &currentBdFE, const DataType &time, UInt offset)
Prescribe Natural boundary condition.
Definition: BCManage.hpp:1625
void updateInverseJacobian(const UInt &iQuadPt)
BCFunctionRobin - class that holds the function used for prescribing Robin boundary conditions...
Definition: BCFunction.hpp:231
BCManageNormal - class for handling normal essential boundary conditions.
void bcFluxManageVector(VectorType &rightHandSide, const BCBase &boundaryCond, const DataType &time, UInt offset)
Prescribe Flux boundary condition only on the right hand side.
Definition: BCManage.hpp:2434
void bcEssentialManageVector(VectorType &rightHandSide, const DOF &dof, const BCBase &boundaryCond, const DataType &time, const DataType &diagonalizeCoef, UInt offset)
Prescribe Essential boundary conditions on the right hand side.
Definition: BCManage.hpp:1405
Int globalAssemble()
Assemble the vector.
UInt numberOfComponents() const
Returns the number of components involved in this boundary condition.
Definition: BCBase.cpp:727
#define ERROR_MSG(A)
Definition: LifeAssert.hpp:69
void bcResistanceManage(MatrixType &matrix, VectorType &rightHandSide, const MeshType &mesh, const DOF &dof, const BCBase &boundaryCond, CurrentFEManifold &currentBdFE, const DataType &, UInt offset)
Prescribe Resistance boundary condition.
Definition: BCManage.hpp:2550
#define ASSERT(X, A)
Definition: LifeAssert.hpp:90
uint32_type ID
IDs.
Definition: LifeV.hpp:194
UInt offset() const
Definition: BCHandler.hpp:444
bcMode_Type mode() const
Returns the boundary condition mode.
Definition: BCBase.cpp:722
void bcRobinManageMatrix(MatrixType &matrix, const MeshType &mesh, const DOF &dof, const BCBase &boundaryCond, CurrentFEManifold &currentBdFE, const DataType &time, UInt offset)
Prescribe Robin boundary condition only on the matrix.
Definition: BCManage.hpp:1977
const int & offset() const
Returns the offset associated to this boundary condition.
Definition: BCBase.hpp:579
const MapEpetra & map() const
Return the MapEpetra of the vector.
void bcManageMtimeUDep(MatrixType &matrix, const DOF &dof, const BCHandler &bcHandler, const DataType diagonalizeCoef)
! Prescribe Essential boundary conditions.
BCVectorInterface - class that holds the FE vectors used for prescribing boundary conditions on Inter...
Definition: BCVector.hpp:475
void bcManageRhs(VectorType &rightHandSide, FESpace< Mesh, MapEpetra > &feSpace, const BCHandler &bcHandler, const DataType &diagonalizeCoef, const DataType &time)
Prescribe boundary conditions. Case in which only the right hand side is modified.
Definition: BCManage.hpp:1155
void bcManageVector(VectorType &rightHandSide, const MeshType &mesh, const DOF &dof, const BCHandler &bcHandler, CurrentFEManifold &currentBdFE, const DataType &time, const DataType &diagonalizeCoef)
Prescribe boundary conditions. Case in which only the right hand side is modified.
Definition: BCManage.hpp:1023
void bcResistanceManageVector(VectorType &rightHandSide, const MeshType &mesh, const DOF &dof, const BCBase &boundaryCond, CurrentFEManifold &currentBdFE, const DataType &, UInt offset)
Definition: BCManage.hpp:2565
const UInt & numTotalDof() const
The total number of Dof.
Definition: DOF.hpp:177
bool isUDep() const
Returns True if the BCBase is based on a BCFunctionUDepBase function, False otherwise.
Definition: BCBase.cpp:784
ID boundaryLocalToGlobalMap(const ID &i) const
Return the global DOF corresponding tho the i-th local DOF in the face.
void bcManage(MatrixType &matrix, VectorType &rightHandSide, MeshType const &mesh, DOF const &dof, BCHandler const &bcHandler, CurrentFEManifold &currentBdFE, DataType const &diagonalizeCoef, DataType const &time=0)
Prescribe boundary conditions.
Definition: BCManage.hpp:769
double Real
Generic real data.
Definition: LifeV.hpp:175
void bcResistanceManageResidual(VectorType &residual, VectorType &rightHandSide, const VectorType &solution, const MeshType &mesh, const DOF &dof, const BCBase &boundaryCond, CurrentFEManifold &currentBdFE, const DataType &time, UInt offset)
Paolo Tricerri/////////////////////.
Definition: BCManage.hpp:2368
VectorEpetra(const VectorEpetra &vector, const Int &reduceToProc)
Copy constructor.
const flag_Type UPDATE_W_ROOT_DET_METRIC(UPDATE_ONLY_W_ROOT_DET_METRIC|UPDATE_METRIC|UPDATE_ONLY_DET_METRIC)
const BCIdentifierBase * operator[](const ID &i) const
Returns a pointer to the (i)-th element of the list of identifiers.
Definition: BCBase.cpp:638
const ID & id() const
Returns the ID of the BCIdentifier.
const flag_Type UPDATE_QUAD_NODES(UPDATE_ONLY_CELL_NODES|UPDATE_ONLY_QUAD_NODES)
BCIdentifierEssential - BCIdentifier for implementing Essential Boundary Conditions.
const Real & x() const
Recovering the node&#39;s x-coordinate.
UInt type() const
Return the type of conditions (see BCVector class description)
Definition: BCVector.hpp:197
#define LIFEV_DEPRECATED(func)
Definition: LifeV.hpp:117
void bcManageRhs(VectorType &rightHandSide, const MeshType &mesh, const DOF &dof, const BCHandler &bcHandler, CurrentFEManifold &currentBdFE, const DataType &diagonalizeCoef, const DataType &time)
Prescribe boundary conditions. Case in which only the right hand side is modified.
Definition: BCManage.hpp:1042
ID component(const ID i) const
Returns the index of the component of the solution associated to the iComponent-th component prescrib...
Definition: BCBase.cpp:466
VectorEpetra & operator*=(const data_type &scalar)
Multiplication operator.
void bcEssentialManageResidual(VectorType &res, VectorType &rhs, const VectorType &sol, const DOF &dof, const BCBase &boundaryCond, const DataType &time, const DataType &diagonalizeCoef, UInt offset)
Prescribe essential boundary conditions. Case in which only the residual is available.
Definition: BCManage.hpp:1531
const BCFunctionBase * pointerToFunctor() const
Returns a pointer to the BCFunctionBase object.
Definition: BCBase.cpp:528
void bcNaturalManageUDep(Real(*mu)(Real time, Real x, Real y, Real z, Real u), VectorType &rightHandSide, const MeshType &mesh, const DOF &dof, const BCBase &boundaryCond, CurrentFEManifold &currentBdFE, const DataType &time, const VectorType &feVec, UInt offset)
Prescribe Natural boundary condition. Case in which the user defined function depends on the FE vecto...
Definition: BCManage.hpp:1855
BCIdentifierNatural - Idenifier for Natural and Robin Boundary Condiions.
UInt size() const
Number of the stored boundary conditions.
Definition: BCHandler.hpp:482
void bcFluxManageResidual(VectorType &residual, VectorType &rightHandSide, const VectorType &solution, const MeshType &mesh, const DOF &dof, const BCBase &boundaryCond, CurrentFEManifold &currentBdFE, const DataType &, UInt offset)
Prescribe Flux boundary conditions. Case in which only the residual is available. ...
Definition: BCManage.hpp:2515
UInt list_size() const
Returns the size of the identifiers list.
Definition: BCBase.cpp:551
std::vector< std::shared_ptr< BCIdentifierBase > > M_idVector
container for id&#39;s when the list is finalized
Definition: BCBase.hpp:647
void bcManageResidual(VectorType &res, VectorType &rhs, const VectorType &sol, FESpace< Mesh, MapEpetra > &feSpace, const BCHandler &bcHandler, const DataType &time, const DataType &diagonalizeCoef)
Prescribe boundary conditions. Case in which only the residual is available.
void bcFluxManageMatrix(MatrixType &matrix, const MeshType &mesh, const DOF &dof, const BCBase &boundaryCond, CurrentFEManifold &currentBdFE, const DataType &, UInt offset)
Prescribe Flux boundary condition only on the matrix.
Definition: BCManage.hpp:2449
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191
const BCVectorBase * pointerToBCVector() const
Returns a pointer to the BCVector object.
Definition: BCBase.cpp:538
void bcEssentialManageRhs(VectorType &rightHandSide, const DOF &dof, const BCBase &boundaryCond, const DataType &diagonalizeCoef, const DataType &time, UInt offset)
Prescribe Essential boundary conditions on the right hand side.
Definition: BCManage.hpp:1459