Memosa-FVM  0.2
GradientMatrix.h
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 #ifndef _GRADIENTMATRIX_H_
6 #define _GRADIENTMATRIX_H_
7 
8 #include <set>
9 
10 #ifdef FVM_PARALLEL
11 #include <mpi.h>
12 #endif
13 
14 #include "Mesh.h"
15 #include "CRConnectivity.h"
16 #include "Array.h"
17 #include "StorageSite.h"
18 #include "Gradient.h"
19 
21 {
22  public:
23  typedef pair<const StorageSite*, const StorageSite*> EntryIndex;
24  typedef map<EntryIndex, shared_ptr<ArrayBase> > GhostArrayMap;
26  virtual void syncLocal() {};
27  virtual ~GradientMatrixBase() {}
28 };
29 
30 template<class T_Scalar>
32 {
33 public:
35 
36  GradientMatrix(const Mesh& mesh) :
37  _mesh(mesh),
38 #ifdef FVM_PARALLEL
39  _conn(mesh.getCellCellsGhostExt()),
40  _row(_conn.getRow() ),
41  _col(_conn.getCol() ),
42 #else
43  _conn(mesh.getCellCells()),
44  _row(_conn.getRow()),
45  _col(_conn.getCol()),
46 #endif
47  _coeffs(_col.getLength()),
49  {
50  }
51 
52  virtual ~GradientMatrix()
53  {}
54 
55  template<class X>
56  shared_ptr<Array<Gradient<X> > >
57  getGradient(const Array<X>& x) const
58  {
59  typedef Gradient<X> GradType;
60  typedef Array<GradType> GradArray;
61 
62  shared_ptr<GradArray> gradXPtr(new GradArray(x.getLength()));
63  GradArray& gradX = *gradXPtr;
64 
65  const int nRows = getConnectivity().getRowSite().getSelfCount();
66  for(int nr=0; nr<nRows; nr++)
67  {
68  gradX[nr].zero();
69  for (int nb = _row[nr]; nb<_row[nr+1]; nb++)
70  {
71  const int j = _col[nb];
72  gradX[nr].accumulate(_coeffs[nb],x[j]-x[nr]);
73  }
74  }
75  return gradXPtr;
76  }
77 
78  template<class X>
79  void
80  computeGradient(Gradient<X>& g, const Array<X>& x, int i) const
81  {
82  g.zero();
83 
84  // for boundaries use the adjacent cell
85  if (_row[i+1] - _row[i] == 1)
86  i = _col[_row[i]];
87 
88  for (int nb = _row[i]; nb<_row[i+1]; nb++)
89  {
90  const int j = _col[nb];
91  g.accumulate(_coeffs[nb],x[j]-x[i]);
92  }
93  }
94 
95  template<class X>
96  X
97  computeR(const Gradient<X>& g, const Array<X>& x, const Coord dist, int i, int j) const
98  {//Darwish and Moukalled, Int. J. H. M. T., 46 (2003) 599-611
99 
100  X den=x[j]-x[i];
101  X num=2.*(g*dist);
102  if (den!=0.)
103  return num/den-1.;
104  return 0;
105  }
106 
107  template<class X>
108  void
109  computeFaceGradient(Gradient<X>& g, const Array<X>& x, int i) const
110  {
111  g.zero();
112 
113  // for boundaries use the adjacent cell
114  if (_row[i+1] - _row[i] == 1)
115  i = _col[_row[i]];
116 
117  for (int nb = _row[i]; nb<_row[i+1]; nb++)
118  {
119  const int j = _col[nb];
120  g.accumulate(_coeffs[nb],x[j]);
121  }
122  }
123 
124  const CRConnectivity& getConnectivity() const {return _conn;}
125 
127  const Array<Coord>& getCoeffs() const {return _coeffs;}
128 
129  Coord& getCoeff(const int i, const int j)
130  {
131  for (int nnb = _row[i]; nnb<_row[i+1]; nnb++)
132  {
133  if (_col[nnb] == j)
134  return _coeffs[nnb];
135  }
136 
137  throw CException("invalid indices");
138  }
139 
140 
141  const Coord& getCoeff(const int i, const int j) const
142  {
143  for (int nnb = _row[i]; nnb<_row[i+1]; nnb++)
144  {
145  if (_col[nnb] == j)
146  return _coeffs[nnb];
147  }
148  throw CException("invalid indices");
149  }
150 
151 
152 
153 
155  {
156  public:
158  const Array<Vector<int,2> >& pairToCol) :
159  _coeffs(coeffs),
160  _pairToCol(pairToCol)
161  {}
162 
163  Coord& getCoeff01(const int np)
164  {
165  return _coeffs[_pairToCol[np][0]];
166  }
167 
168  Coord& getCoeff10(const int np)
169  {
170  return _coeffs[_pairToCol[np][1]];
171  }
172  private:
173 
174 
177  };
178 
180  {
181  if (_pairWiseAssemblers.find(&pairs) == _pairWiseAssemblers.end())
182  {
183  _pairWiseAssemblers[&pairs] =
185  getConnectivity().getPairToColMapping(pairs));
186  }
187  return *_pairWiseAssemblers[&pairs];
188  }
189 
190 
191  //fill scatterArray (both mesh and partition) and only gatherArray for mesh
193  {
194 #ifdef FVM_PARALLEL
195  //SENDING allocation and filling
196  const StorageSite& site = _mesh.getCells();
197  const CRConnectivity& cellCells = _mesh.getCellCells();
198  const StorageSite::ScatterMap& scatterMap = site.getScatterMap();
199  foreach(const StorageSite::ScatterMap::value_type& mpos, scatterMap){
200  const StorageSite& oSite = *mpos.first;
201  const Array<int>& scatterArray = *mpos.second;
202  //loop over surround indices and itself for sizing
203  EntryIndex e(&site,&oSite);
204  int sendSize = 0;
205  for ( int i = 0; i < scatterArray.getLength(); i++ ){
206  sendSize += cellCells.getCount( scatterArray[i] );
207  }
208  //allocate array
209  _sendValues[e] = shared_ptr< Array<Coord> > ( new Array<Coord> (sendSize) );
210  //fill send array
211  Array<Coord>& valueArray = dynamic_cast< Array<Coord>& > ( *_sendValues[e] );
212  int indx = 0;
213  for( int i = 0; i < scatterArray.getLength(); i++ ){
214  const int ii = scatterArray[i];
215  for ( int j = 0; j < cellCells.getCount(ii); j++ ){
216  const int jj = cellCells(ii,j);
217  valueArray[indx] = getCoeff(ii,jj);
218  indx++;
219  }
220  }
221  }
222  //RECIEVING allocation (filling will be done by MPI Communication)
223  const StorageSite::GatherMap& gatherMap = site.getGatherMap();
224  foreach(const StorageSite::GatherMap::value_type& mpos, gatherMap){
225  const StorageSite& oSite = *mpos.first;
226  EntryIndex e(&oSite,&site);
227  //get recvSize
228  const Array<int>& recvCounts = dynamic_cast< const Array<int>& > (_mesh.getRecvCounts(e));
229  int recvSize = 0;
230  for ( int i = 0; i < recvCounts.getLength(); i++ ){
231  recvSize += recvCounts[i];
232  }
233  //allocate array
234  _recvValues [e] = shared_ptr< Array<Coord> > ( new Array<Coord> (recvSize) );
235  }
236 #endif
237  }
238 
239  //fill scatterArray (both mesh and partition) and only gatherArray for mesh
241  {
242 #ifdef FVM_PARALLEL
243  //RECIEVING allocation (filling will be done by MPI Communication)
244  const StorageSite& site = _mesh.getCells();
245  const StorageSite::GatherMap& gatherMap = site.getGatherMap();
246  foreach(const StorageSite::GatherMap::value_type& mpos, gatherMap){
247  const StorageSite& oSite = *mpos.first;
248  EntryIndex e(&oSite,&site);
249  //get recvSize
250  //mesh interface can be done know
251  if ( oSite.getGatherProcID() == - 1) {
252  *_recvValues[e] = *_sendValues [e];
253  }
254  }
255 #endif
256  }
257 
258  //sending values
259  void syncValues()
260  {
261 #ifdef FVM_PARALLEL
262  //SENDING
263  const int request_size = get_request_size();
264  MPI::Request request_send[ request_size ];
265  MPI::Request request_recv[ request_size ];
266  int indxSend = 0;
267  int indxRecv = 0;
268  const StorageSite& site = _mesh.getCells();
269  const StorageSite::ScatterMap& scatterMap = site.getScatterMap();
270  foreach(const StorageSite::ScatterMap::value_type& mpos, scatterMap){
271  const StorageSite& oSite = *mpos.first;
272  EntryIndex e(&site,&oSite);
273  //checking if storage site is only site or ghost site, we only communicate ghost site ( oSite.getCount() == -1 )
274  ArrayBase& sendArray = *_sendValues[e];
275  //loop over surround indices and itself
276  int to_where = oSite.getGatherProcID();
277  if ( to_where != -1 ){
278  int mpi_tag = oSite.getTag();
279  request_send[indxSend++] =
280  MPI::COMM_WORLD.Isend( sendArray.getData(), sendArray.getDataSize(), MPI::BYTE, to_where, mpi_tag );
281  }
282  }
283  //RECIEVING
284  //getting values from other meshes to fill g
285  const StorageSite::GatherMap& gatherMap = site.getGatherMap();
286  foreach(const StorageSite::GatherMap::value_type& mpos, gatherMap){
287  const StorageSite& oSite = *mpos.first;
288  //checking if storage site is only site or ghost site, we only communicate ghost site ( oSite.getCount() == -1 )
289  EntryIndex e(&oSite,&site);
290  ArrayBase& recvArray = *_recvValues[e];
291  int from_where = oSite.getGatherProcID();
292  if ( from_where != -1 ){
293  int mpi_tag = oSite.getTag();
294  request_recv[indxRecv++] =
295  MPI::COMM_WORLD.Irecv( recvArray.getData(), recvArray.getDataSize(), MPI::BYTE, from_where, mpi_tag );
296  }
297  }
298 
299  int count = get_request_size();
300  MPI::Request::Waitall( count, request_recv );
301  MPI::Request::Waitall( count, request_send );
302 
303 // const StorageSite& site = _mesh.getCells();
304 // const StorageSite::GatherMap& gatherMap = site.getGatherMap();
305 
306  //replacing values
307  const map<int,int>& globalToLocal = _mesh.getGlobalToLocal();
308  foreach(const StorageSite::GatherMap::value_type& mpos, gatherMap){
309  const StorageSite& oSite = *mpos.first;
310  const Array<int>& gatherArray = dynamic_cast< const Array<int>& > (*mpos.second);
311  //checking if storage site is only site or ghost site, we only communicate ghost site ( oSite.getCount() == -1 )
312  int from_where = oSite.getGatherProcID();
313  if ( from_where != -1 ){
314  EntryIndex e(&oSite,&site);
315  const Array<int> & recv_counts = dynamic_cast< const Array<int>& > (_mesh.getRecvCounts(e) );
316  const Array<int> & recv_indices = dynamic_cast< const Array<int>& > (_mesh.getRecvIndices(e));
317  const Array<Coord>& recv_values = dynamic_cast< const Array<Coord>& > (*_recvValues [e]);
318 
319  //loop over gatherArray
320  int indx = 0;
321  for ( int i = 0; i < gatherArray.getLength(); i++ ){
322  const int ii = gatherArray[i];
323  const int nnb = recv_counts[i]; //give getCount()
324  for ( int nb = 0; nb < nnb; nb++ ){
325  const int jj = globalToLocal.find( recv_indices[indx] )->second;
326  Coord& matrix_entry = getCoeff(ii,jj);
327  matrix_entry = recv_values[indx];
328  indx++;
329  }
330  }
331  }
332  }
333 
334 #endif
335  }
336 
337 
338 
339 
340 
341 private:
342 
344  {
345  int indx = 0;
346  const StorageSite& site = _mesh.getCells();
347  const StorageSite::ScatterMap& scatterMap = site.getScatterMap();
348  foreach(const StorageSite::ScatterMap::value_type& mpos, scatterMap){
349  const StorageSite& oSite = *mpos.first;
350  //checking if storage site is only site or ghost site, we only communicate ghost site ( oSite.getCount() == -1 )
351  if ( oSite.getGatherProcID() != -1 )
352  indx++;
353  }
354  return indx;
355  }
356 
357 
358  virtual void printRow(const int i) const
359  {
360 
361  for (int nb = _row[i]; nb<_row[i+1]; nb++)
362  {
363  const int j = _col[nb];
364  cout << "coeff (" << i << "," << j << ") = " << _coeffs[nb] << endl;
365  }
366  }
367 
368  const Mesh& _mesh;
370  const Array<int>& _row;
371  const Array<int>& _col;
372 
373 
375  mutable map<const CRConnectivity*,PairWiseAssembler*> _pairWiseAssemblers;
376 
377 #ifdef FVM_PARALLEL
378  GhostArrayMap _sendValues;
379  GhostArrayMap _recvValues;
380 #endif
381 };
382 
383 
384 #endif
GradientMatrix(const Mesh &mesh)
int getCount(const int i) const
virtual int getDataSize() const =0
int getSelfCount() const
Definition: StorageSite.h:40
const Array< Coord > & getCoeffs() const
const Array< int > & _row
const Mesh & _mesh
Coord & getCoeff01(const int np)
virtual void syncLocal()
Coord & getCoeff10(const int np)
const ArrayBase & getRecvIndices(const EntryIndex &e) const
Definition: Mesh.h:281
X computeR(const Gradient< X > &g, const Array< X > &x, const Coord dist, int i, int j) const
Definition: Mesh.h:49
Coord & getCoeff(const int i, const int j)
PairWiseAssembler & getPairWiseAssembler(const CRConnectivity &pairs)
map< int, int > & getGlobalToLocal()
Definition: Mesh.h:243
pair< const StorageSite *, const StorageSite * > EntryIndex
const Coord & getCoeff(const int i, const int j) const
PairWiseAssembler(Array< Coord > &coeffs, const Array< Vector< int, 2 > > &pairToCol)
const Array< Vector< int, 2 > > & _pairToCol
virtual void printRow(const int i) const
Vector< T_Scalar, 3 > Coord
Array< Coord > & getCoeffs()
const CRConnectivity & getConnectivity() const
Array< Coord > _coeffs
int getTag() const
Definition: StorageSite.h:84
int getGatherProcID() const
Definition: StorageSite.h:83
const ArrayBase & getRecvCounts(const EntryIndex &e) const
Definition: Mesh.h:280
map< EntryIndex, shared_ptr< ArrayBase > > GhostArrayMap
const CRConnectivity & getCellCells() const
Definition: Mesh.cpp:480
const StorageSite & getCells() const
Definition: Mesh.h:109
const CRConnectivity & _conn
void accumulate(const Coord &wt, const T &v)
Definition: Gradient.h:57
const ScatterMap & getScatterMap() const
Definition: StorageSite.h:58
virtual ~GradientMatrix()
map< const StorageSite *, shared_ptr< Array< int > > > ScatterMap
Definition: StorageSite.h:23
virtual ~GradientMatrixBase()
shared_ptr< Array< Gradient< X > > > getGradient(const Array< X > &x) const
const GatherMap & getGatherMap() const
Definition: StorageSite.h:59
void recvScatterGatherValuesBufferLocal()
void zero()
Definition: Gradient.h:122
virtual void * getData() const =0
void computeFaceGradient(Gradient< X > &g, const Array< X > &x, int i) const
map< const StorageSite *, shared_ptr< Array< int > > > GatherMap
Definition: StorageSite.h:24
void computeGradient(Gradient< X > &g, const Array< X > &x, int i) const
const StorageSite & getRowSite() const
map< const CRConnectivity *, PairWiseAssembler * > _pairWiseAssemblers
const Array< int > & _col
int getLength() const
Definition: Array.h:87
void createScatterGatherValuesBuffer()