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