source: XIOS/dev/dev_ym/XIOS_COUPLING/src/distribution/weight_transform_connector.hpp @ 2338

Last change on this file since 2338 was 2313, checked in by ymipsl, 2 years ago

Take into account detect_missing_value and renormalize attribute for interpolate class transformation.

YM

  • Property svn:executable set to *
File size: 4.3 KB
Line 
1#ifndef __WEIGHT_TRANSFORM_CONNECTOR_HPP__
2#define __WEIGHT_TRANSFORM_CONNECTOR_HPP__
3
4#include "xios_spl.hpp"
5#include "array_new.hpp"
6#include "local_view.hpp"
7
8
9
10namespace xios
11{
12 
13  class CWeightTransformConnector
14  {
15   
16    private:
17      shared_ptr<CLocalView> srcView_;
18      shared_ptr<CLocalView> dstView_;
19
20      vector<double> weights_; //  sizeof sum(nWeights_) 
21      vector<int> connector_;  //  sizeof sum(nWeights_) 
22      vector<int> nWeights_ ;  //  sizeof dstSize_
23      int srcSize_ ;
24      int dstSize_ ;
25      bool detectMissingValue_ ;
26      bool renormalize_ ;
27
28     void computeConnector(unordered_map<int, std::vector<int>>& indexMap, unordered_map<int, std::vector<double>>& weightMap) ;
29     
30    public:
31
32    CWeightTransformConnector(shared_ptr<CLocalView> srcView, shared_ptr<CLocalView> dstView, unordered_map<int, std::vector<int>>& indexMap, 
33                              unordered_map<int, std::vector<double>>& weightMap, bool detectMissingValue, bool renormalize) ;
34 
35    void transfer(int repeat, int sizeT, const CArray<double,1>& dataIn, CArray<double,1>& dataOut)
36    {
37      int dstSlice = dstSize_*sizeT ;
38      int srcSlice = srcSize_*sizeT ;
39      dataOut.resize(repeat* dstSlice) ;
40      double defaultValue = std::numeric_limits<double>::quiet_NaN();
41      dataOut = defaultValue ; // what to do about missing value => next step ?
42      const double* input = dataIn.dataFirst()  ;
43      double* output = dataOut.dataFirst()  ;
44      vector<bool> isFirst(dstSlice) ;
45      size_t pos ;
46     
47      if (renormalize_)
48      {
49        double inVal ;
50        vector<double> renormalizeFactor(repeat*dstSlice,1) ;
51        double* renorm = renormalizeFactor.data() ;
52        for(int r=0;r<repeat;r++, input+=srcSlice, output+=dstSlice, renorm+=dstSlice)
53        {
54          const double* in = input;
55          double* out = output ;
56          double* ren = renorm ;
57          isFirst.assign(dstSlice,true) ;
58          pos=0 ;
59          int k=0 ;
60          for(int i=0; i<dstSize_; i++, out+=sizeT, pos+=sizeT, ren+=sizeT)
61            for(int j=0 ; j<nWeights_[i] ; j++,k++)
62              for(int l=0; l<sizeT; l++)
63              {
64                inVal=in[connector_[k]*sizeT+l] ;
65                if (!std::isnan(inVal))
66                {
67                  if (isFirst[pos+l])  { out[l] = inVal*weights_[k] ; isFirst[pos+l]=false ;}
68                  else out[l] += inVal*weights_[k] ;
69                }
70                else  ren[l] -= weights_[k] ;
71              }
72          for(int i=0; i<dstSlice; i++) output[i] /= renorm[i] ; 
73        }
74      }
75      else if (detectMissingValue_)
76      {
77        double inVal ;
78        for(int r=0;r<repeat;r++, input+=srcSlice, output+=dstSlice)
79        {
80          const double* in = input;
81          double* out = output ;
82          isFirst.assign(dstSlice,true) ;
83          pos=0 ;
84          int k=0 ;
85          for(int i=0; i<dstSize_; i++, out+=sizeT, pos+=sizeT)
86            for(int j=0 ; j<nWeights_[i] ; j++,k++)
87              for(int l=0; l<sizeT; l++)
88              {
89                inVal=in[connector_[k]*sizeT+l] ;
90                if (!std::isnan(inVal))
91                {
92                  if (isFirst[pos+l])  { out[l] = inVal*weights_[k] ; isFirst[pos+l]=false ;}
93                  else out[l] += inVal*weights_[k] ;
94                }
95              }
96        }
97
98      }
99      else
100      {
101        for(int r=0;r<repeat;r++, input+=srcSlice, output+=dstSlice)
102        {
103          const double* in = input;
104          double* out = output ;
105          isFirst.assign(dstSlice,true) ;
106          pos=0 ;
107          int k=0 ;
108          for(int i=0; i<dstSize_; i++, out+=sizeT, pos+=sizeT)
109            for(int j=0 ; j<nWeights_[i] ; j++,k++)
110              for(int l=0; l<sizeT; l++) 
111                if (isFirst[pos+l])  { out[l] = in[connector_[k]*sizeT+l]*weights_[k] ; isFirst[pos+l]=false ;}
112                else out[l] += in[connector_[k]*sizeT+l]*weights_[k] ;
113        }
114      }
115    }
116
117    void transfer(int sizeT, const CArray<double,1>& dataIn, CArray<double,1>& dataOut)
118    { 
119      transfer(1,sizeT, dataIn, dataOut) ;
120    }
121   
122    void transfer(const CArray<double,1>& dataIn, CArray<double,1>& dataOut)
123    {
124      transfer(1,1,dataIn, dataOut) ;
125    }
126
127 
128  };
129
130}
131
132#endif
Note: See TracBrowser for help on using the repository browser.