LifeV
MultiscaleCouplingMeanNormalStressValve.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 with simple valve
30  *
31  * @date 05-04-2011
32  * @author Cristiano Malossi <cristiano.malossi@epfl.ch>
33  *
34  * @maintainer Cristiano Malossi <cristiano.malossi@epfl.ch>
35  */
36 
37 #include <lifev/multiscale/couplings/MultiscaleCouplingMeanNormalStressValve.hpp>
38 
39 namespace LifeV
40 {
41 namespace Multiscale
42 {
43 
44 // ===================================================
45 // Constructors & Destructor
46 // ===================================================
49  super_Type (),
50  M_valveIsOpen ( true ),
51  M_topologyChange ( false )
52 {
53 
54 #ifdef HAVE_LIFEV_DEBUG
55  debugStream ( 8240 ) << "MultiscaleCouplingMeanNormalStressValve::MultiscaleCouplingMeanNormalStressValve() \n";
56 #endif
57 
59 }
60 
61 // ===================================================
62 // Multiscale PhysicalCoupling Implementation
63 // ===================================================
64 void
66 {
67 
68 #ifdef HAVE_LIFEV_DEBUG
69  debugStream ( 8240 ) << "MultiscaleCouplingMeanNormalStressValve::setupCoupling() \n";
70 #endif
71 
72  super_Type::setupCoupling();
73 
74  // Preliminary checks to use the valve
75  if ( myModelsNumber() > 0 )
76  {
77  if ( modelsNumber() > 2 )
78  {
79  std::cout << "!!! WARNING: MultiscaleCouplingMeanNormalStressValve does not work with more than two models !!!" << std::endl;
80  }
81  if ( M_flowRateInterfaces != static_cast<Int>(modelsNumber()) )
82  {
83  std::cout << "!!! WARNING: MultiscaleCouplingMeanNormalStressValve does not work with stress boundary data !!!" << std::endl;
84  }
85  }
86 }
87 
88 void
90 {
91 
92 #ifdef HAVE_LIFEV_DEBUG
93  debugStream ( 8240 ) << "MultiscaleCouplingMeanNormalStressValve::initializeCouplingVariables() \n";
94 #endif
95 
96  super_Type::initializeCouplingVariables();
97 
98  // We determine the initial position of the valve on the leader process of model 0,
99  // then we share the information with the other processes.
100 
101  Int localValvePosition ( 0 );
102  Int globalValvePosition ( 0 );
103  if ( myModel ( 0 ) )
104  if ( isModelLeaderProcess ( 0 ) )
105  {
106  if ( localCouplingVariables ( 0 ) [M_flowRateInterfaces] <= 1e-10 )
107  {
108  std::cout << " MS- Valve closed at coupling " << M_ID << std::endl;
109  localValvePosition = 0;
110  }
111  else
112  {
113  std::cout << " MS- Valve open at coupling " << M_ID << std::endl;
114  localValvePosition = 1;
115  }
116  }
117 
118  // We use the SumAll() instead of the Broadcast() because this way we don't need the id of the leader process.
119  M_comm->SumAll ( &localValvePosition, &globalValvePosition, 1 );
120 
121  // If the valve is closed the coupling variables are set to zero
122  if ( globalValvePosition == 0 )
123  {
124  M_valveIsOpen = false;
125  if ( myModelsNumber() > 0 )
126  for ( Int i ( 0 ); i < M_flowRateInterfaces; ++i ) // Only the flow rate is set to zero
127  {
128  localCouplingVariables ( 0 ) [i] = 0;
129  }
130  }
131  else
132  {
133  M_valveIsOpen = true;
134  }
135 }
136 
137 void
139 {
140 
141 #ifdef HAVE_LIFEV_DEBUG
142  debugStream ( 8240 ) << "MultiscaleCouplingMeanNormalStressValve::updateCoupling() \n";
143 #endif
144 
145  super_Type::updateCoupling();
146 
147  // We determine if there is a topology change on the leader process of model 0,
148  // then we share the information with the other processes.
149  Int localTopology ( 0 );
150  Int globalTopology ( 0 );
151  if ( M_valveIsOpen )
152  {
153  if ( myModel ( 0 ) )
154  {
155  Real myValue = multiscaleDynamicCast< MultiscaleInterface > ( M_models[0] )->boundaryFlowRate ( M_boundaryIDs[0] );
156  if ( isModelLeaderProcess ( 0 ) && myValue < 0 )
157  {
158  std::cout << " MS- Closing the valve at coupling " << M_ID << std::endl;
159  localTopology = 1;
160  }
161  }
162  }
163  else
164  {
165  Real globalSum ( 0 );
166  Real localSum ( 0 );
167 
168  if ( myModel ( 1 ) )
169  {
170  Real myValue = multiscaleDynamicCast< MultiscaleInterface > ( M_models[1] )->boundaryMeanNormalStress ( M_boundaryIDs[1] );
171  if ( isModelLeaderProcess ( 1 ) )
172  {
173  localSum = myValue;
174  }
175  }
176 
177  // We use the SumAll() instead of the Broadcast() because this way we don't need the id of the leader process.
178  M_comm->SumAll ( &localSum, &globalSum, 1 );
179 
180  if ( myModel ( 0 ) )
181  {
182  Real myValue = globalSum - multiscaleDynamicCast< MultiscaleInterface > ( M_models[0] )->boundaryMeanNormalStress ( M_boundaryIDs[0] );
183  if ( isModelLeaderProcess ( 0 ) && myValue > 0 )
184  {
185  std::cout << " MS- Opening the valve at coupling " << M_ID << std::endl;
186  localTopology = 1;
187  }
188  }
189  }
190 
191  // We use the SumAll() instead of the Broadcast() because this way we don't need the id of the leader process.
192  M_comm->SumAll ( &localTopology, &globalTopology, 1 );
193 
194  if ( globalTopology > 0 )
195  {
196  M_topologyChange = true;
198 
199  // Reset coupling variable history
200  resetCouplingHistory();
201  }
202  else
203  {
204  M_topologyChange = false;
205  }
206 }
207 
208 void
210 {
211 
212 #ifdef HAVE_LIFEV_DEBUG
213  debugStream ( 8240 ) << "MultiscaleCouplingMeanNormalStressValve::computeCouplingResiduals() \n";
214 #endif
215 
216  if ( M_valveIsOpen )
217  {
218  super_Type::computeCouplingResiduals();
219  }
220  else
221  {
222  *M_localCouplingResiduals = 0.;
223  }
224 }
225 
226 // ===================================================
227 // Private MultiscaleCoupling Implementation
228 // ===================================================
229 void
231 {
232 
233 #ifdef HAVE_LIFEV_DEBUG
234  debugStream ( 8240 ) << "MultiscaleCouplingMeanNormalStressValve::insertJacobianConstantCoefficients( jacobian ) \n";
235 #endif
236 
237  if ( M_valveIsOpen )
238  {
239  super_Type::insertJacobianConstantCoefficients ( jacobian );
240  }
241  else
242  {
243  // The constant coefficients are added by the leader process of model 0.
244  if ( myModel ( 0 ) )
245  if ( isModelLeaderProcess ( 0 ) )
246  {
249 
250  for ( Int i ( 0 ); i < M_flowRateInterfaces + 1; ++i )
251  {
252  jacobian.addToCoefficient ( row + i, column + i, 1 );
253  }
254  }
255  }
256 }
257 
258 void
259 MultiscaleCouplingMeanNormalStressValve::insertJacobianDeltaCoefficients ( multiscaleMatrix_Type& jacobian, const UInt& column, const UInt& ID, bool& solveLinearSystem )
260 {
261 
262 #ifdef HAVE_LIFEV_DEBUG
263  debugStream ( 8240 ) << "MultiscaleCouplingMeanNormalStressValve::insertJacobianDeltaCoefficients( jacobian, column, ID, solveLinearSystem ) \n";
264 #endif
265 
266  if ( M_valveIsOpen )
267  {
268  super_Type::insertJacobianDeltaCoefficients ( jacobian, column, ID, solveLinearSystem );
269  }
270 }
271 
272 } // Namespace Multiscale
273 } // Namespace LifeV
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...
MultiscaleCoupling multiscaleCoupling_Type
int32_type Int
Generic integer data.
Definition: LifeV.hpp:188
void updateInverseJacobian(const UInt &iQuadPt)
MatrixEpetra< Real > multiscaleMatrix_Type
double Real
Generic real data.
Definition: LifeV.hpp:175
void computeCouplingResiduals()
Compute the local coupling residuals vector.
void initializeCouplingVariables()
Initialize the values of the coupling variables.
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191
MultiscaleCouplingMeanNormalStressValve - Mean normal stress coupling condition with simple valve...
void insertJacobianConstantCoefficients(multiscaleMatrix_Type &jacobian)
Insert constant coefficients into the Jacobian matrix.