source: XIOS/trunk/src/transformation/domain_algorithm_generate_rectilinear.cpp @ 827

Last change on this file since 827 was 827, checked in by mhnguyen, 5 years ago

Implementing dynamic interpolation on axis

+) Change grid transformation to make it more flexible
+) Make some small improvements

Test
+) On Curie
+) All test pass

File size: 4.6 KB
Line 
1/*!
2   \file domain_algorithm_generate_rectilinear.cpp
3   \author Ha NGUYEN
4   \since 31 Aug 2015
5   \date 31 Aug 2015
6
7   \brief Algorithm for automatic generation of rectilinear domain.
8 */
9#include "domain_algorithm_generate_rectilinear.hpp"
10#include "grid.hpp"
11#include "domain.hpp"
12#include "context.hpp"
13#include "context_client.hpp"
14#include "generate_rectilinear_domain.hpp"
15
16namespace xios {
17
18CDomainAlgorithmGenerateRectilinear::CDomainAlgorithmGenerateRectilinear(CDomain* domainDestination, CDomain* domainSource,
19                                                                         CGrid* gridDest, CGrid* gridSource,
20                                                                         CGenerateRectilinearDomain* genRectDomain)
21: CDomainAlgorithmTransformation(domainDestination, domainSource), nbDomainDistributedPart_(0)
22{
23  genRectDomain->checkValid(domainDestination);
24  if (0 != gridSource) computeDistributionGridSource(gridSource);
25  else
26  {
27    computeDistributionGridDestination(gridDest);
28  }
29  fillInAttributesDomainDestination();
30}
31
32/*!
33  Compute the index mapping between domain on grid source and one on grid destination
34*/
35void CDomainAlgorithmGenerateRectilinear::computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs)
36{
37 /* Nothing to do */
38}
39
40/*!
41  Calculate the number of distributed parts on domain source
42*/
43void CDomainAlgorithmGenerateRectilinear::computeDistributionGridSource(CGrid* gridSrc)
44{
45  CContext* context = CContext::getCurrent();
46  CContextClient* client = context->client;
47
48  std::vector<CDomain*> domListSrcP = gridSrc->getDomains();
49  std::vector<CAxis*> axisListSrcP = gridSrc->getAxis();
50
51  for (int i = 0; i < domListSrcP.size(); ++i) // support we have only domain, more than one, for now, dont know how to process
52  {
53    // First, find (roundly) distribution of associated axis (if any)
54    if (axisListSrcP.empty()) nbDomainDistributedPart_ = client->clientSize;
55    else
56    {
57      gridSrc->solveAxisRef(false);
58      int nbAxis = axisListSrcP.size();
59      std::vector<int> nbLocalAxis(nbAxis, 0);
60      for (int j = 0; j < nbAxis; ++j)
61      {
62        std::vector<int> globalAxisIndex(axisListSrcP[j]->n);
63        for (int idx = 0; idx < axisListSrcP[j]->n; ++idx)
64          globalAxisIndex[idx] = axisListSrcP[j]->begin + idx;
65        HashXIOS<int> hashFunc;
66        StdSize hashValue = hashFunc.hashVec(globalAxisIndex);
67        std::vector<StdSize> recvBuff(client->clientSize);
68        MPI_Gather(&hashValue, 1, MPI_UNSIGNED_LONG,
69                   &recvBuff[0], 1, MPI_UNSIGNED_LONG,
70                   0,
71                   client->intraComm);
72        if (0 == client->clientRank)
73        {
74          std::set<StdSize> setTmp;
75          for (int k = 0; k < recvBuff.size(); ++k)
76          {
77            if (setTmp.end() == setTmp.find(recvBuff[k]))
78            {
79              ++nbLocalAxis[j];
80              setTmp.insert(recvBuff[k]);
81            }
82          }
83        }
84
85        MPI_Bcast(&nbLocalAxis[0], nbAxis, MPI_INT,
86                  0, client->intraComm);
87      }
88
89      int nbAxisDistributedPart = 1;
90      for (int j = 0; j < nbAxis; ++j) nbAxisDistributedPart *= nbLocalAxis[j];
91      nbDomainDistributedPart_ = client->clientSize/nbAxisDistributedPart;
92    }
93  }
94}
95
96/*!
97  Compute the distribution of the domain destination by using available information provided by user such as n_distributed_partition of axis
98*/
99void CDomainAlgorithmGenerateRectilinear::computeDistributionGridDestination(CGrid* gridDest)
100{
101  // For now, just suppose that the grid contains only one domain
102  std::vector<CAxis*> axisListDestP = gridDest->getAxis();
103  int nbPartition = 1, idx = 0;
104  for (int i = 0; i < gridDest->axis_domain_order.numElements(); ++i)
105  {
106    if (false == (gridDest->axis_domain_order)(i))
107    {
108      nbPartition *= (axisListDestP[idx]->n_distributed_partition.isEmpty()) ? 1: (axisListDestP[idx]->n_distributed_partition.getValue());
109      ++idx;
110    }
111  }
112
113  CContext* context = CContext::getCurrent();
114  CContextClient* client = context->client;
115  int modPart = (client->clientSize) % nbPartition;
116  if (0 != modPart)
117    ERROR("CDomainAlgorithmGenerateRectilinear::computeDistributionGridDestination(CGrid* gridDest)",
118       << "The grid " <<gridDest->getId() << " is not well-distributed. There is an incompatibility between distribution of axis and domain.");
119  nbDomainDistributedPart_ = client->clientSize/nbPartition;
120
121}
122
123/*!
124  Fill in all necessary attributes of domain destination and their values
125*/
126void CDomainAlgorithmGenerateRectilinear::fillInAttributesDomainDestination()
127{
128  domainDest_->redistribute(nbDomainDistributedPart_);
129}
130
131}
Note: See TracBrowser for help on using the repository browser.