LifeV
MultiscaleCouplingMeanNormalStress.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 the multiscale mean normal stress coupling class
30  *
31  * @date 07-08-2012
32  * @author Cristiano Malossi <cristiano.malossi@epfl.ch>
33  *
34  * @maintainer Cristiano Malossi <cristiano.malossi@epfl.ch>
35  */
36 
37 #include <lifev/multiscale/couplings/MultiscaleCouplingMeanNormalStress.hpp>
38 
39 namespace LifeV
40 {
41 namespace Multiscale
42 {
43 
44 // ===================================================
45 // Constructors & Destructor
46 // ===================================================
49 {
50 
51 #ifdef HAVE_LIFEV_DEBUG
52  debugStream ( 8220 ) << "MultiscaleCouplingMeanNormalStress::MultiscaleCouplingMeanNormalStress() \n";
53 #endif
54 
56 }
57 
58 // ===================================================
59 // Multiscale PhysicalCoupling Implementation
60 // ===================================================
61 void
63 {
64 
65 #ifdef HAVE_LIFEV_DEBUG
66  debugStream ( 8220 ) << "MultiscaleCouplingMeanNormalStress::setupCouplingVariablesNumber() \n";
67 #endif
68 
70 }
71 
72 void
74 {
75 
76 #ifdef HAVE_LIFEV_DEBUG
77  debugStream ( 8220 ) << "MultiscaleCouplingMeanNormalStress::setupCoupling() \n";
78 #endif
79 
80  if ( myModelsNumber() > 0 )
81  {
82  // Impose flow rate boundary conditions
83  for ( UInt i ( 0 ); i < static_cast<UInt>(M_flowRateInterfaces); ++i )
84  if ( myModel ( i ) )
85  {
86  M_localCouplingFunctions.push_back ( MultiscaleCouplingFunction ( this, i ) );
87  multiscaleDynamicCast< MultiscaleInterface > ( M_models[i] )->imposeBoundaryFlowRate ( M_boundaryIDs[i], std::bind ( &MultiscaleCouplingFunction::function, M_localCouplingFunctions.back(), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5 ) );
88  }
89 
90  // Impose stress boundary conditions
91  for ( UInt i ( M_flowRateInterfaces ); i < modelsNumber(); ++i )
92  if ( myModel ( i ) )
93  {
94  M_localCouplingFunctions.push_back ( MultiscaleCouplingFunction ( this, M_flowRateInterfaces ) );
95  multiscaleDynamicCast< MultiscaleInterface > ( M_models[i] )->imposeBoundaryMeanNormalStress ( M_boundaryIDs[i], std::bind ( &MultiscaleCouplingFunction::function, M_localCouplingFunctions.back(), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5 ) );
96  }
97  }
98 }
99 
100 void
102 {
103 
104 #ifdef HAVE_LIFEV_DEBUG
105  debugStream ( 8220 ) << "MultiscaleCouplingMeanNormalStress::initializeCouplingVariables() \n";
106 #endif
107 
108  // Compute the flow rate coupling variables on the first M_flowRateInterfaces models
109  Real localSum ( 0 );
110  Real globalSum ( 0 );
111 
112  for ( UInt i ( 0 ); i < static_cast<UInt>(M_flowRateInterfaces); ++i )
113  {
114  if ( myModel ( i ) )
115  {
116  Real myValue = multiscaleDynamicCast< MultiscaleInterface > ( M_models[i] )->boundaryFlowRate ( M_boundaryIDs[i] );
117  if ( isModelLeaderProcess ( i ) )
118  {
119  localSum = myValue;
120  }
121  }
122 
123  // We use the SumAll() instead of the Broadcast() because this way we don't need the id of the leader process.
124  M_comm->SumAll ( &localSum, &globalSum, 1 );
125  if ( myModelsNumber() > 0 )
126  {
127  localCouplingVariables ( 0 ) [i] = globalSum;
128  }
129 
130  localSum = 0;
131  globalSum = 0;
132  }
133 
134  // Compute the mean normal stress coupling variable as an average of all the stresses
135  for ( UInt i ( 0 ); i < modelsNumber(); ++i )
136  if ( myModel ( i ) )
137  {
138  Real myValue = multiscaleDynamicCast< MultiscaleInterface > ( M_models[i] )->boundaryMeanNormalStress ( M_boundaryIDs[i] );
139  if ( isModelLeaderProcess ( i ) )
140  {
141  localSum += myValue;
142  }
143  }
144 
145  M_comm->SumAll ( &localSum, &globalSum, 1 );
146  if ( myModelsNumber() > 0 )
147  {
148  localCouplingVariables ( 0 ) [M_flowRateInterfaces] = globalSum / modelsNumber();
149  }
150 }
151 
152 void
154 {
155 
156 #ifdef HAVE_LIFEV_DEBUG
157  debugStream ( 8220 ) << "MultiscaleCouplingMeanNormalStress::computeCouplingResiduals() \n";
158 #endif
159 
160  // Reset coupling residual
161  *M_localCouplingResiduals = 0.;
162 
163  if ( myModelsNumber() > 0 )
164  {
165  for ( UInt i ( 0 ); i < static_cast<UInt>(M_flowRateInterfaces); ++i )
166  if ( myModel ( i ) )
167  {
168  Real myValueStress = multiscaleDynamicCast< MultiscaleInterface > ( M_models[i] )->boundaryMeanNormalStress ( M_boundaryIDs[i] );
169  if ( isModelLeaderProcess ( i ) )
170  {
171  ( *M_localCouplingResiduals ) [0] += localCouplingVariables ( 0 ) [i];
172  ( *M_localCouplingResiduals ) [i + 1] = myValueStress - localCouplingVariables ( 0 ) [M_flowRateInterfaces];
173  }
174  }
175 
176  for ( UInt i ( M_flowRateInterfaces ); i < modelsNumber(); ++i )
177  if ( myModel ( i ) )
178  {
179  Real myValueFlowRate = multiscaleDynamicCast< MultiscaleInterface > ( M_models[i] )->boundaryFlowRate ( M_boundaryIDs[i] );
180  if ( isModelLeaderProcess ( i ) )
181  {
182  ( *M_localCouplingResiduals ) [0] += myValueFlowRate;
183  }
184  }
185  }
186 }
187 
188 // ===================================================
189 // Private MultiscaleCoupling Implementation
190 // ===================================================
191 void
193 {
194 
195 #ifdef HAVE_LIFEV_DEBUG
196  debugStream ( 8220 ) << "MultiscaleCouplingMeanNormalStress::exportListOfPerturbedModels( localCouplingVariableID ) \n";
197 #endif
198 
199  if ( static_cast<Int>(localCouplingVariableID) < M_flowRateInterfaces )
200  {
201  if ( myModel (localCouplingVariableID) )
202  {
203  perturbedModelsList.reserve ( 1 );
204  perturbedModelsList.push_back ( M_models[localCouplingVariableID] );
205  }
206  }
207  else
208  {
209  perturbedModelsList.reserve ( modelsNumber() - M_flowRateInterfaces );
210  for ( UInt i ( M_flowRateInterfaces ); i < modelsNumber(); ++i )
211  if ( myModel ( i ) )
212  {
213  perturbedModelsList.push_back ( M_models[i] );
214  }
215  }
216 }
217 
218 void
220 {
221 
222 #ifdef HAVE_LIFEV_DEBUG
223  debugStream ( 8220 ) << "MultiscaleCouplingMeanNormalStress::insertJacobianConstantCoefficients( jacobian ) \n";
224 #endif
225 
226  // The constant coefficients are added by the leader process of model 0.
227  if ( myModel ( 0 ) )
228  if ( isModelLeaderProcess ( 0 ) )
229  for ( UInt i ( 0 ); i < static_cast<UInt>(M_flowRateInterfaces); ++i )
230  {
231  jacobian.addToCoefficient ( M_couplingVariablesOffset, M_couplingVariablesOffset + i, 1 );
232  jacobian.addToCoefficient ( M_couplingVariablesOffset + 1 + i, M_couplingVariablesOffset + M_flowRateInterfaces, -1 );
233  }
234 }
235 
236 void
237 MultiscaleCouplingMeanNormalStress::insertJacobianDeltaCoefficients ( multiscaleMatrix_Type& jacobian, const UInt& column, const UInt& ID, bool& solveLinearSystem )
238 {
239 
240 #ifdef HAVE_LIFEV_DEBUG
241  debugStream ( 8220 ) << "MultiscaleCouplingMeanNormalStress::insertJacobianDeltaCoefficients( jacobian, column, ID, solveLinearSystem ) \n";
242 #endif
243 
244  // Model global to local conversion
245  UInt modelLocalID = modelGlobalToLocalID ( ID );
246  if ( myModel ( modelLocalID ) )
247  {
248  Real row ( 0 );
249  Real coefficient ( 0 );
250 
251  if ( static_cast<Int>(modelLocalID) >= M_flowRateInterfaces )
252  {
254  coefficient = multiscaleDynamicCast< MultiscaleInterface > ( M_models[modelLocalID] )->boundaryDeltaFlowRate ( M_boundaryIDs[modelLocalID], solveLinearSystem );
255  }
256  else
257  {
258  row = M_couplingVariablesOffset + 1 + modelLocalID;
259  coefficient = multiscaleDynamicCast< MultiscaleInterface > ( M_models[modelLocalID] )->boundaryDeltaMeanNormalStress ( M_boundaryIDs[modelLocalID], solveLinearSystem );
260  }
261 
262  // Add the coefficient to the matrix
263  if ( isModelLeaderProcess ( modelLocalID ) )
264  {
265  jacobian.addToCoefficient ( row, column, coefficient );
266 
267 #ifdef HAVE_LIFEV_DEBUG
268  debugStream ( 8220 ) << "J(" << row << "," << column << ") = " << coefficient << "\n";
269 #endif
270  }
271  }
272 
273 }
274 
275 } // Namespace Multiscale
276 } // Namespace LifeV
virtual void setupCouplingVariablesNumber()
Setup the coupling variables number.
MultiscaleCoupling multiscaleCoupling_Type
int32_type Int
Generic integer data.
Definition: LifeV.hpp:188
void updateInverseJacobian(const UInt &iQuadPt)
virtual void insertJacobianDeltaCoefficients(multiscaleMatrix_Type &jacobian, const UInt &column, const UInt &ID, bool &solveLinearSystem)
Insert the Jacobian coefficient(s) depending on a perturbation of the model, due to a specific variab...
MatrixEpetra< Real > multiscaleMatrix_Type
virtual void exportListOfPerturbedModels(const UInt &localCouplingVariableID, multiscaleModelsContainer_Type &perturbedModelsList)
Build the list of models affected by the perturbation of a local coupling variable.
std::vector< multiscaleModelPtr_Type > multiscaleModelsContainer_Type
double Real
Generic real data.
Definition: LifeV.hpp:175
virtual void computeCouplingResiduals()
Compute the local coupling residuals vector.
MultiscaleCouplingMeanNormalStress - Stress coupling condition.
virtual void initializeCouplingVariables()
Initialize the values of the coupling variables.
virtual void insertJacobianConstantCoefficients(multiscaleMatrix_Type &jacobian)
Insert constant coefficients into the Jacobian matrix.
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191