XdmfMap.cpp 10.4 KB
Newer Older
Kenneth Leiter's avatar
Kenneth Leiter committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/*****************************************************************************/
/*                                    XDMF                                   */
/*                       eXtensible Data Model and Format                    */
/*                                                                           */
/*  Id : XdmfMap.cpp                                                         */
/*                                                                           */
/*  Author:                                                                  */
/*     Kenneth Leiter                                                        */
/*     kenneth.leiter@arl.army.mil                                           */
/*     US Army Research Laboratory                                           */
/*     Aberdeen Proving Ground, MD                                           */
/*                                                                           */
/*     Copyright @ 2011 US Army Research Laboratory                          */
/*     All Rights Reserved                                                   */
/*     See Copyright.txt for details                                         */
/*                                                                           */
/*     This software is distributed WITHOUT ANY WARRANTY; without            */
/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
/*     for more information.                                                 */
/*                                                                           */
/*****************************************************************************/

24
#include "XdmfAttribute.hpp"
25
#include "XdmfError.hpp"
26 27
#include "XdmfGridCollection.hpp"
#include "XdmfGridCollectionType.hpp"
28
#include "XdmfHeavyDataController.hpp"
29 30
#include "XdmfMap.hpp"

31
shared_ptr<XdmfMap>
32
XdmfMap::New()
33
{
34
  shared_ptr<XdmfMap> p(new XdmfMap());
35
  return p;
36 37
}

38 39
std::vector<shared_ptr<XdmfMap> >
XdmfMap::New(const std::vector<shared_ptr<XdmfAttribute> > & globalNodeIds)
40
{
41
  // globalNodeId | taskId | localNodeId at taskId
42
  std::map<node_id, std::map<task_id, node_id> > globalNodeIdMap;
43

44
  // fill globalNodeIdMap using globalNodeIds
45
  for(unsigned int i=0; i<globalNodeIds.size(); ++i) {
46
    const shared_ptr<XdmfAttribute> currGlobalNodeIds = globalNodeIds[i];
47
    for(unsigned int j=0; j<currGlobalNodeIds->getSize(); ++j) {
48
      const node_id currGlobalNodeId = currGlobalNodeIds->getValue<node_id>(j);
49 50 51
      globalNodeIdMap[currGlobalNodeId][i] = j;
    }
  }
52

53
  std::vector<shared_ptr<XdmfMap> > returnValue;
54 55 56
  returnValue.resize(globalNodeIds.size());

  // fill maps for each partition
57
  for(unsigned int i=0; i<globalNodeIds.size(); ++i)  {
58
    shared_ptr<XdmfMap> map = XdmfMap::New();
59
    returnValue[i] = map;
60 61
    const shared_ptr<XdmfAttribute> currGlobalNodeIds = globalNodeIds[i];

62
    for(unsigned int j=0; j<currGlobalNodeIds->getSize(); ++j) {
63 64 65 66
      const node_id currGlobalNodeId = currGlobalNodeIds->getValue<node_id>(j);
      const std::map<task_id, node_id> & currMap = 
        globalNodeIdMap[currGlobalNodeId];
      if(currMap.size() > 1) {
67
        for(std::map<task_id, node_id>::const_iterator iter = currMap.begin();
68
            iter != currMap.end();
69 70
            ++iter) {
          if(iter->first != i) {
71
            map->insert(iter->first, j, iter->second);
72 73 74 75 76
          }
        }
      }
    }
  }
77

78
  return returnValue;
79 80
}

81 82
XdmfMap::XdmfMap() :
  mName("")
83 84 85 86 87 88 89 90 91
{
}

XdmfMap::~XdmfMap()
{
}

const std::string XdmfMap::ItemTag = "Map";

92 93
std::map<std::string, std::string>
XdmfMap::getItemProperties() const
94
{
95
  std::map<std::string, std::string> mapProperties;
96
  mapProperties["Name"] = mName;
97
  return mapProperties;
98 99
}

100 101
std::string
XdmfMap::getItemTag() const
102
{
103
  return ItemTag;
104 105
}

106
std::map<XdmfMap::task_id, XdmfMap::node_id_map>
107
XdmfMap::getMap() const
108
{
109 110 111
  return mMap;
}

