LifeV
MonolithicBlock.cpp
Go to the documentation of this file.
1 /* -*- mode: c++ -*- */
2 //@HEADER
3 /*
4 *******************************************************************************
5 
6  Copyright (C) 2004, 2005, 2007 EPFL, Politecnico di Milano, INRIA
7  Copyright (C) 2010 EPFL, Politecnico di Milano, Emory University
8 
9  This file is part of LifeV.
10 
11  LifeV is free software; you can redistribute it and/or modify
12  it under the terms of the GNU Lesser General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  LifeV is distributed in the hope that it will be useful,
17  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  Lesser General Public License for more details.
20 
21  You should have received a copy of the GNU Lesser General Public License
22  along with LifeV. If not, see <http://www.gnu.org/licenses/>.
23 
24 *******************************************************************************
25 */
26 //@HEADER
27 
28 #include <lifev/core/LifeV.hpp>
29 
30 #include <lifev/fsi/solver/MonolithicBlock.hpp>
31 
32 namespace LifeV
33 {
34 
35 
36 // ===================================================
37 //! Public Methods
38 // ===================================================
39 
40 void MonolithicBlock::couplingMatrix (matrixPtr_Type& bigMatrix,
41  Int flag,
42  const std::vector<fespacePtr_Type>& problem,
43  const std::vector<UInt>& offset,
44  const std::map<ID, ID>& locDofMap,
45  const vectorPtr_Type& numerationInterface,
46  const Real& timeStep,
47  const Real& value,
48  const Real& coefficient,
49  const Real& rescaleFactor) // not working with non-matching grids
50 {
51  // coupling from 1 to 31, working as chmod
52  if ( flag - 31 > 0 ) //recursive call
53  {
54  Int subFlag (flag);
55  subFlag -= 31;
56  std::vector<fespacePtr_Type> newProblem (problem.begin() + 3, problem.end() );
57  std::vector<UInt> newOffset (offset.begin() + 3, offset.end() );
58 
59  couplingMatrix ( bigMatrix, subFlag, newProblem, newOffset, locDofMap, numerationInterface, rescaleFactor, value, coefficient, rescaleFactor);
60  }
61  std::map<ID, ID>::const_iterator ITrow;
62  UInt interface (numerationInterface->map().map (Unique)->NumGlobalElements() );
63  UInt totalSize (offset[0] + problem[0]->map().map (Unique)->NumGlobalElements() );
64 
65  if (flag - 16 >= 0) //coupling the mesh in FSI
66  {
67  //UInt interface( numerationInterface->getMap().getMap( Unique )->NumGlobalElements() );
68  UInt solidFluidInterface ( offset[2] );
69  std::map<ID, ID>::const_iterator ITrow;
70  for ( UInt dim = 0; dim < nDimensions; ++dim )
71  {
72  for ( ITrow = locDofMap.begin(); ITrow != locDofMap.end() ; ++ITrow )
73  {
74  if ( numerationInterface->map().map (Unique)->LID ( static_cast<EpetraInt_Type> (ITrow->second /*+ dim*solidDim*/) ) >= 0 ) //to avoid repeated stuff
75  {
76  bigMatrix->addToCoefficient (solidFluidInterface + ITrow->first + dim * problem[2]->dof().numTotalDof(), offset[0] + ITrow->second + dim * problem[0]->dof().numTotalDof(), (-value) *rescaleFactor/*scaling of the solid matrix*/);
77  }
78  }
79  }
80  flag -= 16;
81  }
82 
83  Int newFlag (flag);
84 
85  for (UInt dim = 0; dim < nDimensions; ++dim) //coupling F-S in FSI
86  {
87  for ( ITrow = locDofMap.begin(); ITrow != locDofMap.end() ; ++ITrow, newFlag = flag )
88  {
89  if (numerationInterface->map().map (Unique)->LID ( static_cast<EpetraInt_Type> (ITrow->second /*+ dim*solidDim*/) ) >= 0 ) //to avoid repeated stuff
90  {
91  if (newFlag - 8 >= 0) //right low
92  {
93  bigMatrix->addToCoefficient ( offset[0] + ITrow->second + dim * problem[0]->dof().numTotalDof(), (int) (*numerationInterface) [ITrow->second/*+ dim*solidDim*/ ] + dim * interface + totalSize, value ); //right low
94  newFlag -= 8;
95  }
96  if (newFlag - 4 >= 0) // right up
97  {
98  bigMatrix->addToCoefficient ( offset[1] + ITrow->first + dim * problem[1]->dof().numTotalDof(), (int) (*numerationInterface) [ITrow->second/*+ dim*solidDim*/ ] + dim * interface + totalSize, -value ); //right up
99  newFlag -= 4;
100  }
101  if (newFlag - 2 >= 0) //low left
102  {
103  bigMatrix->addToCoefficient ( (int) (*numerationInterface) [ITrow->second/*+ dim*solidDim*/ ] + dim * interface + totalSize, (ITrow->first) + dim * problem[1]->dof().numTotalDof(), value); //low left
104  newFlag -= 2;
105  }
106  if (newFlag - 1 >= 0) //low right
107  {
108  bigMatrix->addToCoefficient ( (int) (*numerationInterface) [ITrow->second/*+ dim*solidDim*/ ] + dim * interface + totalSize, (offset[0] + ITrow->second) + dim * problem[0]->dof().numTotalDof(), -value / timeStep * rescaleFactor * coefficient); //low right
109  }
110 
111  bigMatrix->addToCoefficient ( (int) (*numerationInterface) [ITrow->second/*+ dim*solidDim*/ ] + dim * interface + totalSize , (int) (*numerationInterface) [ITrow->second /*+ dim*solidDim*/ ] + dim * interface + totalSize, 0.0);
112  }
113  }
114  }
115 }
116 
117 void MonolithicBlock::applyBoundaryConditions (const Real& time)
118 {
119  ASSERT ( M_bch.size() == M_blocks.size(), "The number of BChandlers must correspond to the number of blocks" )
120  for (ID i = 0; i < M_bch.size(); ++i)
121  {
122  applyBoundaryConditions (time, i);
123  }
124 }
125 
126 
127 void MonolithicBlock::applyBoundaryConditions (const Real& time, const UInt i)
128 {
129  M_blocks[i]->openCrsMatrix();
130  if ( !M_bch[i]->bcUpdateDone() )
131  {
132  M_bch[i]->bcUpdate ( *M_FESpace[i]->mesh(), M_FESpace[i]->feBd(), M_FESpace[i]->dof() );
133  M_bch[i]->setOffset (M_offset[i]);
134  }
135  //M_blocks[i]->GlobalAssemble();
136  bcManageMatrix ( *M_blocks[i] , *M_FESpace[i]->mesh(), M_FESpace[i]->dof(), *M_bch[i], M_FESpace[i]->feBd(), 1., time);
137 }
138 
139 void MonolithicBlock::setConditions ( std::vector<bchandlerPtr_Type>& vec )
140 {
141  M_bch = vec;
142 }
143 
144 void
145 MonolithicBlock::setSpaces (std::vector<fespacePtr_Type>& vec )
146 {
147  M_FESpace = vec;
148 }
149 
150 void
151 MonolithicBlock::setOffsets (UInt blocks, ...)
152 {
153  using namespace std;
154  va_list arguments;
155  va_start (arguments, blocks);
156  M_offset.resize (0);
157 
158  for (ID i = 0; i < M_blocks.size(); ++i)
159  {
160  M_offset.push_back (va_arg (arguments, UInt) );
161  }
162  va_end (arguments);
163 }
164 
165 
166 void
167 MonolithicBlock::robinCoupling ( matrixPtr_Type& matrix,
168  Real& alphaf,
169  Real& alphas,
170  UInt coupling,
171  const MonolithicBlock::fespacePtr_Type& FESpace1,
172  const UInt& /*offset1*/,
173  const MonolithicBlock::fespacePtr_Type& FESpace2,
174  const UInt& offset2,
175  const std::map<ID, ID>& locDofMap,
176  const MonolithicBlock::vectorPtr_Type& numerationInterface ) // not working with non-matching grids
177 {
178  //coupling: flag from 1 to 4 working as chmod
179  UInt interface (numerationInterface->map().map (Unique)->NumGlobalElements() );
180  std::map<ID, ID>::const_iterator ITrow;
181  UInt totalSize (offset2 + FESpace2->map().map (Unique)->NumGlobalElements() );
182 
183 
184  if ( ( (Int) coupling) - 4 >= 0)
185  {
186  for ( ITrow = locDofMap.begin(); ITrow != locDofMap.end() ; ++ITrow)
187  {
188  if (numerationInterface->map().map (Unique)->LID ( static_cast<EpetraInt_Type> (ITrow->second /*+ dim*solidDim*/) ) >= 0 ) //to avoid repeated stuff
189  {
190  for (UInt dim = 0; dim < nDimensions; ++dim)
191  {
192  matrix->addToCoefficient ( (int) (*numerationInterface) [ITrow->second ] + dim * interface + totalSize, (offset2 + ITrow->second) + dim * FESpace2->dof().numTotalDof(), alphas); //low right
193  }
194  }
195  }
196  coupling -= 4;
197  }
198  if ( ( (Int) coupling - 2) >= 0)
199  {
200  for ( ITrow = locDofMap.begin(); ITrow != locDofMap.end() ; ++ITrow)
201  {
202  if (numerationInterface->map().map (Unique)->LID ( static_cast<EpetraInt_Type> (ITrow->second /*+ dim*solidDim*/) ) >= 0 ) //to avoid repeated stuff
203  {
204  for (UInt dim = 0; dim < nDimensions; ++dim)
205  {
206  matrix->addToCoefficient ( ITrow->first + dim * FESpace1->dof().numTotalDof(), (int) (*numerationInterface) [ITrow->second ] + dim * interface + totalSize, alphaf ); //right up
207  }
208  }
209  }
210  coupling -= 2;
211  }
212  if ( ( (Int) coupling) - 1 >= 0)
213  {
214  for ( ITrow = locDofMap.begin(); ITrow != locDofMap.end() ; ++ITrow)
215  {
216  if (numerationInterface->map().map (Unique)->LID ( static_cast<EpetraInt_Type> (ITrow->second /*+ dim*solidDim*/) ) >= 0 ) //to avoid repeated stuff
217  {
218  for (UInt dim = 0; dim < nDimensions; ++dim)
219  {
220  matrix->addToCoefficient ( (int) (*numerationInterface) [ITrow->second ] + dim * interface + totalSize, (ITrow->first) + dim * FESpace1->dof().numTotalDof(), alphas); //low left
221  }
222  }
223  }
224  }
225 }
226 
227 void MonolithicBlock::addToBlock ( const matrixPtr_Type& Mat, UInt position)
228 {
229  *Mat += *M_blocks[position];
230  M_blocks[position] = Mat;
231 }
232 
233 void MonolithicBlock::push_back_oper ( MonolithicBlock& Oper)
234 {
235  // M_blocks.reserve(M_blocks.size()+Oper.blockVector().size());
236  // M_bch.reserve(M_bch.size()+Oper.BChVector().size());
237  // M_FESpace.reserve(M_FESpace.size()+Oper.FESpaceVector().size());
238  // M_offset.reserve(M_offset.size()+Oper.getOffestVector().size());
239 
240  M_blocks.insert (M_blocks.end(), Oper.blockVector().begin(), Oper.blockVector().end() );
241  M_bch.insert (M_bch.end(), Oper.BChVector().begin(), Oper.BChVector().end() );
242  M_FESpace.insert (M_FESpace.end(), Oper.FESpaceVector().begin(), Oper.FESpaceVector().end() );
243  M_offset.insert (M_offset.end(), Oper.offsetVector().begin(), Oper.offsetVector().end() );
244 }
245 
246 } // Namespace LifeV
int32_type Int
Generic integer data.
Definition: LifeV.hpp:188
void updateInverseJacobian(const UInt &iQuadPt)
#define ASSERT(X, A)
Definition: LifeAssert.hpp:90
double Real
Generic real data.
Definition: LifeV.hpp:175
const UInt nDimensions(NDIM)
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191