source: XIOS/dev/dev_ym/XIOS_COUPLING/src/transformation/axis_algorithm/axis_algorithm_interpolate_coordinate.cpp @ 2011

Last change on this file since 2011 was 2011, checked in by ymipsl, 3 years ago
  • bug fix when createing mask on server side when overlapping grid
  • implement axis interpolation on pressure coordinate
  • big cleaning in transformation

YM

  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 9.0 KB
Line 
1/*!
2   \file axis_algorithm_interpolate.cpp
3   \author Ha NGUYEN
4   \since 23 June 2015
5   \date 02 Jul 2015
6
7   \brief Algorithm for interpolation on an axis.
8 */
9#include "axis_algorithm_interpolate_coordinate.hpp"
10#include "axis.hpp"
11#include "interpolate_axis.hpp"
12#include <algorithm>
13#include <numeric>
14#include "context.hpp"
15#include "context_client.hpp"
16#include "utils.hpp"
17#include "grid.hpp"
18#include "grid_transformation_factory_impl.hpp"
19#include "distribution_client.hpp"
20#include "transform_filter.hpp"
21#include "timer.hpp"
22
23namespace xios
24{
25  CGenericAlgorithmTransformation* CAxisAlgorithmInterpolateCoordinate::create(bool isSource, CGrid* gridDst, CGrid* gridSrc,
26                                                                     CTransformation<CAxis>* transformation,
27                                                                     int elementPositionInGrid,
28                                                                     std::map<int, int>& elementPositionInGridSrc2ScalarPosition,
29                                                                     std::map<int, int>& elementPositionInGridSrc2AxisPosition,
30                                                                     std::map<int, int>& elementPositionInGridSrc2DomainPosition,
31                                                                     std::map<int, int>& elementPositionInGridDst2ScalarPosition,
32                                                                     std::map<int, int>& elementPositionInGridDst2AxisPosition,
33                                                                     std::map<int, int>& elementPositionInGridDst2DomainPosition)
34  TRY
35  {
36    std::vector<CAxis*> axisListDestP = gridDst->getAxis();
37    std::vector<CAxis*> axisListSrcP  = gridSrc->getAxis();
38
39    CInterpolateAxis* interpolateAxis = dynamic_cast<CInterpolateAxis*> (transformation);
40    int axisDstIndex = elementPositionInGridDst2AxisPosition[elementPositionInGrid];
41    int axisSrcIndex = elementPositionInGridSrc2AxisPosition[elementPositionInGrid];
42
43    return (new CAxisAlgorithmInterpolateCoordinate(isSource, axisListDestP[axisDstIndex], axisListSrcP[axisSrcIndex], interpolateAxis));
44  }
45  CATCH
46
47  bool CAxisAlgorithmInterpolateCoordinate::dummyRegistered_ = CAxisAlgorithmInterpolateCoordinate::registerTrans();
48  bool CAxisAlgorithmInterpolateCoordinate::registerTrans()
49  TRY
50  {
51    return CGridTransformationFactory<CAxis>::registerTransformation(TRANS_INTERPOLATE_AXIS, create);
52  }
53  CATCH
54
55  vector<string> CAxisAlgorithmInterpolateCoordinate::getAuxFieldId(void)
56  {
57    if (hasCoordinate_) return vector<string>(1,coordinate_) ;
58    else return vector<string>() ;
59  }
60
61  CAxisAlgorithmInterpolateCoordinate::CAxisAlgorithmInterpolateCoordinate(bool isSource, CAxis* axisDestination, CAxis* axisSource, CInterpolateAxis* interpAxis)
62  : CAlgorithmTransformationTransfer(isSource), axisSrc_(axisSource), axisDest_(axisDestination)
63  TRY
64  {
65    interpAxis->checkValid(axisSource);
66    axisDestination->checkAttributes() ;
67
68    order_ = interpAxis->order.getValue();
69    if (!interpAxis->coordinate.isEmpty())
70    {
71      coordinate_ = interpAxis->coordinate.getValue();
72      hasCoordinate_=true ;
73    }
74 
75    ngloSrc_=axisSource->n_glo ;
76    nDest_ =  axisDest_-> getLocalView(CElementView::WORKFLOW)->getSize() ;
77    CArray<double,1> coord ;
78    CLocalConnector destConnector(axisDest_->getLocalView(CElementView::FULL), axisDest_->getLocalView(CElementView::WORKFLOW)) ;
79    destConnector.computeConnector() ;
80    destConnector.transfer(axisDest_->value, coord) ;
81    destCoordinate_ = vector<double>(coord.dataFirst(), coord.dataFirst()+nDest_) ;
82   
83    CArray<size_t,1> globalIndex(ngloSrc_) ;
84    for(int i=0;i<ngloSrc_;i++) 
85    {
86      transformationMapping_[i] = i ;
87      globalIndex(i) = i ;
88    }
89   
90
91    CLocalElement axisSourceGlo(CContext::getCurrent()->getIntraCommRank(), ngloSrc_, globalIndex) ;
92    axisSourceGlo.addFullView() ; 
93
94    this->computeAlgorithm(axisSource->getLocalView(CElementView::WORKFLOW), axisSourceGlo.getView(CElementView::FULL)) ;
95  }
96  CATCH
97
98  CTransformFilter* CAxisAlgorithmInterpolateCoordinate::createTransformFilter(CGarbageCollector& gc, CGridAlgorithm* algo, bool detectMissingValues, double defaultValue)
99  {
100    return new CTransformFilter(gc, 2, algo, detectMissingValues, defaultValue) ; 
101  }
102
103  void CAxisAlgorithmInterpolateCoordinate::apply(int dimBefore, int dimAfter, const CArray<double,1>& dataIn, 
104                                                   const vector<CArray<double,1>>& auxDataIn, CArray<double,1>& dataOut)
105  {
106    CArray<double,1> dataInTmp;
107    CArray<double,1> auxDataInTmp ;
108    transferTransformConnector_ -> transfer(dimBefore, dimAfter, dataIn, dataInTmp) ;
109    transferTransformConnector_ -> transfer(dimBefore, dimAfter, auxDataIn[0], auxDataInTmp) ;
110 
111    dataOut.resize(dimBefore*dimAfter*nDest_) ;
112    const double* pressure = auxDataInTmp.dataFirst() ;
113    const double* in = dataInTmp.dataFirst() ;
114    double* out = dataOut.dataFirst() ;
115
116    size_t sliceSrc = dimAfter*ngloSrc_ ;
117    size_t sliceDest = dimAfter*nDest_ ;
118    vector<double> srcCoordinate(ngloSrc_) ;
119    vector<double> destCoordinate(nDest_) ;
120    std::vector<int> srcIndex(ngloSrc_);
121    vector<double> srcValue(ngloSrc_) ;
122    vector<double> destValue(nDest_) ;
123    std::vector<int> destIndex(nDest_);
124
125    size_t nsrc ;
126    for(size_t j=0, posJsrc=0, posJdest=0 ;  j<dimBefore ; j++, posJsrc+=sliceSrc, posJdest+=sliceDest )
127      for(size_t k=0, posKsrc=posJsrc, posKdest=posJdest ; k<dimAfter ; k++, posKsrc++,posKdest++)
128      {
129        nsrc=0 ;
130        for(size_t i=0, posIsrc=posKsrc, posIdest=posKdest ; i<ngloSrc_ ; i++, posIsrc+=dimAfter, posIdest+=dimAfter)
131        {
132          if ( !( std::isnan(pressure[posIsrc]) || std::isnan(in[posIsrc]) ) )
133          {
134            srcCoordinate[nsrc]=pressure[posIsrc] ;
135            srcValue[nsrc] = in[posIsrc] ;
136            nsrc++ ;
137          }
138        }
139        destCoordinate = destCoordinate_ ;   
140        computeInterp(nsrc, srcCoordinate, srcValue, srcIndex, nDest_, destCoordinate, destValue, destIndex) ;
141
142        for(size_t i=0, posIdest=posKdest ; i<nDest_ ; i++, posIdest+=dimAfter)  out[posIdest] = destValue[i] ;
143      }
144
145  }
146
147  void CAxisAlgorithmInterpolateCoordinate::computeInterp(int nsrc, vector<double>& srcCoordinate, vector<double>& srcValue, vector<int>& srcIndex,
148                                                          int ndst, vector<double>& dstCoordinate, vector<double>& dstValue, vector<int>& dstIndex)
149  {
150    double x,y ;
151    double d ;
152 
153    iota(srcIndex.data(), srcIndex.data()+nsrc, 0); // sort array and retrive sorted index
154    stable_sort(srcIndex.data(), srcIndex.data()+nsrc, [&srcCoordinate](size_t i1, size_t i2) {return srcCoordinate[i1] < srcCoordinate[i2];});
155
156    iota(dstIndex.data(), dstIndex.data()+ndst, 0);
157    stable_sort(dstIndex.data(), dstIndex.data()+ndst, [&dstCoordinate](size_t i1, size_t i2) {return dstCoordinate[i1] < dstCoordinate[i2];});
158
159    if (order_==1 || nsrc<=2)
160    {
161      if (nsrc<=1) dstValue.assign(ndst,std::numeric_limits<double>::quiet_NaN());
162      else
163      {
164
165        double x0,x1 ;
166        double y0,y1 ;
167        int lastj=0;
168     
169        for(int i=0; i < ndst;i++)
170        {
171          x=dstCoordinate[dstIndex[i]] ;
172          if ( x<=srcCoordinate[srcIndex[0]]) lastj=0 ;
173          else if (x>=srcCoordinate[srcIndex[nsrc-1]]) lastj=nsrc-2 ;
174          else
175          {
176            for(int j=lastj; j<nsrc; j++)
177            { 
178              if (x >= srcCoordinate[srcIndex[j]] && x<srcCoordinate[srcIndex[j+1]]) ;
179              lastj=j ;
180              break ;
181            } 
182          }
183          x0=srcCoordinate[srcIndex[lastj]] ;
184          x1=srcCoordinate[srcIndex[lastj+1]] ;
185          y0=srcValue[srcIndex[lastj]] ;
186          y1=srcValue[srcIndex[lastj+1]] ;
187          y=((x-x1)*y0-(x-x0)*y1)/(x0-x1) ;
188          dstValue[dstIndex[i]]=y ;
189        }
190      }
191    }
192    else if (order_==2)
193    {
194      double x0,x1,x2 ;
195      double y0,y1,y2 ;
196      int lastj=0, cj ;
197     
198      for(int i=0; i < ndst;i++)
199      {
200        x=dstCoordinate[dstIndex[i]] ;
201        if ( x<=srcCoordinate[srcIndex[0]]) lastj=0 ;
202        else if (x>=srcCoordinate[srcIndex[nsrc-1]]) lastj=nsrc-2 ;
203        else
204        {
205          for(int j=lastj; j<nsrc; j++)
206          { 
207            if (x >= srcCoordinate[srcIndex[j]] && x<srcCoordinate[srcIndex[j+1]]) ;
208           
209            lastj=j ;
210            break ;
211          } 
212        }
213       
214        if (lastj==0) cj=1 ;
215        else if (lastj>=nsrc-2) cj=nsrc-2 ;
216        else
217        {
218          if ( (x-srcCoordinate[srcIndex[lastj-1]]) > (srcCoordinate[srcIndex[lastj+2]]-x) ) cj=lastj ;
219          else cj=lastj+1 ;
220        } 
221        x0=srcCoordinate[srcIndex[cj-1]] ;
222        x1=srcCoordinate[srcIndex[cj]] ;
223        x2=srcCoordinate[srcIndex[cj+1]] ;
224        y0=srcValue[srcIndex[cj-1]] ;
225        y1=srcValue[srcIndex[cj]] ;
226        y2=srcValue[srcIndex[cj+1]] ;
227           
228        y=y0*(x-x1)*(x-x2)/((x0-x1)*(x0-x2)) + y1*(x-x0)*(x-x2)/((x1-x0)*(x1-x2)) + y2*(x-x0)*(x-x1)/((x2-x0)*(x2-x1))  ;
229        dstValue[dstIndex[i]]=y ;
230      }
231    }
232  } 
233
234}
Note: See TracBrowser for help on using the repository browser.