Ignore:
Timestamp:
11/26/18 10:35:26 (5 years ago)
Author:
ymipsl
Message:

Interpolation enhancement :
Domain area can be used to improved global conservation when there is a discrepency between model area and xios computed area.

New domain attribute :

radius : radius af the spherical domain, used to compute area ond the sphere with a normalized radius of 1 (for remapper).

New domain_interpolate attribute :
use_area : remapper will take model computed area in order to perform a global conservation for flux integrated over the cell (mass for example).
In this case the domain attributes "area" and "radius" must be defined on the source or target domain to be taking into account.

YM

File:
1 edited

Legend:

Unmodified
Added
Removed
  • XIOS/trunk/src/transformation/domain_algorithm_interpolate.cpp

    r1542 r1615  
    304304  CArray<double,2> boundsLonSrcUnmasked(nVertexSrc,nSrcLocalUnmasked); 
    305305  CArray<double,2> boundsLatSrcUnmasked(nVertexSrc,nSrcLocalUnmasked); 
     306  CArray<double,1> areaSrcUnmasked(nSrcLocalUnmasked); 
     307   
    306308  long int * globalSrcUnmasked = new long int [nSrcLocalUnmasked]; 
    307309 
    308310  nSrcLocalUnmasked=0 ; 
     311  bool hasSrcArea=!domainSrc_->area.isEmpty() && !domainSrc_->radius.isEmpty() && !interpDomain_->use_area.isEmpty() && interpDomain_->use_area==true  ; 
     312  double srcAreaFactor ; 
     313  if (hasSrcArea) srcAreaFactor=1./(domainSrc_->radius*domainSrc_->radius) ; 
     314   
    309315  for (int idx=0 ; idx < nSrcLocal; idx++) 
    310316  { 
     
    316322        boundsLatSrcUnmasked(n,nSrcLocalUnmasked) = boundsLatSrc(n,idx) ; 
    317323      } 
     324      if (hasSrcArea) areaSrcUnmasked(nSrcLocalUnmasked) = domainSrc_->area(idx)*srcAreaFactor ; 
    318325      globalSrcUnmasked[nSrcLocalUnmasked]=globalSrc[idx] ; 
    319326      ++nSrcLocalUnmasked ; 
    320327    } 
    321328  } 
    322  
     329  
    323330 
    324331  int nDstLocalUnmasked = 0 ; 
     
    327334  CArray<double,2> boundsLonDestUnmasked(nVertexDest,nDstLocalUnmasked); 
    328335  CArray<double,2> boundsLatDestUnmasked(nVertexDest,nDstLocalUnmasked); 
     336  CArray<double,1>   areaDstUnmasked(nSrcLocalUnmasked); 
     337 
    329338  long int * globalDstUnmasked = new long int [nDstLocalUnmasked]; 
    330339 
    331340  nDstLocalUnmasked=0 ; 
     341  bool hasDstArea=!domainDest_->area.isEmpty() && !domainDest_->radius.isEmpty() && !interpDomain_->use_area.isEmpty() && interpDomain_->use_area==true ; 
     342  double dstAreaFactor ; 
     343  if (hasDstArea) dstAreaFactor=1./(domainDest_->radius*domainDest_->radius) ; 
    332344  for (int idx=0 ; idx < nDstLocal; idx++) 
    333345  { 
     
    339351        boundsLatDestUnmasked(n,nDstLocalUnmasked) = boundsLatDest(n,idx) ; 
    340352      } 
     353      if (hasDstArea) areaDstUnmasked(nDstLocalUnmasked) = domainDest_->area(idx)*dstAreaFactor ; 
    341354      globalDstUnmasked[nDstLocalUnmasked]=globalDst[idx] ; 
    342355      ++nDstLocalUnmasked ; 
     
    344357  } 
    345358 
    346   mapper.setSourceMesh(boundsLonSrcUnmasked.dataFirst(), boundsLatSrcUnmasked.dataFirst(), nVertexSrc, nSrcLocalUnmasked, &srcPole[0], globalSrcUnmasked); 
    347   mapper.setTargetMesh(boundsLonDestUnmasked.dataFirst(), boundsLatDestUnmasked.dataFirst(), nVertexDest, nDstLocalUnmasked, &dstPole[0], globalDstUnmasked); 
     359  double* ptAreaSrcUnmasked = NULL ; 
     360  if (hasSrcArea) ptAreaSrcUnmasked=areaSrcUnmasked.dataFirst() ; 
     361 
     362  double* ptAreaDstUnmasked = NULL ; 
     363  if (hasDstArea) ptAreaDstUnmasked=areaDstUnmasked.dataFirst() ; 
     364 
     365  mapper.setSourceMesh(boundsLonSrcUnmasked.dataFirst(), boundsLatSrcUnmasked.dataFirst(), ptAreaSrcUnmasked, nVertexSrc, nSrcLocalUnmasked, &srcPole[0], globalSrcUnmasked); 
     366  mapper.setTargetMesh(boundsLonDestUnmasked.dataFirst(), boundsLatDestUnmasked.dataFirst(), ptAreaDstUnmasked, nVertexDest, nDstLocalUnmasked, &dstPole[0], globalDstUnmasked); 
    348367 
    349368  std::vector<double> timings = mapper.computeWeights(orderInterp,renormalize,quantity); 
     
    949968    size_t nbIndex=dataOut.numElements() ;  
    950969 
    951     for (int idx = 0; idx < nbIndex; ++idx) 
    952     { 
    953       if (allMissing(idx)) dataOut(idx) = defaultValue; // If all data source are nan then data destination must be nan 
     970    if (allMissing.numElements()>0) 
     971    { 
     972      for (int idx = 0; idx < nbIndex; ++idx) 
     973      { 
     974        if (allMissing(idx)) dataOut(idx) = defaultValue; // If all data source are nan then data destination must be nan 
     975      } 
    954976    } 
    955977     
Note: See TracChangeset for help on using the changeset viewer.