RepastHPC  2.3.1
DiffusionLayerND.h
1 /*
2  * Repast for High Performance Computing (Repast HPC)
3  *
4  * Copyright (c) 2010 Argonne National Laboratory
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with
8  * or without modification, are permitted provided that the following
9  * conditions are met:
10  *
11  * Redistributions of source code must retain the above copyright notice,
12  * this list of conditions and the following disclaimer.
13  *
14  * Redistributions in binary form must reproduce the above copyright notice,
15  * this list of conditions and the following disclaimer in the documentation
16  * and/or other materials provided with the distribution.
17  *
18  * Neither the name of the Argonne National Laboratory nor the names of its
19  * contributors may be used to endorse or promote products derived from
20  * this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE TRUSTEES OR
26  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
32  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  *
34  *
35  * DiffusionLayerND.h
36  *
37  * Created on: July 25, 2015
38  * Author: jtm
39  */
40 
41 #ifndef DIFFUSIONLAYERND_H_
42 #define DIFFUSIONLAYERND_H_
43 
44 #include <fstream>
45 #include <vector>
46 #include <map>
47 
48 #include "mpi.h"
49 
50 #include "RelativeLocation.h"
51 #include "CartesianTopology.h"
52 #include "RepastProcess.h"
53 #include "ValueLayerND.h"
54 
55 using namespace std;
56 
57 namespace repast {
58 
63 template<typename T>
64 class Diffusor{
65 
66 public:
67 
68  Diffusor();
69  virtual ~Diffusor();
70 
80  virtual int getRadius();
81 
96  virtual T getNewValue(T* values) = 0;
97 };
98 
99 
103 template<typename T>
105 
109 template<typename T>
111 
115 template<typename T>
117  return 1;
118 }
119 
146 template<typename T>
148 
149 private:
150 
151 public:
152 
153  DiffusionLayerND(vector<int> processesPerDim, GridDimensions globalBoundaries, int bufferSize, bool periodic, T initialValue = 0, T initialBufferZoneValue = 0);
154  virtual ~DiffusionLayerND();
155 
171  void diffuse(Diffusor<T>* diffusor, bool omitSynchronize = false);
172 
173 private:
174 
179  void diffuseDimension(T* currentDataSpacePointer, T* otherDataSpacePointer, T* vals, Diffusor<T>* diffusor, int dimIndex);
180 
184  void grabDimensionData(T*& destinationPointer, T* startPointer, int radius, int dimIndex);
185 };
186 
187 
188 template<typename T>
189 DiffusionLayerND<T>::DiffusionLayerND(vector<int> processesPerDim, GridDimensions globalBoundaries, int bufferSize, bool periodic,
190  T initialValue, T initialBufferZoneValue): ValueLayerNDSU<T>(processesPerDim, globalBoundaries, bufferSize, periodic,
191  initialValue, initialBufferZoneValue){
192 
193 }
194 
195 template<typename T>
196 DiffusionLayerND<T>::~DiffusionLayerND(){
197 }
198 
199 template<typename T>
200 void DiffusionLayerND<T>::diffuse(Diffusor<T>* diffusor, bool omitSynchronize){
201  int countOfVals = (int)(pow(diffusor->getRadius() * 2 + 1, AbstractValueLayerND<T>::numDims));
202  T* vals = new T[countOfVals];
203 
205 
206  this->switchValueLayer();
207 
208  if(!omitSynchronize) this->synchronize();
209 
210  delete[] vals;
211 }
212 
213 template<typename T>
214 void DiffusionLayerND<T>::diffuseDimension(T* currentDataSpacePointer, T* otherDataSpacePointer, T* vals, Diffusor<T>* diffusor, int dimIndex){
215  int bufferEdge = AbstractValueLayerND<T>::dimensionData[dimIndex].leftBufferSize;
216  int localEdge = bufferEdge + AbstractValueLayerND<T>::dimensionData[dimIndex].localWidth;
217 
218  int pointerIncrement = AbstractValueLayerND<T>::places[dimIndex];
219 
220  int i = 0;
221  for(; i < bufferEdge; i++){
222  // Increment the pointers
223  currentDataSpacePointer += pointerIncrement;
224  otherDataSpacePointer += pointerIncrement;
225  }
226  for(; i < localEdge; i++){
227  if(dimIndex == 0){
228  // Populate the vals array
229  T* destLocation = vals; // Note: This gets passed as a handle and changed
230  grabDimensionData(destLocation, currentDataSpacePointer, diffusor->getRadius(), AbstractValueLayerND<T>::numDims - 1);
231  *otherDataSpacePointer = diffusor->getNewValue(vals);
232  }
233  else{
234  diffuseDimension(currentDataSpacePointer, otherDataSpacePointer, vals, diffusor, dimIndex - 1);
235  }
236  // Increment the pointers
237  currentDataSpacePointer += pointerIncrement;
238  otherDataSpacePointer += pointerIncrement;
239  }
240 }
241 
242 template<typename T>
243 void DiffusionLayerND<T>::grabDimensionData(T*& destinationPointer, T* startPointer, int radius, int dimIndex){
244  int pointerIncrement = AbstractValueLayerND<T>::places[dimIndex];
245  startPointer -= pointerIncrement * radius; // Go back
246  int size = 2 * radius + 1;
247  for(int i = 0; i < size; i++){
248  if(dimIndex == 0){
249  *destinationPointer = 1;
250  double myVal = *startPointer;
251  *destinationPointer = myVal;
252  destinationPointer++; // Handle; all recursive instances share
253  }
254  else{
255  grabDimensionData(destinationPointer, startPointer, radius, dimIndex - 1);
256  }
257  startPointer += pointerIncrement;
258  }
259 
260 }
261 
262 
263 
264 }
265 
266 #endif /* DIFFUSIONLAYERND_H_ */
repast::DiffusionLayerND::diffuse
void diffuse(Diffusor< T > *diffusor, bool omitSynchronize=false)
Performs the diffusion operation on the entire grid (only within local boundaries) If omit synchroniz...
Definition: DiffusionLayerND.h:200
repast::Diffusor
A Diffusor is a custom class that performs diffusion.
Definition: DiffusionLayerND.h:64
repast::Diffusor::getNewValue
virtual T getNewValue(T *values)=0
Given a list of values that represent the values in adjacent cells, return the value that should be p...
repast::AbstractValueLayerND
An AbstractValueLayerND is the abstract parent class for N-dimensional value layers.
Definition: ValueLayerND.h:253
repast::GridDimensions
Basic structure for specifying grid dimenions.
Definition: GridDimensions.h:58
repast::Diffusor::getRadius
virtual int getRadius()
Implementing classes must return the value that is the number of concentric layers that are used in d...
Definition: DiffusionLayerND.h:116
repast::ValueLayerNDSU
ValueLayerNDSU is a version of the ValueLayerND class that facilitates SynchronousUpdating: that is,...
Definition: ValueLayerND.h:892
repast::DiffusionLayerND
The DiffusionLayerND class is an N-dimensional layer of double values that can be used to diffuse thr...
Definition: DiffusionLayerND.h:147