LifeV
OneDFSIBC.cpp
Go to the documentation of this file.
1 //@HEADER
2 /*
3 *******************************************************************************
4 
5  Copyright (C) 2004, 2005, 2007 EPFL, Politecnico di Milano, INRIA
6  Copyright (C) 2010 EPFL, Politecnico di Milano, Emory University
7 
8  This file is part of LifeV.
9 
10  LifeV is free software; you can redistribute it and/or modify
11  it under the terms of the GNU Lesser General Public License as published by
12  the Free Software Foundation, either version 3 of the License, or
13  (at your option) any later version.
14 
15  LifeV is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public License
21  along with LifeV. If not, see <http://www.gnu.org/licenses/>.
22 
23 *******************************************************************************
24 */
25 //@HEADER
26 
27 /*!
28  * @file
29  * @brief File containing a class for the boundary conditions of the 1D model.
30  *
31  * @version 1.0
32  * @date 01-28-2006
33  * @author Lucia Mirabella <lucia@mathcs.emory.edu>
34  * @author Tiziano Passerini <tiziano@mathcs.emory.edu>
35  *
36  * @version 2.0
37  * @date 20-04-2010
38  * @author Cristiano Malossi <cristiano.malossi@epfl.ch>
39  *
40  * @contributors Ricardo Ruiz-Baier <ricardo.ruiz@epfl.ch>
41  * @maintainer Cristiano Malossi <cristiano.malossi@epfl.ch>
42  */
43 
44 #include <lifev/one_d_fsi/fem/OneDFSIBC.hpp>
45 
46 namespace LifeV
47 {
48 
49 // ===================================================
50 // Constructors & Destructor
51 // ===================================================
52 OneDFSIBC::OneDFSIBC ( const bcSide_Type& bcSide ) :
53  M_bcType (),
54  M_bcSide ( bcSide ),
55  M_bcFunction ()
56 {
57 }
58 
59 OneDFSIBC::OneDFSIBC ( const OneDFSIBC& bc ) :
60  M_bcType ( bc.M_bcType ),
61  M_bcSide ( bc.M_bcSide ),
63 {}
64 
65 // ===================================================
66 // Methods
67 // ===================================================
68 void
69 OneDFSIBC::applyBC ( const Real& time, const Real& timeStep, const solution_Type& solution,
70  const fluxPtr_Type& fluxPtr, vectorPtrContainer_Type& rhs )
71 {
72  UInt iNode;
73  ( M_bcSide == OneDFSI::left ) ? iNode = 0 : iNode = fluxPtr->physics()->data()->numberOfNodes() - 1;
74 
75  container2D_Type boundaryU;
76  boundaryU[0] = (*solution.find ("A")->second) (iNode);
77  boundaryU[1] = (*solution.find ("Q")->second) (iNode);
78 
79  // Eigenvalues and eigenvectors of the jacobian diffFlux (= dF/dU = H)
80  container2D_Type eigenvalues;
81  container2D_Type leftEigenvector1, leftEigenvector2;
82 
83  fluxPtr->eigenValuesEigenVectors ( boundaryU[0], boundaryU[1],
84  eigenvalues, leftEigenvector1, leftEigenvector2, iNode );
85 
86  std::map<bcLine_Type, container2D_Type> bcMatrix;
87  bcMatrix[ OneDFSI::first ] = container2D_Type();
88  bcMatrix[ OneDFSI::second ] = container2D_Type();
89 
90  container2D_Type bcRHS;
91 
92  // First line of Matrix and RHS
93  computeMatrixAndRHS ( time, timeStep, fluxPtr, OneDFSI::first,
94  leftEigenvector1, leftEigenvector2, iNode, bcMatrix, bcRHS[0] );
95 
96  // Second line of Matrix and RHS
97  computeMatrixAndRHS ( time, timeStep, fluxPtr, OneDFSI::second,
98  leftEigenvector1, leftEigenvector2, iNode, bcMatrix, bcRHS[1] );
99 
100 
101  container2D_Type bc = solveLinearSystem ( bcMatrix[OneDFSI::first], bcMatrix[OneDFSI::second], bcRHS );
102 
103  // Set the BC in the RHS
104  (*rhs[0]) ( iNode ) = bc[0];
105  (*rhs[1]) ( iNode ) = bc[1];
106 
107 #ifdef HAVE_LIFEV_DEBUG
108  debugStream (6311) << "[OneDFSIBC::applyBC] on bcSide " << M_bcSide << " imposing [ A, Q ] = [ " << bc[0] << ", " << bc[1] << " ]\n";
109 #endif
110 }
111 
112 void
113 OneDFSIBC::applyViscoelasticBC ( const fluxPtr_Type& fluxPtr, matrix_Type& matrix, vector_Type& rhs )
114 {
115  UInt iNode;
116  ( M_bcSide == OneDFSI::left ) ? iNode = 0 : iNode = fluxPtr->physics()->data()->numberOfNodes() - 1;
117 
118  switch ( M_bcType.find ( OneDFSI::first )->second )
119  {
120  case OneDFSI::A:
121  case OneDFSI::P:
122  case OneDFSI::S:
123 
124 #ifdef HAVE_NEUMANN_VISCOELASTIC_BC
125  break;
126 #endif
127 
128  case OneDFSI::Q:
129  case OneDFSI::W1:
130  case OneDFSI::W2:
131 
132  matrix.diagonalize ( iNode, 1 );
133  rhs ( iNode ) = 0;
134 
135  break;
136 
137  default:
138 
139  std::cout << "Warning: bcType \"" << M_bcType.find ( OneDFSI::first )->second << "\"not available!" << std::endl;
140 
141  break;
142  }
143 }
144 
145 // ===================================================
146 // Private Methods
147 // ===================================================
148 void
149 OneDFSIBC::computeMatrixAndRHS ( const Real& time, const Real& timeStep, const fluxPtr_Type& fluxPtr, const bcLine_Type& line,
150  const container2D_Type& leftEigenvector1, const container2D_Type& leftEigenvector2,
151  const UInt& iNode, std::map<bcLine_Type, container2D_Type>& bcMatrix, Real& bcRHS )
152 {
153  // This is not general (typical situation):
154  // on first line, left boundary, I impose W1
155  // on second line, left boundary, I impose W2
156  // on first line, right boundary, I impose W2
157  // on second line, right boundary, I impose W1
158  // The code does not check for coherence (you cannot impose the same variable on both lines!)
159 
160  // Compute Matrix & RHS
161  bcRHS = M_bcFunction[ line ] (time, timeStep);
162  switch ( M_bcType[line] )
163  {
164  case OneDFSI::W1:
165  bcMatrix[line] = leftEigenvector1;
166  break;
167  case OneDFSI::W2:
168  bcMatrix[line] = leftEigenvector2;
169  break;
170  case OneDFSI::A:
171  bcMatrix[line][0] = 1.;
172  bcMatrix[line][1] = 0.;
173  break;
174  case OneDFSI::S:
175  // The normal stress has opposite sign with respect to the pressure
176  bcRHS *= -1;
177  // The break here is missing on purpose!
178  case OneDFSI::P:
179  bcRHS = fluxPtr->physics()->fromPToA ( bcRHS, timeStep, iNode );
180  bcMatrix[line][0] = 1.;
181  bcMatrix[line][1] = 0.;
182  break;
183  case OneDFSI::Q:
184  // Flow rate is positive with respect to the outgoing normal
185  if ( M_bcSide == OneDFSI::left )
186  {
187  bcRHS *= -1;
188  }
189  bcMatrix[line][0] = 0.;
190  bcMatrix[line][1] = 1.;
191  break;
192  default:
193  std::cout << "\n[OneDFSIBC::computeMatrixAndRHS] Wrong boundary variable as " << line << " condition on bcSide " << M_bcSide;
194  break;
195  }
196 
197 #ifdef HAVE_LIFEV_DEBUG
198  debugStream (6311) << "[OneDFSIBC::computeMatrixAndRHS] to impose variable "
199  << M_bcType[line] << ", " << line << " line = " << bcMatrix[line][0] << ", " << bcMatrix[line][1] << "\n";
200 #endif
201 }
202 
203 OneDFSIBC::container2D_Type
204 OneDFSIBC::solveLinearSystem ( const container2D_Type& line1,
205  const container2D_Type& line2,
206  const container2D_Type& rhs ) const
207 {
208 #ifdef HAVE_LIFEV_DEBUG
209  ASSERT_PRE ( line1.size() == 2 && line2.size() == 2 && rhs.size() == 2,
210  "OneDFSIBC::solveLinearSystem works only for 2D vectors");
211 #endif
212 
213  Real determinant = line1[0] * line2[1] - line1[1] * line2[0];
214 
215 #ifdef HAVE_LIFEV_DEBUG
216  ASSERT ( determinant != 0,
217  "Error: the 2x2 system on the boundary is not invertible."
218  "\nCheck the boundary conditions.");
219 #endif
220 
221  container2D_Type solution;
222 
223  solution[0] = ( line2[1] * rhs[0] - line1[1] * rhs[1] ) / determinant;
224  solution[1] = ( - line2[0] * rhs[0] + line1[0] * rhs[1] ) / determinant;
225 
226  return solution;
227 }
228 
229 }
bcSide_Type M_bcSide
Definition: OneDFSIBC.hpp:233
void applyBC(const Real &time, const Real &timeStep, const solution_Type &solution, const fluxPtr_Type &fluxPtr, vectorPtrContainer_Type &rhs)
Apply boundary conditions to the rhs of the Taylor-Galerkin problem.
Definition: OneDFSIBC.cpp:69
OneDFSIBC(const OneDFSIBC &bc)
Copy constructor.
Definition: OneDFSIBC.cpp:59
void computeMatrixAndRHS(const Real &time, const Real &timeStep, const fluxPtr_Type &fluxPtr, const bcLine_Type &bcLine, const container2D_Type &leftEigenvector1, const container2D_Type &leftEigenvector2, const UInt &dof, std::map< bcLine_Type, container2D_Type > &bcMatrix, Real &bcRHS)
Compute the matrix and the RHS for the BC 2x2 linear system.
Definition: OneDFSIBC.cpp:149
void updateInverseJacobian(const UInt &iQuadPt)
OneDFSIBC - Class featuring methods to handle boundary conditions.
Definition: OneDFSIBC.hpp:64
void applyViscoelasticBC(const fluxPtr_Type &fluxPtr, matrix_Type &matrix, vector_Type &rhs)
Apply boundary conditions to the rhs of the viscoelastic problem.
Definition: OneDFSIBC.cpp:113
double Real
Generic real data.
Definition: LifeV.hpp:175
container2D_Type solveLinearSystem(const container2D_Type &line1, const container2D_Type &line2, const container2D_Type &rhs) const
Solve a 2x2 linear system by the Cramer method (for the boundary conditions)
Definition: OneDFSIBC.cpp:204
OneDFSIBC(const bcSide_Type &bcSide)
Constructor.
Definition: OneDFSIBC.cpp:52
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191