112 113 114 115 116 117
std::string
XdmfMap::getName() const
{
  return mName;
}

118 119 120
XdmfMap::node_id_map
XdmfMap::getRemoteNodeIds(const task_id remoteTaskId)
{
121
  std::map<task_id, node_id_map>::const_iterator iter =
122
    mMap.find(remoteTaskId);
123 124 125 126
  if(iter != mMap.end()) {
    return iter->second;
  }
  // No entry, return empty map.
127
  return node_id_map();
128 129
}

130
void
131 132 133
XdmfMap::insert(const task_id remoteTaskId,
                const node_id localNodeId,
                const node_id remoteLocalNodeId)
134
{
135
  mMap[remoteTaskId][localNodeId].insert(remoteLocalNodeId);
136 137
}

138 139
bool XdmfMap::isInitialized() const
{
140
  return mMap.size() > 0;
141 142
}

143 144
void
XdmfMap::populateItem(const std::map<std::string, std::string> & itemProperties,
145
                      std::vector<shared_ptr<XdmfItem> > & childItems,
146
                      const XdmfCoreReader * const reader)
147
{
148
  XdmfItem::populateItem(itemProperties, childItems, reader);
149 150 151 152 153 154 155 156
  std::map<std::string, std::string>::const_iterator name =
    itemProperties.find("Name");
  if(name != itemProperties.end()) {
    mName = name->second;
  }
  else {
    mName = "";
  }
157
  std::vector<shared_ptr<XdmfArray> > arrayVector;
158
  arrayVector.reserve(3);
159
  for(std::vector<shared_ptr<XdmfItem> >::const_iterator iter =
160 161 162
        childItems.begin();
      iter != childItems.end();
      ++iter) {
163 164 165
    if(shared_ptr<XdmfArray> array = shared_dynamic_cast<XdmfArray>(*iter)) {
      arrayVector.push_back(array);
    }
166
  }
167

168 169 170 171 172 173 174 175 176 177 178 179
  if(arrayVector.size() != 0) {
    if(arrayVector.size() != 3) {
      XdmfError::message(XdmfError::FATAL,
                         "Expected 3 arrays attached to "
                         "XdmfMap::populateItem");
    }
    if(!(arrayVector[0]->getSize() == arrayVector[1]->getSize() &&
         arrayVector[0]->getSize() == arrayVector[2]->getSize())) {
      XdmfError::message(XdmfError::FATAL,
                         "Arrays must be of equal size in "
                         "XdmfMap:: populateItem");
    }
180

181 182 183
    // check if any arrays have values in memory - if so, they need to be
    // read into map
    bool needToRead = false;
184
    for(std::vector<shared_ptr<XdmfArray> >::const_iterator iter =
185 186 187
          arrayVector.begin();
        iter != arrayVector.end();
        ++iter) {
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206
      if((*iter)->isInitialized()) {
        needToRead = true;
        break;
      }
    }

    if(needToRead) {
      for(std::vector<shared_ptr<XdmfArray> >::const_iterator iter =
            arrayVector.begin();
          iter != arrayVector.end();
          ++iter) {
        if(!(*iter)->isInitialized()) {
          (*iter)->read();
        }
      }
      for(unsigned int i=0; i<arrayVector[0]->getSize(); ++i) {
        this->insert(arrayVector[0]->getValue<task_id>(i),
                     arrayVector[1]->getValue<node_id>(i),
                     arrayVector[2]->getValue<node_id>(i));
207
      }
208
    }
209 210 211 212
    else {
      mRemoteTaskIdsController = arrayVector[0]->getHeavyDataController();
      mLocalNodeIdsController = arrayVector[1]->getHeavyDataController();
      mRemoteLocalNodeIdsController = arrayVector[2]->getHeavyDataController();
213 214
    }
  }
215 216
}

