LifeV
MonolithicBlockComposedNN.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/core/fem/BCManage.hpp>
31 
32 #include <lifev/fsi/solver/MonolithicBlockComposedNN.hpp>
33 
34 namespace LifeV
35 {
36 
37 // ===================================================
38 //! Public Methods
39 // ===================================================
40 
41 int MonolithicBlockComposedNN::solveSystem ( const vector_Type& rhs, vector_Type& step, solverPtr_Type& linearSolver )
42 {
43  M_firstCompPrec .reset (new composed_prec (M_comm) );
44  M_secondCompPrec.reset (new composed_prec (M_comm) );
45 
46  LifeChrono chrono;
47 
48  if ( !M_blockPrecs.get() )
49  {
50  M_blockPrecs.reset (new ComposedOperator< composed_prec > (M_comm) );
51  }
52  if ( !set() )
53  {
54  M_overlapLevel = M_list.get ("overlap level", 2);
55  M_precType = M_list.get ("prectype", "Amesos");
56 
57  //////////////// \todo Copy: should be avoided ////////////////////////
58  M_matrixVector.push_back (*M_blocks[ (*M_blockReordering) [0]]);
59  M_matrixVector.push_back (*M_blocks[ (*M_blockReordering) [1]]);
60  M_matrixVector.push_back (*M_blocks[ (*M_blockReordering) [2]]);
61  M_matrixVector.push_back (*M_blocks[ (*M_blockReordering) [3]]);
62  /////////////////////////////////////////////////////////////
63 
64  for (ID k (0); k < M_blocks.size(); ++k)
65  {
66  M_blockPrecs->displayer().leaderPrint (" M- Computing double prec. factorization ... ");
67  chrono.start();
68  //////////////// \todo Copy: should be avoided ////////////////////////
69  if (!M_recompute[ (*M_blockReordering) [k]])
70  {
71  M_prec[k].reset (M_factory.Create (M_precType, M_matrixVector[k].matrixPtr().get(), M_overlapLevel) );
72  }
73  else
74  //////////////////////////////////////////////////////////////
75 
76  {
77  M_prec[k].reset (M_factory.Create (M_precType, M_blocks[ (*M_blockReordering) [k]]->matrixPtr().get(), M_overlapLevel) );
78  }
79  if ( !M_prec[k].get() )
80  {
81  ERROR_MSG ( "Preconditioner not set, something went wrong in its computation\n" );
82  }
83  M_prec[k]->SetParameters (M_list);
84  M_prec[k]->Initialize();
85  M_prec[k]->Compute();
86  chrono.stop();
87  M_blockPrecs->displayer().leaderPrintMax ("done in ", chrono.diff() );
88  }
89  }
90  else
91  {
92  for (ID k (0); k < M_blocks.size(); ++k)
93  {
94  if (M_recompute[ (*M_blockReordering) [k]])
95  {
96  M_blockPrecs->displayer().leaderPrint (" M- Computing double prec. factorization ... ");
97  chrono.start();
98  M_prec[k].reset (M_factory.Create (M_precType, M_blocks[ (*M_blockReordering) [k]]->matrixPtr().get(), M_overlapLevel) );
99  if ( !M_prec[k].get() )
100  {
101  ERROR_MSG ( "Preconditioner not set, something went wrong in its computation\n" );
102  }
103  M_prec[k]->SetParameters (M_list);
104  M_prec[k]->Initialize();
105  M_prec[k]->Compute();
106  chrono.stop();
107  M_blockPrecs->displayer().leaderPrintMax ("done in ", chrono.diff() );
108  }
109  else
110  {
111  M_blockPrecs->displayer().leaderPrint (" M- Reusing double prec. factorization ... \n");
112  }
113  }
114  }
115  M_firstCompPrec->push_back (M_prec[0], false, false);
116  M_firstCompPrec->push_back (M_prec[1], false, false);
117 
118  M_secondCompPrec->push_back (M_prec[2], false, false);
119  M_secondCompPrec->push_back (M_prec[3], false, false);
120 
121  //M_blockPrecs->resetOperator();
122  if (! (M_blockPrecs->number() ) )
123  {
124  M_blockPrecs->push_back (M_firstCompPrec, false, false, false);
125  M_blockPrecs->push_back (M_secondCompPrec, false, false, true /*sum*/);
126  }
127  else
128  {
129  M_blockPrecs->replace (M_firstCompPrec, (UInt) 0, false, false);
130  M_blockPrecs->replace (M_secondCompPrec, (UInt) 1, false, false);
131  }
132 
133  return linearSolver->solveSystem (rhs, step, std::static_pointer_cast<Epetra_Operator> (M_blockPrecs) );
134 }
135 
136 
137 
138 void MonolithicBlockComposedNN::setDataFromGetPot (const GetPot& data, const std::string& section)
139 {
140  PreconditionerIfpack::createIfpackList ( M_list, data, section, "ifpack");
141 }
142 
143 void MonolithicBlockComposedNN::coupler (mapPtr_Type& map,
144  const std::map<ID, ID>& locDofMap,
145  const vectorPtr_Type& numerationInterface,
146  const Real& timeStep,
147  const Real& coefficient,
148  const Real& rescaleFactor)
149 {
150  UInt totalDofs = map->map (Unique)->NumGlobalElements();
151  UInt fluidSolid = M_offset[0] + M_FESpace[0]->map().map (Unique)->NumGlobalElements();
152 
153  for (ID k = 0; k < 2; ++k)
154  {
155  M_blocks[k]->globalAssemble();
156  matrixPtr_Type block (new matrix_Type (*M_blocks[k]) );
157  M_blocks.push_back (block);
158  M_bch.push_back (M_bch[k]);
159  M_FESpace.push_back (M_FESpace[k]);
160  M_offset.push_back (M_offset[k]);
161  M_recompute[2 + k] = (M_recompute[k]);
162  }
163 
164  matrixPtr_Type coupling (new matrix_Type (*map) );
165 
166  coupling.reset (new matrix_Type (*map, 0) );
167  coupling->insertValueDiagonal (1., M_offset[fluid], M_offset[solid] );
168  coupling->insertValueDiagonal (1., fluidSolid, totalDofs);
169  couplingMatrix (coupling, (*M_couplingFlags) [0]/*8*/, M_FESpace, M_offset, locDofMap, numerationInterface, timeStep, 2., coefficient, rescaleFactor);
170  M_coupling.push_back (coupling);
171 
172  coupling.reset (new matrix_Type (*map, 0) );
173  coupling->insertValueDiagonal ( 1., M_offset[0], fluidSolid );
174  coupling->insertValueDiagonal ( 1., fluidSolid , totalDofs);
175  couplingMatrix (coupling, (*M_couplingFlags) [1]/*4*/, M_FESpace, M_offset, locDofMap, numerationInterface, timeStep, 2., coefficient, rescaleFactor);
176  M_coupling.push_back (coupling);
177 
178  coupling.reset (new matrix_Type (*map, 0) );
179  coupling->insertValueDiagonal (1., M_offset[fluid], M_offset[solid] );
180  coupling->insertValueDiagonal (-1, fluidSolid, totalDofs);
181  couplingMatrix (coupling, (*M_couplingFlags) [2]/*1*/, M_FESpace, M_offset, locDofMap, numerationInterface, timeStep, 2., coefficient, rescaleFactor);
182  M_coupling.push_back (coupling);
183 
184  coupling.reset (new matrix_Type (*map, 0) );
185  coupling->insertValueDiagonal ( 1., M_offset[0], fluidSolid );
186  coupling->insertValueDiagonal ( 1., fluidSolid, totalDofs );
187  couplingMatrix (coupling, (*M_couplingFlags) [3]/*2*/, M_FESpace, M_offset, locDofMap, numerationInterface, timeStep, 2., coefficient, rescaleFactor);
188  M_coupling.push_back (coupling);
189 
190  M_prec.resize (M_blocks.size() );
191 }
192 
193 void MonolithicBlockComposedNN::applyBoundaryConditions (const Real& time, const UInt i)
194 {
195  M_blocks[i]->openCrsMatrix();
196  if ( !M_bch[i]->bcUpdateDone() )
197  {
198  M_bch[i]->bcUpdate ( *M_FESpace[i]->mesh(), M_FESpace[i]->feBd(), M_FESpace[i]->dof() );
199  M_bch[i]->setOffset (M_offset[i]);
200  }
201  bcManageMatrix ( *M_blocks[i] , *M_FESpace[i]->mesh(), M_FESpace[i]->dof(), *M_bch[i], M_FESpace[i]->feBd(), 2., time);
202 }
203 
204 
205 void MonolithicBlockComposedNN::push_back_matrix (const matrixPtr_Type& Mat, const bool recompute)
206 {
207  Mat->globalAssemble();
208  *Mat *= 2.;
209  super_Type::push_back_matrix (Mat, recompute);
210 }
211 
212 
213 
214 void MonolithicBlockComposedNN::replace_matrix ( const matrixPtr_Type& oper, UInt position )
215 {
216  oper->globalAssemble();
217  *oper *= 2.;
218  M_blocks[position] = oper;
219  M_blocks[ (position + 2) % 4] = oper;
220 }
221 
222 } // Namespace LifeV
void updateInverseJacobian(const UInt &iQuadPt)
#define ERROR_MSG(A)
Definition: LifeAssert.hpp:69
uint32_type ID
IDs.
Definition: LifeV.hpp:194
double Real
Generic real data.
Definition: LifeV.hpp:175
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191