#include "domain.hpp" #include "attribute_template.hpp" #include "object_template.hpp" #include "group_template.hpp" #include "xios_spl.hpp" #include "event_client.hpp" #include "event_server.hpp" #include "buffer_in.hpp" #include "message.hpp" #include "type.hpp" #include "context.hpp" #include "context_client.hpp" #include "array_new.hpp" #include "server_distribution_description.hpp" #include "client_server_mapping_distributed.hpp" #include "zoom_domain.hpp" #include "interpolate_from_file_domain.hpp" namespace xios { /// ////////////////////// Définitions ////////////////////// /// CDomain::CDomain(void) : CObjectTemplate(), CDomainAttributes() , isChecked(false), relFiles(), isClientChecked(false), nbConnectedClients_(), indSrv_(), connectedServerRank_() , hasBounds(false), hasArea(false), isDistributed_(false), nGlobDomain_(), isUnstructed_(false) , global_zoom_ni(0), global_zoom_ibegin(0), global_zoom_nj(0), global_zoom_jbegin(0) , isClientAfterTransformationChecked(false), hasLonLat(false) , lonvalue_client(), latvalue_client(), bounds_lon_client(), bounds_lat_client() { /* Ne rien faire de plus */ } CDomain::CDomain(const StdString & id) : CObjectTemplate(id), CDomainAttributes() , isChecked(false), relFiles(), isClientChecked(false), nbConnectedClients_(), indSrv_(), connectedServerRank_() , hasBounds(false), hasArea(false), isDistributed_(false), nGlobDomain_(), isUnstructed_(false) , global_zoom_ni(0), global_zoom_ibegin(0), global_zoom_nj(0), global_zoom_jbegin(0) , isClientAfterTransformationChecked(false), hasLonLat(false) , lonvalue_client(), latvalue_client(), bounds_lon_client(), bounds_lat_client() { /* Ne rien faire de plus */ } CDomain::~CDomain(void) { } ///--------------------------------------------------------------- CDomain* CDomain::createDomain() { CDomain* domain = CDomainGroup::get("domain_definition")->createChild(); return domain; } void CDomain::duplicateAttributes(CDomain* domain) { domain->setAttributes(this); } const std::set & CDomain::getRelFiles(void) const { return (this->relFiles); } //---------------------------------------------------------------- bool CDomain::isEmpty(void) const { return ((this->zoom_ni_srv == 0) || (this->zoom_nj_srv == 0)); } //---------------------------------------------------------------- bool CDomain::IsWritten(const StdString & filename) const { return (this->relFiles.find(filename) != this->relFiles.end()); } //---------------------------------------------------------------- bool CDomain::isDistributed(void) const { return isDistributed_; } //---------------------------------------------------------------- void CDomain::addRelFile(const StdString & filename) { this->relFiles.insert(filename); } StdString CDomain::GetName(void) { return (StdString("domain")); } StdString CDomain::GetDefName(void){ return (CDomain::GetName()); } ENodeType CDomain::GetType(void) { return (eDomain); } //---------------------------------------------------------------- void CDomain::checkDomain(void) { if (type.isEmpty()) { ERROR("CDomain::checkDomain(void)", << "[ Id = " << this->getId() << " ] " << "The domain type is not defined," << " check the 'type' value !") } if (type==type_attr::unstructured) { if (ni_glo.isEmpty() || ni_glo <= 0 ) { ERROR("CDomain::checkAttributes(void)", << "[ Id = " << this->getId() << " ] " << "The global domain is badly defined," << " check the \'ni_glo\' value !") } isUnstructed_ = true; nj_glo = 1; nj = 1; jbegin = 0; if (ni.isEmpty()) ni = i_index.numElements(); j_index.resize(ni); for(int i=0;i ni_glo.getValue()) { ERROR("CDomain::checkLocalIDomain(void)", << "[ Id = " << this->getId() << " ] " << "The local domain is wrongly defined," << " check the attributes 'ni_glo', 'ni' and 'ibegin'"); } } //---------------------------------------------------------------- void CDomain::checkLocalJDomain(void) { if (jbegin.isEmpty() && nj.isEmpty()) { jbegin = 0; nj = nj_glo; } else if (!j_index.isEmpty()) { jbegin = j_index(0); } if (nj.getValue() < 0 || jbegin.getValue() < 0 || (jbegin.getValue() + nj.getValue()) > nj_glo.getValue()) { ERROR("CDomain::checkLocalJDomain(void)", << "[ Id = " << this->getId() << " ] " << "The local domain is wrongly defined," << " check the attributes 'nj_glo', 'nj' and 'jbegin'"); } } //---------------------------------------------------------------- void CDomain::checkMask(void) { using namespace std; int ibegin_mask = 0, jbegin_mask = 0, iend_mask = ibegin.getValue() + ni.getValue() - 1, jend_mask = jbegin.getValue() + nj.getValue() - 1; if (!mask_1d.isEmpty() && !mask_2d.isEmpty()) ERROR("CDomain::checkMask(void)", <<"Only one mask is used but both mask_1d and mask_2d are defined! "< lonvalue_temp(ni*nj) ; CArray bounds_lon_temp(nvertex,ni*nj); CArray latvalue_temp(ni*nj) ; CArray bounds_lat_temp(nvertex,ni*nj); if (!lonvalue_2d.isEmpty()) { for (j = 0; j < nj; ++j) for (i = 0; i < ni; ++i) { lonvalue_temp(i+j*ni) = lonvalue_2d(i,j); latvalue_temp(i+j*ni) = latvalue_2d(i,j); if (hasBounds) { k=j*ni+i; for(int n=0;n= global_zoom_ibegin && i_ind <= global_zoom_iend && j_ind >= global_zoom_jbegin && j_ind <= global_zoom_jend) { ++globalIndexCountZoom; } } // Make sure that this attribute is non-empty for every client. if (0 != globalIndexCountZoom) { lonvalue_client.resize(globalIndexCountZoom); latvalue_client.resize(globalIndexCountZoom); if (hasBounds) { bounds_lon_client.resize(nvertex,globalIndexCountZoom); bounds_lat_client.resize(nvertex,globalIndexCountZoom); } } int nCountZoom = 0; for (i = 0; i < nbIndex; ++i) { i_ind=i_index(i); j_ind=j_index(i); if (i_ind >= global_zoom_ibegin && i_ind <= global_zoom_iend && j_ind >= global_zoom_jbegin && j_ind <= global_zoom_jend) { lonvalue_client(nCountZoom) = lonvalue_temp(i); latvalue_client(nCountZoom) = latvalue_temp(i); if (hasBounds) { for (int n = 0; n < nvertex; ++n) { bounds_lon_client(n,nCountZoom) = bounds_lon_temp(n,i); bounds_lat_client(n,nCountZoom) = bounds_lat_temp(n,i); } } ++nCountZoom; } } } void CDomain::checkBounds(void) { if (!nvertex.isEmpty() && (0 != nvertex.getValue())) { if (!bounds_lon_1d.isEmpty() && !bounds_lon_2d.isEmpty()) ERROR("CDomain::checkBounds(void)", <<"Only one longitude boundary value can be used but both bounds_lon_1d and bounds_lon_2d are defined! "<isClientAfterTransformationChecked) return; if (context->hasClient) { this->checkMask(); if (hasLonLat || hasArea) this->computeConnectedServer(); if (hasLonLat) this->completeLonLatClient(); } this->isClientAfterTransformationChecked = true; } //---------------------------------------------------------------- // Divide function checkAttributes into 2 seperate onescheckBounds // This function only checks all attributes of current domain void CDomain::checkAttributesOnClient() { if (this->isClientChecked) return; CContext* context=CContext::getCurrent(); this->checkDomain(); this->checkBounds(); this->checkArea(); this->checkLonLat(); if (context->hasClient) { // Côté client uniquement this->checkMask(); this->checkDomainData(); this->checkCompression(); } else { // Côté serveur uniquement } this->isClientChecked = true; } // Send all checked attributes to server void CDomain::sendCheckedAttributes() { if (!this->isClientChecked) checkAttributesOnClient(); if (!this->isClientAfterTransformationChecked) checkAttributesOnClientAfterTransformation(); CContext* context=CContext::getCurrent() ; if (this->isChecked) return; if (context->hasClient) { sendServerAttribut(); if (hasLonLat || hasArea) sendLonLatArea(); } this->isChecked = true; } void CDomain::checkAttributes(void) { if (this->isChecked) return; CContext* context=CContext::getCurrent() ; this->checkDomain(); this->checkLonLat(); this->checkBounds(); this->checkArea(); if (context->hasClient) { // Côté client uniquement this->checkMask(); this->checkDomainData(); this->checkCompression(); } else { // Côté serveur uniquement } if (context->hasClient) { this->computeConnectedServer(); this->completeLonLatClient(); this->sendServerAttribut(); this->sendLonLatArea(); } this->isChecked = true; } void CDomain::sendServerAttribut(void) { CServerDistributionDescription serverDescription(nGlobDomain_); CContext* context = CContext::getCurrent(); CContextClient* client = context->client; int nbServer = client->serverSize; if (isUnstructed_) serverDescription.computeServerDistribution(nbServer,0); else serverDescription.computeServerDistribution(nbServer,1); std::vector > serverIndexBegin = serverDescription.getServerIndexBegin(); std::vector > serverDimensionSizes = serverDescription.getServerDimensionSizes(); CEventClient event(getType(),EVENT_ID_SERVER_ATTRIBUT); if (client->isServerLeader()) { std::list msgs; const std::list& ranks = client->getRanksServerLeader(); for (std::list::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) { // Use const int to ensure CMessage holds a copy of the value instead of just a reference const int ibegin_srv = serverIndexBegin[*itRank][0]; const int jbegin_srv = serverIndexBegin[*itRank][1]; const int ni_srv = serverDimensionSizes[*itRank][0]; const int nj_srv = serverDimensionSizes[*itRank][1]; const int iend_srv = ibegin_srv + ni_srv - 1; const int jend_srv = jbegin_srv + nj_srv - 1; msgs.push_back(CMessage()); CMessage& msg = msgs.back(); msg << this->getId() ; msg << ni_srv << ibegin_srv << iend_srv << nj_srv << jbegin_srv << jend_srv; msg << global_zoom_ni << global_zoom_ibegin << global_zoom_nj << global_zoom_jbegin; event.push(*itRank,1,msg); } client->sendEvent(event); } else client->sendEvent(event); } void CDomain::computeNGlobDomain() { nGlobDomain_.resize(2); nGlobDomain_[0] = ni_glo.getValue(); nGlobDomain_[1] = nj_glo.getValue(); } void CDomain::computeConnectedServer(void) { CContext* context=CContext::getCurrent() ; CContextClient* client=context->client ; int nbServer=client->serverSize; bool doComputeGlobalIndexServer = true; int i,j,i_ind,j_ind, nbIndex; int global_zoom_iend=global_zoom_ibegin+global_zoom_ni-1 ; int global_zoom_jend=global_zoom_jbegin+global_zoom_nj-1 ; // Precompute number of index int globalIndexCountZoom = 0; nbIndex = i_index.numElements(); for (i = 0; i < nbIndex; ++i) { i_ind=i_index(i); j_ind=j_index(i); if (i_ind >= global_zoom_ibegin && i_ind <= global_zoom_iend && j_ind >= global_zoom_jbegin && j_ind <= global_zoom_jend) { ++globalIndexCountZoom; } } // Fill in index CArray globalIndexDomainZoom(globalIndexCountZoom); CArray localIndexDomainZoom(globalIndexCountZoom); CArray globalIndexDomain(nbIndex); size_t globalIndex; int globalIndexCount = 0; globalIndexCountZoom = 0; for (i = 0; i < nbIndex; ++i) { i_ind=i_index(i); j_ind=j_index(i); globalIndex = i_ind + j_ind * ni_glo; globalIndexDomain(globalIndexCount) = globalIndex; ++globalIndexCount; if (i_ind >= global_zoom_ibegin && i_ind <= global_zoom_iend && j_ind >= global_zoom_jbegin && j_ind <= global_zoom_jend) { globalIndexDomainZoom(globalIndexCountZoom) = globalIndex; localIndexDomainZoom(globalIndexCountZoom) = i; ++globalIndexCountZoom; } } size_t globalSizeIndex = 1, indexBegin, indexEnd; int range, clientSize = client->clientSize; for (int i = 0; i < nGlobDomain_.size(); ++i) globalSizeIndex *= nGlobDomain_[i]; indexBegin = 0; for (int i = 0; i < clientSize; ++i) { range = globalSizeIndex / clientSize; if (i < (globalSizeIndex%clientSize)) ++range; if (i == client->clientRank) break; indexBegin += range; } indexEnd = indexBegin + range - 1; CServerDistributionDescription serverDescription(nGlobDomain_); if (isUnstructed_) serverDescription.computeServerGlobalIndexInRange(nbServer, std::make_pair(indexBegin, indexEnd), 0); else serverDescription.computeServerGlobalIndexInRange(nbServer, std::make_pair(indexBegin, indexEnd), 1); CClientServerMapping* clientServerMap = new CClientServerMappingDistributed(serverDescription.getGlobalIndexRange(), client->intraComm); clientServerMap->computeServerIndexMapping(globalIndexDomain); const std::map >& globalIndexDomainOnServer = clientServerMap->getGlobalIndexOnServer(); std::map >::const_iterator it = globalIndexDomainOnServer.begin(), ite = globalIndexDomainOnServer.end(); indSrv_.clear(); for (; it != ite; ++it) { int rank = it->first; std::vector::const_iterator itbVec = (it->second).begin(), iteVec = (it->second).end(); int nb = globalIndexDomainZoom.numElements(); for (int i = 0; i < nb; ++i) { if (iteVec != std::find(itbVec, iteVec, globalIndexDomainZoom(i))) { indSrv_[rank].push_back(localIndexDomainZoom(i)); } } } connectedServerRank_.clear(); for (it = globalIndexDomainOnServer.begin(); it != ite; ++it) { connectedServerRank_.push_back(it->first); } if (!indSrv_.empty()) { connectedServerRank_.clear(); for (it = indSrv_.begin(); it != indSrv_.end(); ++it) connectedServerRank_.push_back(it->first); } nbConnectedClients_ = clientServerMap->computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_); delete clientServerMap; } const std::map >& CDomain::getIndexServer() const { return indSrv_; } void CDomain::sendIndex() { int ns, n, i, j, ind, nv, idx; CContext* context = CContext::getCurrent(); CContextClient* client=context->client; CEventClient eventIndex(getType(), EVENT_ID_INDEX); list list_msgsIndex; list > list_indi, list_indj; std::map >::const_iterator it, iteMap; iteMap = indSrv_.end(); for (int k = 0; k < connectedServerRank_.size(); ++k) { int nbData = 0; int rank = connectedServerRank_[k]; it = indSrv_.find(rank); if (iteMap != it) nbData = it->second.size(); list_indi.push_back(CArray(nbData)); list_indj.push_back(CArray(nbData)); CArray& indi = list_indi.back(); CArray& indj = list_indj.back(); const std::vector& temp = it->second; for (n = 0; n < nbData; ++n) { idx = static_cast(it->second[n]); indi(n) = i_index(idx); indj(n) = j_index(idx); } list_msgsIndex.push_back(CMessage()); list_msgsIndex.back() << this->getId() << (int)type; // enum ne fonctionne pour les message => ToFix list_msgsIndex.back() << isCurvilinear; list_msgsIndex.back() << list_indi.back() << list_indj.back(); eventIndex.push(rank, nbConnectedClients_[rank], list_msgsIndex.back()); } client->sendEvent(eventIndex); } void CDomain::sendArea() { if (!hasArea) return; int ns, n, i, j, ind, nv, idx; CContext* context = CContext::getCurrent(); CContextClient* client=context->client; // send area for each connected server CEventClient eventArea(getType(), EVENT_ID_AREA); list list_msgsArea; list > list_area; std::map >::const_iterator it, iteMap; iteMap = indSrv_.end(); for (int k = 0; k < connectedServerRank_.size(); ++k) { int nbData = 0; int rank = connectedServerRank_[k]; it = indSrv_.find(rank); if (iteMap != it) nbData = it->second.size(); list_area.push_back(CArray(nbData)); const std::vector& temp = it->second; for (n = 0; n < nbData; ++n) { idx = static_cast(it->second[n]); i = i_index(idx); j = j_index(idx); if (hasArea) list_area.back()(n) = area(i - ibegin, j - jbegin); } list_msgsArea.push_back(CMessage()); list_msgsArea.back() << this->getId() << list_area.back(); eventArea.push(rank, nbConnectedClients_[rank], list_msgsArea.back()); } client->sendEvent(eventArea); } void CDomain::sendLonLat() { if (!hasLonLat) return; int ns, n, i, j, ind, nv, idx; CContext* context = CContext::getCurrent(); CContextClient* client=context->client; // send lon lat for each connected server CEventClient eventLon(getType(), EVENT_ID_LON); CEventClient eventLat(getType(), EVENT_ID_LAT); list list_msgsLon, list_msgsLat; list > list_lon, list_lat; list > list_boundslon, list_boundslat; std::map >::const_iterator it, iteMap; iteMap = indSrv_.end(); for (int k = 0; k < connectedServerRank_.size(); ++k) { int nbData = 0; int rank = connectedServerRank_[k]; it = indSrv_.find(rank); if (iteMap != it) nbData = it->second.size(); list_lon.push_back(CArray(nbData)); list_lat.push_back(CArray(nbData)); if (hasBounds) { list_boundslon.push_back(CArray(nvertex, nbData)); list_boundslat.push_back(CArray(nvertex, nbData)); } CArray& lon = list_lon.back(); CArray& lat = list_lat.back(); const std::vector& temp = it->second; for (n = 0; n < nbData; ++n) { idx = static_cast(it->second[n]); lon(n) = lonvalue_client(idx); lat(n) = latvalue_client(idx); if (hasBounds) { CArray& boundslon = list_boundslon.back(); CArray& boundslat = list_boundslat.back(); for (nv = 0; nv < nvertex; ++nv) { boundslon(nv, n) = bounds_lon_client(nv, idx); boundslat(nv, n) = bounds_lat_client(nv, idx); } } } list_msgsLon.push_back(CMessage()); list_msgsLat.push_back(CMessage()); list_msgsLon.back() << this->getId() << list_lon.back(); list_msgsLat.back() << this->getId() << list_lat.back(); if (hasBounds) { list_msgsLon.back() << list_boundslon.back(); list_msgsLat.back() << list_boundslat.back(); } eventLon.push(rank, nbConnectedClients_[rank], list_msgsLon.back()); eventLat.push(rank, nbConnectedClients_[rank], list_msgsLat.back()); } client->sendEvent(eventLon); client->sendEvent(eventLat); } void CDomain::sendLonLatArea(void) { sendIndex(); sendLonLat(); sendArea(); } bool CDomain::dispatchEvent(CEventServer& event) { if (SuperClass::dispatchEvent(event)) return true; else { switch(event.type) { case EVENT_ID_SERVER_ATTRIBUT: recvServerAttribut(event); return true; break; case EVENT_ID_INDEX: recvIndex(event); return true; break; case EVENT_ID_LON: recvLon(event); return true; break; case EVENT_ID_LAT: recvLat(event); return true; break; case EVENT_ID_AREA: recvArea(event); return true; break; default: ERROR("bool CContext::dispatchEvent(CEventServer& event)", << "Unknown Event"); return false; } } } void CDomain::recvServerAttribut(CEventServer& event) { CBufferIn* buffer=event.subEvents.begin()->buffer; string domainId ; *buffer>>domainId ; get(domainId)->recvServerAttribut(*buffer) ; } void CDomain::recvServerAttribut(CBufferIn& buffer) { buffer >> ni_srv >> ibegin_srv >> iend_srv >> nj_srv >> jbegin_srv >> jend_srv >> global_zoom_ni >> global_zoom_ibegin >> global_zoom_nj >> global_zoom_jbegin; int zoom_iend = global_zoom_ibegin + global_zoom_ni - 1; int zoom_jend = global_zoom_jbegin + global_zoom_nj - 1; zoom_ibegin_srv = global_zoom_ibegin > ibegin_srv ? global_zoom_ibegin : ibegin_srv ; zoom_iend_srv = zoom_iend < iend_srv ? zoom_iend : iend_srv ; zoom_ni_srv=zoom_iend_srv-zoom_ibegin_srv+1 ; zoom_jbegin_srv = global_zoom_jbegin > jbegin_srv ? global_zoom_jbegin : jbegin_srv ; zoom_jend_srv = zoom_jend < jend_srv ? zoom_jend : jend_srv ; zoom_nj_srv=zoom_jend_srv-zoom_jbegin_srv+1 ; if (zoom_ni_srv<=0 || zoom_nj_srv<=0) { zoom_ibegin_srv=0 ; zoom_iend_srv=0 ; zoom_ni_srv=0 ; zoom_jbegin_srv=0 ; zoom_jend_srv=0 ; zoom_nj_srv=0 ; } lonvalue_srv.resize(zoom_ni_srv*zoom_nj_srv) ; lonvalue_srv = 0. ; latvalue_srv.resize(zoom_ni_srv*zoom_nj_srv) ; latvalue_srv = 0. ; if (hasBounds) { bounds_lon_srv.resize(nvertex,zoom_ni_srv*zoom_nj_srv) ; bounds_lon_srv = 0. ; bounds_lat_srv.resize(nvertex,zoom_ni_srv*zoom_nj_srv) ; bounds_lat_srv = 0. ; } if (hasArea) area_srv.resize(zoom_ni_srv * zoom_nj_srv); } void CDomain::recvIndex(CEventServer& event) { list::iterator it; for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it) { CBufferIn* buffer = it->buffer; string domainId; *buffer >> domainId; get(domainId)->recvIndex(it->rank, *buffer); } } void CDomain::recvIndex(int rank, CBufferIn& buffer) { int type_int; buffer >> type_int >> isCurvilinear >> indiSrv[rank] >> indjSrv[rank]; type.setValue((type_attr::t_enum)type_int); // probleme des type enum avec les buffers : ToFix } void CDomain::recvLon(CEventServer& event) { list::iterator it; for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it) { CBufferIn* buffer = it->buffer; string domainId; *buffer >> domainId; get(domainId)->recvLon(it->rank, *buffer); } } void CDomain::recvLon(int rank, CBufferIn& buffer) { CArray &indi = indiSrv[rank], &indj = indjSrv[rank]; CArray lon; CArray boundslon; buffer >> lon; if (hasBounds) buffer >> boundslon; int i, j, ind_srv; for (int ind = 0; ind < indi.numElements(); ind++) { i = indi(ind); j = indj(ind); ind_srv = (i - zoom_ibegin_srv) + (j - zoom_jbegin_srv) * zoom_ni_srv; lonvalue_srv(ind_srv) = lon(ind); if (hasBounds) { for (int nv = 0; nv < nvertex; ++nv) bounds_lon_srv(nv, ind_srv) = boundslon(nv, ind); } } } void CDomain::recvLat(CEventServer& event) { list::iterator it; for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it) { CBufferIn* buffer = it->buffer; string domainId; *buffer >> domainId; get(domainId)->recvLat(it->rank, *buffer); } } void CDomain::recvLat(int rank, CBufferIn& buffer) { CArray &indi = indiSrv[rank], &indj = indjSrv[rank]; CArray lat; CArray boundslat; buffer >> lat; if (hasBounds) buffer >> boundslat; int i, j, ind_srv; for (int ind = 0; ind < indi.numElements(); ind++) { i = indi(ind); j = indj(ind); ind_srv = (i - zoom_ibegin_srv) + (j - zoom_jbegin_srv) * zoom_ni_srv; latvalue_srv(ind_srv) = lat(ind); if (hasBounds) { for (int nv = 0; nv < nvertex; nv++) bounds_lat_srv(nv, ind_srv) = boundslat(nv, ind); } } } void CDomain::recvArea(CEventServer& event) { list::iterator it; for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it) { CBufferIn* buffer = it->buffer; string domainId; *buffer >> domainId; get(domainId)->recvArea(it->rank, *buffer); } } void CDomain::recvArea(int rank, CBufferIn& buffer) { CArray &indi = indiSrv[rank], &indj = indjSrv[rank]; CArray clientArea; buffer >> clientArea; int i, j, ind_srv; for (int ind = 0; ind < indi.numElements(); ind++) { i = indi(ind); j = indj(ind); ind_srv = (i - zoom_ibegin_srv) + (j - zoom_jbegin_srv) * zoom_ni_srv; area_srv(ind_srv) = clientArea(ind); } } bool CDomain::hasTransformation() { return (!transformationMap_.empty()); } void CDomain::setTransformations(const TransMapTypes& domTrans) { transformationMap_ = domTrans; } CDomain::TransMapTypes CDomain::getAllTransformations(void) { return transformationMap_; } /*! Check the validity of all transformations applied on domain This functions is called AFTER all inherited attributes are solved */ void CDomain::checkTransformations() { TransMapTypes::const_iterator itb = transformationMap_.begin(), it, ite = transformationMap_.end(); for (it = itb; it != ite; ++it) { (it->second)->checkValid(this); } } void CDomain::solveInheritanceTransformation() { if (this->hasTransformation()) return; std::vector refDomain; CDomain* refer_sptr; CDomain* refer_ptr = this; while (refer_ptr->hasDirectDomainReference()) { refDomain.push_back(refer_ptr); refer_sptr = refer_ptr->getDirectDomainReference(); refer_ptr = refer_sptr; if (refer_ptr->hasTransformation()) break; } if (refer_ptr->hasTransformation()) for (int idx = 0; idx < refDomain.size(); ++idx) refDomain[idx]->setTransformations(refer_ptr->getAllTransformations()); } void CDomain::parse(xml::CXMLNode & node) { SuperClass::parse(node); if (node.goToChildElement()) { StdString zoomDomainDefRoot("zoom_domain_definition"); StdString zoom("zoom_domain"); StdString interpFromFileDomainDefRoot("interpolate_from_file_domain_definition"); StdString interpFromFile("interpolate_from_file_domain"); do { if (node.getElementName() == zoom) { CZoomDomain* tmp = (CZoomDomainGroup::get(zoomDomainDefRoot))->createChild(); tmp->parse(node); transformationMap_.push_back(std::make_pair(TRANS_ZOOM_DOMAIN,tmp)); } else if (node.getElementName() == interpFromFile) { CInterpolateFromFileDomain* tmp = (CInterpolateFromFileDomainGroup::get(interpFromFileDomainDefRoot))->createChild(); tmp->parse(node); transformationMap_.push_back(std::make_pair(TRANS_INTERPOLATE_DOMAIN_FROM_FILE,tmp)); } } while (node.goToNextElement()) ; node.goToParentElement(); } } //---------------------------------------------------------------- DEFINE_REF_FUNC(Domain,domain) ///--------------------------------------------------------------- } // namespace xios