217 218
void
XdmfMap::read()
219
{
220 221 222
  if(mLocalNodeIdsController &&
     mRemoteTaskIdsController &&
     mRemoteLocalNodeIdsController) {
223 224

    if(!(mLocalNodeIdsController->getSize() ==
225 226 227
         mRemoteTaskIdsController->getSize() &&
         mLocalNodeIdsController->getSize() ==
         mRemoteLocalNodeIdsController->getSize())) {
228
      XdmfError::message(XdmfError::FATAL,
229 230 231
                         "Arrays must be of equal size in XdmfMap::read");
    }

232 233 234
    shared_ptr<XdmfArray> remoteTaskIds = XdmfArray::New();
    shared_ptr<XdmfArray> localNodeIds = XdmfArray::New();
    shared_ptr<XdmfArray> remoteLocalNodeIds = XdmfArray::New();
235

236 237 238 239 240 241 242
    mRemoteTaskIdsController->read(remoteTaskIds.get());
    mLocalNodeIdsController->read(localNodeIds.get());
    mRemoteLocalNodeIdsController->read(remoteLocalNodeIds.get());

    for(unsigned int i=0; i<remoteTaskIds->getSize(); ++i) {
      const unsigned int remoteTaskId = remoteTaskIds->getValue<task_id>(i);
      const unsigned int localNodeId = localNodeIds->getValue<node_id>(i);
243
      const unsigned int remoteLocalNodeId =
244 245
        remoteLocalNodeIds->getValue<node_id>(i);
      mMap[remoteTaskId][localNodeId].insert(remoteLocalNodeId);
246 247
    }
  }
248 249
}

250 251
void
XdmfMap::release()
252
{
253
  mMap.clear();
254 255
}

256
void
257 258 259
XdmfMap::setHeavyDataControllers(shared_ptr<XdmfHeavyDataController> remoteTaskIdsController,
                                 shared_ptr<XdmfHeavyDataController> localNodeIdsController,
                                 shared_ptr<XdmfHeavyDataController> remoteLocalNodeIdsController)
260
{
261
  if(!(localNodeIdsController->getSize() ==
262 263 264
       remoteTaskIdsController->getSize() &&
       localNodeIdsController->getSize() ==
       remoteLocalNodeIdsController->getSize()))
265
    XdmfError::message(XdmfError::FATAL,
266 267
                       "Arrays must be of equal size in "
                       "XdmfMap::setHeavyDataControllers");
268
  mRemoteTaskIdsController = remoteTaskIdsController;
269
  mLocalNodeIdsController = localNodeIdsController;
270
  mRemoteLocalNodeIdsController = remoteLocalNodeIdsController;
271 272
}

273 274 275 276 277
void 
XdmfMap::setMap(std::map<task_id, node_id_map> map)
{
  mMap = map;
}
278

279 280 281 282 283 284
void
XdmfMap::setName(const std::string & name)
{
  mName = name;
}

285
void
286
XdmfMap::traverse(const shared_ptr<XdmfBaseVisitor> visitor)
287
{
288
  XdmfItem::traverse(visitor);
289

290 291 292
  shared_ptr<XdmfArray> remoteTaskIds = XdmfArray::New();
  shared_ptr<XdmfArray> localNodeIds = XdmfArray::New();
  shared_ptr<XdmfArray> remoteLocalNodeIds = XdmfArray::New();
293 294

  for(std::map<task_id, node_id_map>::const_iterator
295 296 297
        iter = mMap.begin();
      iter != mMap.end();
      ++iter) {
298
    for(node_id_map::const_iterator
299
          iter2 = iter->second.begin();
300 301
        iter2 != iter->second.end();
        ++iter2) {
302
      for(node_id_map::mapped_type::const_iterator iter3 =
303 304 305 306 307 308 309
            iter2->second.begin();
          iter3 != iter2->second.end();
          ++iter3) {
        remoteTaskIds->pushBack(iter->first);
        localNodeIds->pushBack(iter2->first);
        remoteLocalNodeIds->pushBack(*iter3);
      }
310 311
    }
  }
312

313
  remoteTaskIds->setHeavyDataController(mRemoteTaskIdsController);
314
  localNodeIds->setHeavyDataController(mLocalNodeIdsController);
315
  remoteLocalNodeIds->setHeavyDataController(mRemoteLocalNodeIdsController);
316

317
  remoteTaskIds->accept(visitor);
318 319
  localNodeIds->accept(visitor);
  remoteLocalNodeIds->accept(visitor);
320

321 322 323
  mLocalNodeIdsController = localNodeIds->getHeavyDataController();
  mRemoteTaskIdsController = remoteTaskIds->getHeavyDataController();
  mRemoteLocalNodeIdsController = remoteLocalNodeIds->getHeavyDataController();
324
}