Memosa-FVM  0.2
LinearSystem.cpp
Go to the documentation of this file.
1 // This file os part of FVM
2 // Copyright (c) 2012 FVM Authors
3 // See LICENSE file for terms.
4 
5 #ifdef FVM_PARALLEL
6 #include <mpi.h>
7 #endif
8 
9 #include "LinearSystem.h"
10 #include "Array.h"
11 #include "Field.h"
12 
14  isSymmetric(false),
15  _x(new MultiField()),
16  _b(),
17  _delta(),
18  _residual(),
19  _coarseIndex(),
20  _coarseningField(0)
21 {}
22 
24 {
25 
26 
27 }
28 
29 
30 
31 void
33 {
35  _b = dynamic_pointer_cast<MultiField>(_x->newClone());
36  _b->zero();
37 }
38 
39 void
41 {
42  _delta = dynamic_pointer_cast<MultiField>(_x->newClone());
43  _residual = dynamic_pointer_cast<MultiField>(_x->newClone());
44  _delta->zero();
45  _residual->zero();
46 
47 
48  MultiField::ArrayIndexList indicesToRemove;
49 
50  const MultiField::ArrayIndexList& arrayIndices = _b->getArrayIndices();
51  foreach(MultiField::ArrayIndex i, arrayIndices)
52  {
53  if (!_matrix.hasMatrix(i,i) || _matrix.getMatrix(i,i).isInvertible())
54  indicesToRemove.push_back(i);
55  else
57  }
58 
59  _xAux = _x->extract(indicesToRemove);
60  _bAux = _b->extract(indicesToRemove);
61  _deltaAux = _delta->extract(indicesToRemove);
62  _residualAux = _residual->extract(indicesToRemove);
63 
64 }
65 
66 shared_ptr<LinearSystem>
67 LinearSystem::createCoarse(const int groupSize, const double weightRatioThreshold)
68 {
69 
70  shared_ptr<LinearSystem> coarseLS(new LinearSystem());
79  // keep track of which fieldIndex was used for coarsening each site
80  map<const StorageSite*, const Field *> sitesCoarsenedWithField;
81 
82 
83  const MultiField::ArrayIndexList& arrayIndices = _b->getArrayIndices();
84  foreach(MultiField::ArrayIndex ai,arrayIndices)
85  {
86  const Field *fieldIndex = ai.first;
87  const StorageSite *site = ai.second;
88 
89  if (!_coarseningField || fieldIndex == _coarseningField)
90  {
91  if (sitesCoarsenedWithField.find(site) == sitesCoarsenedWithField.end())
92  {
93  sitesCoarsenedWithField[site] = fieldIndex;
94  const ArrayBase& bi = (*_b)[ai];
95  shared_ptr<Array<int> > cIndex(new Array<int>(bi.getLength()));
96  _coarseIndex.addArray(ai,cIndex);
97 
98  }
99  }
100 
101  }
102 
111  _matrix.createCoarsening(_coarseIndex,groupSize,weightRatioThreshold);
112 
113  _coarseIndex.sync();
114 
115 
117 
118 
119  // we can now create the coarse sites for each fine site
120  foreach(MultiField::ArrayIndex k,arrayIndices)
121  {
122  // we will only have entries for indices which were selected to be coarsened
123  if (_matrix._coarseSizes.find(k) != _matrix._coarseSizes.end())
124  {
125  int selfSize = _matrix._coarseSizes[k];
126  int ghostSize = _matrix._coarseGhostSizes[k];
127  _matrix._coarseSites[k] =
128  shared_ptr<StorageSite>(new StorageSite(selfSize,ghostSize));
129  }
130  }
131 
132  // set the mappers in the newly created coarse sites
133  foreach(MultiField::ArrayIndex k,arrayIndices)
134  {
135  if (_matrix._coarseSites.find(k) != _matrix._coarseSites.end())
136  {
137  const StorageSite& fineSite = *k.second;
138 
139  StorageSite& coarseSite = *_matrix._coarseSites[k];
140 
141  const StorageSite::ScatterMap& fineScatterMap = fineSite.getScatterMap();
142  StorageSite::ScatterMap& coarseScatterMap = coarseSite.getScatterMap();
143 
144  foreach(const StorageSite::ScatterMap::value_type& pos, fineScatterMap)
145  {
146  const StorageSite& fineOSite = *pos.first;
147  MultiField::ArrayIndex kO(k.first,&fineOSite);
148 
149 
150 #ifdef FVM_PARALLEL
151  // the ghost site will not have its corresponding coarse
152  // site created yet so we create it here
153  if (_matrix._coarseSites.find(kO) == _matrix._coarseSites.end())
154  {
155  shared_ptr<StorageSite> ghostSite
156  (new StorageSite(-1));
157  ghostSite->setGatherProcID ( fineOSite.getGatherProcID() );
158  ghostSite->setScatterProcID( fineOSite.getScatterProcID() );
159  ghostSite->setTag( fineOSite.getTag() );
160  _matrix._coarseSites[kO] = ghostSite;
161  }
162 #endif
163  const StorageSite& coarseOSite = *_matrix._coarseSites[kO];
164  MultiFieldMatrix::SSPair sskey(&fineSite,&fineOSite);
165  coarseScatterMap[&coarseOSite] = _matrix._coarseScatterMaps[sskey];
166  }
167 
168  const StorageSite::GatherMap& fineGatherMap = fineSite.getGatherMap();
169  StorageSite::GatherMap& coarseGatherMap = coarseSite.getGatherMap();
170  foreach(const StorageSite::GatherMap::value_type& pos, fineGatherMap)
171  {
172  const StorageSite& fineOSite = *pos.first;
173  MultiField::ArrayIndex kO(k.first,&fineOSite);
174  const StorageSite& coarseOSite = *_matrix._coarseSites[kO];
175  MultiFieldMatrix::SSPair sskey(&fineSite,&fineOSite);
176 
177 
178  coarseGatherMap[&coarseOSite] = _matrix._coarseGatherMaps[sskey];
179  }
180 
181 
182  }
183  }
184 
185  // create the connectivities for the coarse matrices
187 
197  foreach(MultiField::ArrayIndex k,arrayIndices)
198  {
199  const StorageSite *site = k.second;
200  if (_matrix._coarseSites.find(k) == _matrix._coarseSites.end())
201  {
202  const Field* fieldIndexUsedForCoarsening = sitesCoarsenedWithField[site];
203  MultiField::ArrayIndex indexCoarsened(fieldIndexUsedForCoarsening,site);
204  _coarseIndex.addArray(k, _coarseIndex.getArrayPtr(indexCoarsened));
205  _matrix._coarseSizes[k] = _matrix._coarseSizes[indexCoarsened];
206  _matrix._coarseGhostSizes[k] = _matrix._coarseGhostSizes[indexCoarsened];
207  _matrix._coarseSites[k] = _matrix._coarseSites[indexCoarsened];
209  }
210  }
211 
214  foreach(MultiField::ArrayIndex fineRowIndex,arrayIndices)
215  {
216  MultiField::ArrayIndex coarseRowIndex (fineRowIndex.first,
217  _matrix._coarseSites[fineRowIndex].get());
218  foreach(MultiField::ArrayIndex fineColIndex,arrayIndices)
219  {
220  MultiFieldMatrix::EntryIndex fineEntryIndex(fineRowIndex,fineColIndex);
221  if (_matrix.hasMatrix(fineRowIndex,fineColIndex))
222  {
223  MultiField::ArrayIndex coarseColIndex(fineColIndex.first,
224  _matrix._coarseSites[fineColIndex].get());
225  MultiFieldMatrix::EntryIndex coarseEntryIndex(coarseRowIndex,coarseColIndex);
226  coarseLS->_matrix._matrices[coarseEntryIndex] =
227  _matrix._coarseMatrices[fineEntryIndex];
228  }
229  }
230  }
231 
232  coarseLS->_b = shared_ptr<MultiField>(new MultiField());
233 
234  foreach(MultiField::ArrayIndex k,arrayIndices)
235  {
236  const StorageSite& coarseSite = *_matrix._coarseSites[k];
237  MultiField::ArrayIndex coarseIndex(k.first,&coarseSite);
238  coarseLS->_b->addArray(coarseIndex, (*_b)[k].newSizedClone(coarseSite.getCount()));
239  }
240 
241  coarseLS->_b->zero();
242  coarseLS->_delta = dynamic_pointer_cast<MultiField>(coarseLS->_b->newClone());
243  coarseLS->_delta->zero();
244  coarseLS->_residual = dynamic_pointer_cast<MultiField>(coarseLS->_b->newClone());
245  coarseLS->_residual->zero();
246 
247  return coarseLS;
248 }
249 
251 {
253 
254  if (_xAux)
255  {
256  _x->merge(*_xAux);
257  _b->merge(*_bAux);
258  _delta->merge(*_deltaAux);
259  _residual->merge(*_residualAux);
260 
262  }
263 }
264 
266 {
267  *_x += *_delta;
268  _x->sync();
269 }
270 
shared_ptr< MultiField > _delta
Definition: LinearSystem.h:56
MatrixSizeMap _coarseGhostSizes
void initAssembly()
Matrix & getMatrix(const Index &rowIndex, const Index &colIndex)
virtual int getLength() const =0
void createCoarseToFineMapping(const MultiField &coarseIndexField)
void createCoarseConnectivity(MultiField &coarseIndex)
Definition: Field.h:14
shared_ptr< MultiField > _b
Definition: LinearSystem.h:55
bool hasMatrix(const Index &rowIndex, const Index &colIndex) const
shared_ptr< MultiField > _x
Definition: LinearSystem.h:54
void createCoarsening(MultiField &coarseIndex, const int groupSize, const double weightRatioThreshold)
shared_ptr< ArrayBase > getArrayPtr(const ArrayIndex &)
Definition: MultiField.cpp:67
CoarseToFineMappingMap _coarseToFineMappings
virtual void zero()
Definition: MultiField.cpp:115
StorageSiteMap _coarseSites
shared_ptr< MultiField > _residual
Definition: LinearSystem.h:57
shared_ptr< MultiField > _bAux
Definition: LinearSystem.h:61
void updateSolution()
int getTag() const
Definition: StorageSite.h:84
pair< const Field *, const StorageSite * > ArrayIndex
Definition: MultiField.h:21
int getScatterProcID() const
Definition: StorageSite.h:82
int getGatherProcID() const
Definition: StorageSite.h:83
void initSolve()
shared_ptr< MultiField > _residualAux
Definition: LinearSystem.h:63
MatrixMap _coarseMatrices
vector< ArrayIndex > ArrayIndexList
Definition: MultiField.h:24
shared_ptr< LinearSystem > createCoarse(const int groupSize, const double weightRatioThreshold)
virtual bool isInvertible()
Definition: Matrix.h:73
void createCoarseMatrices(MultiField &coarseIndex)
MultiField _coarseIndex
Definition: LinearSystem.h:58
const ScatterMap & getScatterMap() const
Definition: StorageSite.h:58
MatrixMappersMap _coarseGatherMaps
shared_ptr< MultiField > _xAux
Definition: LinearSystem.h:60
map< const StorageSite *, shared_ptr< Array< int > > > ScatterMap
Definition: StorageSite.h:23
MatrixMappersMap _coarseScatterMaps
MultiFieldMatrix _matrix
Definition: LinearSystem.h:53
virtual void eliminateBoundaryEquations(IContainer &xB)
Definition: Matrix.h:50
const GatherMap & getGatherMap() const
Definition: StorageSite.h:59
int getCount() const
Definition: StorageSite.h:39
map< const StorageSite *, shared_ptr< Array< int > > > GatherMap
Definition: StorageSite.h:24
void addArray(const ArrayIndex &aIndex, shared_ptr< ArrayBase > a)
Definition: MultiField.cpp:270
const Field * _coarseningField
Definition: LinearSystem.h:59
pair< Index, Index > EntryIndex
shared_ptr< MultiField > _deltaAux
Definition: LinearSystem.h:62
virtual ~LinearSystem()
void syncGhostCoarsening(MultiField &coarseIndexField)
MatrixSizeMap _coarseSizes
void sync()
Definition: MultiField.cpp:489
pair< const StorageSite *, const StorageSite * > SSPair
virtual void solveBoundary(IContainer &xB, const IContainer &bB, IContainer &temp) const