/*! \file scalar_algorithm_redistribute.cpp \brief Algorithm for redistribute a scalar. */ #include "scalar_algorithm_redistribute.hpp" #include "redistribute_scalar.hpp" #include "scalar.hpp" #include "grid.hpp" #include "grid_transformation_factory_impl.hpp" #include "context.hpp" namespace xios { shared_ptr CScalarAlgorithmRedistribute::create(bool isSource, CGrid* gridDst, CGrid* gridSrc, CTransformation* transformation, int elementPositionInGrid, std::map& elementPositionInGridSrc2ScalarPosition, std::map& elementPositionInGridSrc2AxisPosition, std::map& elementPositionInGridSrc2DomainPosition, std::map& elementPositionInGridDst2ScalarPosition, std::map& elementPositionInGridDst2AxisPosition, std::map& elementPositionInGridDst2DomainPosition) TRY { std::vector scalarListDestP = gridDst->getScalars(); std::vector scalarListSrcP = gridSrc->getScalars(); CRedistributeScalar* redistributeScalar = dynamic_cast (transformation); int scalarDstIndex = elementPositionInGridDst2ScalarPosition[elementPositionInGrid]; int scalarSrcIndex = elementPositionInGridSrc2ScalarPosition[elementPositionInGrid]; return make_shared(isSource, scalarListDestP[scalarDstIndex], scalarListSrcP[scalarSrcIndex], redistributeScalar); } CATCH bool CScalarAlgorithmRedistribute::dummyRegistered_ = CScalarAlgorithmRedistribute::registerTrans(); bool CScalarAlgorithmRedistribute::registerTrans() TRY { return CGridTransformationFactory::registerTransformation(TRANS_REDISTRIBUTE_SCALAR, create); } CATCH CScalarAlgorithmRedistribute::CScalarAlgorithmRedistribute(bool isSource, CScalar* scalarDestination, CScalar* scalarSource, CRedistributeScalar* redistributeScalar) : CAlgorithmTransformationTransfer(isSource) TRY { CContext* context = CContext::getCurrent(); scalarDestination->n.reset(); scalarDestination->mask.reset(); scalarDestination->value.reset(); scalarDestination->bounds.reset(); redistributeScalar->checkValid(scalarSource); // define the global index of the new domain CArray globalIndex ; if ( redistributeScalar->type == CRedistributeScalar::type_attr::bands || redistributeScalar->type == CRedistributeScalar::type_attr::column || redistributeScalar->type == CRedistributeScalar::type_attr::root ) { if (context->getIntraCommRank()==0) { scalarDestination->n = 1; globalIndex.resize(1) ; globalIndex(0)=0 ; } else { scalarDestination->n = 0; globalIndex.resize(0) ; } } else if (redistributeScalar->type == CRedistributeScalar::type_attr::full) { scalarDestination->n = 1; globalIndex.resize(1) ; globalIndex(0)=0 ; } auto& transMap = this->transformationMapping_; for(int i=0; i(new CLocalElement(context->getIntraCommRank(), 1, globalIndex)) ; elementDst->addFullView() ; auto transformConnector = make_shared(scalarSource->getLocalView(CElementView::FULL), elementDst->getView(CElementView::FULL),context->getIntraComm()) ; transformConnector->computeConnector() ; CArray valSrc, valDst ; valSrc.resize(scalarSource->getLocalView(CElementView::FULL)->getSize()) ; valDst.resize(scalarDestination->getLocalView(CElementView::FULL)->getSize()) ; if (scalarSource->hasValue()) { if (valSrc.numElements()>0) valSrc(0)=scalarSource->value ; transformConnector->transfer(valSrc, valDst) ; if (valDst.numElements()>0) scalarDestination->value = valDst(0) ; } if (scalarSource->hasBounds()) { transformConnector->transfer(2, scalarSource->bounds, scalarDestination->bounds) ; } if (scalarSource->hasLabel()) { //ym transferTransformConnector.transfer(axisSrc->label, axisDestination->label) ; -> probably not supported now, see later } // transfer the mask auto transformMask = make_shared(scalarSource->getLocalView(CElementView::WORKFLOW), elementDst->getView(CElementView::FULL),context->getIntraComm()) ; transformMask->computeConnector() ; CArray workflow(scalarSource->getLocalView(CElementView::WORKFLOW)->getSize()) ; CArray mask ; mask.resize(scalarSource->getLocalView(CElementView::FULL)->getSize()) ; workflow=true ; transformMask->transfer(workflow, mask, false) ; scalarDestination->mask = mask(0) ; scalarDestination->checkAttributes() ; } CATCH }