[219] | 1 | #include "field.hpp" |
---|
| 2 | |
---|
[352] | 3 | #include "attribute_template.hpp" |
---|
| 4 | #include "object_template.hpp" |
---|
| 5 | #include "group_template.hpp" |
---|
[219] | 6 | |
---|
| 7 | #include "node_type.hpp" |
---|
| 8 | #include "calendar_util.hpp" |
---|
[352] | 9 | #include "message.hpp" |
---|
| 10 | #include "xmlioserver_spl.hpp" |
---|
| 11 | #include "type.hpp" |
---|
| 12 | #include "context_client.hpp" |
---|
[459] | 13 | #include <set> |
---|
[219] | 14 | |
---|
[335] | 15 | namespace xios{ |
---|
[219] | 16 | |
---|
| 17 | /// ////////////////////// Définitions ////////////////////// /// |
---|
| 18 | |
---|
| 19 | CField::CField(void) |
---|
| 20 | : CObjectTemplate<CField>(), CFieldAttributes() |
---|
| 21 | , refObject(), baseRefObject() |
---|
| 22 | , grid(), file() |
---|
| 23 | , freq_operation(), freq_write() |
---|
[266] | 24 | , nstep(0) |
---|
[219] | 25 | , last_Write(), last_operation() |
---|
[459] | 26 | , foperation(), hasInstantData(false), hasExpression(false) |
---|
| 27 | , active(false) , hasOutputFile(false), slotUpdateDate(NULL) |
---|
| 28 | , processed(false) |
---|
[369] | 29 | { /* Ne rien faire de plus */ } |
---|
[219] | 30 | |
---|
| 31 | CField::CField(const StdString & id) |
---|
| 32 | : CObjectTemplate<CField>(id), CFieldAttributes() |
---|
| 33 | , refObject(), baseRefObject() |
---|
| 34 | , grid(), file() |
---|
| 35 | , freq_operation(), freq_write() |
---|
[266] | 36 | , nstep(0) |
---|
[219] | 37 | , last_Write(), last_operation() |
---|
[459] | 38 | , foperation(), hasExpression(false) |
---|
| 39 | , active(false), hasOutputFile(false), slotUpdateDate(NULL) |
---|
| 40 | , processed(false) |
---|
[219] | 41 | { /* Ne rien faire de plus */ } |
---|
| 42 | |
---|
| 43 | CField::~CField(void) |
---|
| 44 | { |
---|
[347] | 45 | // this->grid.reset() ; |
---|
| 46 | // this->file.reset() ; |
---|
[219] | 47 | this->foperation.reset() ; |
---|
[459] | 48 | if (hasExpression) delete expression ; |
---|
| 49 | if (slotUpdateDate!=NULL) delete slotUpdateDate ; |
---|
| 50 | |
---|
[219] | 51 | } |
---|
| 52 | |
---|
| 53 | //---------------------------------------------------------------- |
---|
| 54 | |
---|
| 55 | bool CField::updateDataServer |
---|
[343] | 56 | (const CDate & currDate, |
---|
[369] | 57 | const std::deque< CArray<double, 1>* > storedClient) |
---|
[219] | 58 | { |
---|
[343] | 59 | const CDate opeDate = *last_operation + freq_operation; |
---|
| 60 | const CDate writeDate = *last_Write + freq_write; |
---|
[278] | 61 | |
---|
| 62 | if (opeDate <= currDate) |
---|
[219] | 63 | { |
---|
[369] | 64 | if (this->data.numElements() != this->grid->storeIndex[0]->numElements()) |
---|
[278] | 65 | { |
---|
[369] | 66 | this->data.resize(this->grid->storeIndex[0] ->numElements()); |
---|
[278] | 67 | } |
---|
[369] | 68 | CArray<double,1> input(data.numElements()) ; |
---|
[278] | 69 | this->grid->inputFieldServer(storedClient, input); |
---|
[219] | 70 | (*this->foperation)(input); |
---|
| 71 | *last_operation = currDate; |
---|
| 72 | } |
---|
[278] | 73 | if (writeDate < (currDate + freq_operation)) |
---|
[219] | 74 | { |
---|
[278] | 75 | this->foperation->final(); |
---|
| 76 | this->incrementNStep(); |
---|
| 77 | *last_Write = writeDate; |
---|
| 78 | return (true); |
---|
[219] | 79 | } |
---|
| 80 | return (false); |
---|
| 81 | } |
---|
[300] | 82 | |
---|
| 83 | bool CField::dispatchEvent(CEventServer& event) |
---|
| 84 | { |
---|
| 85 | |
---|
| 86 | if (SuperClass::dispatchEvent(event)) return true ; |
---|
| 87 | else |
---|
| 88 | { |
---|
| 89 | switch(event.type) |
---|
| 90 | { |
---|
| 91 | case EVENT_ID_UPDATE_DATA : |
---|
| 92 | recvUpdateData(event) ; |
---|
| 93 | return true ; |
---|
| 94 | break ; |
---|
| 95 | |
---|
| 96 | default : |
---|
| 97 | ERROR("bool CField::dispatchEvent(CEventServer& event)",<<"Unknown Event") ; |
---|
| 98 | return false ; |
---|
| 99 | } |
---|
| 100 | } |
---|
| 101 | } |
---|
| 102 | |
---|
| 103 | void CField::sendUpdateData(void) |
---|
| 104 | { |
---|
[347] | 105 | CContext* context = CContext::getCurrent() ; |
---|
[300] | 106 | CContextClient* client=context->client ; |
---|
| 107 | |
---|
| 108 | CEventClient event(getType(),EVENT_ID_UPDATE_DATA) ; |
---|
| 109 | |
---|
[369] | 110 | map<int,CArray<int, 1>* >::iterator it ; |
---|
[300] | 111 | list<shared_ptr<CMessage> > list_msg ; |
---|
[369] | 112 | list< CArray<double,1>* > list_data ; |
---|
[300] | 113 | |
---|
| 114 | for(it=grid->storeIndex_toSrv.begin();it!=grid->storeIndex_toSrv.end();it++) |
---|
| 115 | { |
---|
| 116 | int rank=(*it).first ; |
---|
[369] | 117 | CArray<int,1>& index = *(it->second) ; |
---|
| 118 | CArray<double,1> data_tmp(index.numElements()) ; |
---|
| 119 | |
---|
| 120 | for(int n=0;n<data_tmp.numElements();n++) data_tmp(n)=data(index(n)) ; |
---|
[300] | 121 | list_msg.push_back(shared_ptr<CMessage>(new CMessage)) ; |
---|
[369] | 122 | list_data.push_back(new CArray<double,1>(data_tmp)) ; |
---|
| 123 | *list_msg.back()<<getId()<<*list_data.back() ; |
---|
[300] | 124 | event.push(rank,grid->nbSenders[rank],*list_msg.back()) ; |
---|
| 125 | } |
---|
| 126 | client->sendEvent(event) ; |
---|
[369] | 127 | |
---|
| 128 | for(list< CArray<double,1>* >::iterator it=list_data.begin();it!=list_data.end();it++) delete *it ; |
---|
[300] | 129 | } |
---|
| 130 | |
---|
| 131 | void CField::recvUpdateData(CEventServer& event) |
---|
| 132 | { |
---|
| 133 | vector<int> ranks ; |
---|
| 134 | vector<CBufferIn*> buffers ; |
---|
| 135 | |
---|
| 136 | list<CEventServer::SSubEvent>::iterator it ; |
---|
| 137 | string fieldId ; |
---|
[219] | 138 | |
---|
[300] | 139 | for (it=event.subEvents.begin();it!=event.subEvents.end();++it) |
---|
| 140 | { |
---|
| 141 | int rank=it->rank; |
---|
| 142 | CBufferIn* buffer=it->buffer; |
---|
| 143 | *buffer>>fieldId ; |
---|
| 144 | ranks.push_back(rank) ; |
---|
| 145 | buffers.push_back(buffer) ; |
---|
| 146 | } |
---|
| 147 | get(fieldId)->recvUpdateData(ranks,buffers) ; |
---|
| 148 | } |
---|
| 149 | |
---|
| 150 | void CField::recvUpdateData(vector<int>& ranks, vector<CBufferIn*>& buffers) |
---|
| 151 | { |
---|
| 152 | |
---|
| 153 | if (data_srv.empty()) |
---|
| 154 | { |
---|
[369] | 155 | for(map<int, CArray<int, 1>* >::iterator it=grid->out_i_fromClient.begin();it!=grid->out_i_fromClient.end();it++) |
---|
[300] | 156 | { |
---|
| 157 | int rank=it->first ; |
---|
[369] | 158 | CArray<double,1> data_tmp(it->second->numElements()) ; |
---|
| 159 | data_srv.insert( pair<int, CArray<double,1>* >(rank, new CArray<double,1>(data_tmp) ) ) ; |
---|
| 160 | foperation_srv.insert(pair<int,boost::shared_ptr<func::CFunctor> >(rank,boost::shared_ptr<func::CFunctor>(new func::CInstant(*data_srv[rank])))) ; |
---|
[300] | 161 | } |
---|
| 162 | } |
---|
| 163 | |
---|
[347] | 164 | CContext* context = CContext::getCurrent() ; |
---|
[343] | 165 | const CDate & currDate = context->getCalendar()->getCurrentDate(); |
---|
| 166 | const CDate opeDate = *last_operation_srv + freq_operation_srv; |
---|
| 167 | const CDate writeDate = *last_Write_srv + freq_write_srv; |
---|
[300] | 168 | |
---|
| 169 | |
---|
| 170 | |
---|
| 171 | if (opeDate <= currDate) |
---|
| 172 | { |
---|
| 173 | for(int n=0;n<ranks.size();n++) |
---|
| 174 | { |
---|
[369] | 175 | CArray<double,1> data_tmp ; |
---|
[300] | 176 | *buffers[n]>>data_tmp ; |
---|
| 177 | (*foperation_srv[ranks[n]])(data_tmp) ; |
---|
| 178 | } |
---|
| 179 | *last_operation_srv = currDate; |
---|
| 180 | } |
---|
| 181 | |
---|
| 182 | if (writeDate < (currDate + freq_operation_srv)) |
---|
| 183 | { |
---|
| 184 | for(int n=0;n<ranks.size();n++) |
---|
| 185 | { |
---|
| 186 | this->foperation_srv[ranks[n]]->final(); |
---|
| 187 | } |
---|
| 188 | |
---|
| 189 | *last_Write_srv = writeDate; |
---|
| 190 | writeField() ; |
---|
[334] | 191 | *lastlast_Write_srv=*last_Write_srv; |
---|
[300] | 192 | } |
---|
| 193 | } |
---|
| 194 | |
---|
| 195 | void CField::writeField(void) |
---|
| 196 | { |
---|
[379] | 197 | if (! getRelFile()->allDomainEmpty ) |
---|
| 198 | if (! grid->domain->isEmpty() || getRelFile()->type == CFile::type_attr::one_file) |
---|
| 199 | { |
---|
| 200 | getRelFile()->checkFile(); |
---|
| 201 | this->incrementNStep(); |
---|
| 202 | getRelFile()->getDataOutput()->writeFieldData(CField::get(this)); |
---|
| 203 | } |
---|
[300] | 204 | } |
---|
[219] | 205 | //---------------------------------------------------------------- |
---|
| 206 | |
---|
[347] | 207 | void CField::setRelFile(CFile* _file) |
---|
[219] | 208 | { |
---|
[459] | 209 | this->file = _file; |
---|
| 210 | hasOutputFile=true ; |
---|
[219] | 211 | } |
---|
| 212 | |
---|
| 213 | //---------------------------------------------------------------- |
---|
| 214 | |
---|
| 215 | StdString CField::GetName(void) { return (StdString("field")); } |
---|
| 216 | StdString CField::GetDefName(void){ return (CField::GetName()); } |
---|
| 217 | ENodeType CField::GetType(void) { return (eField); } |
---|
| 218 | |
---|
| 219 | //---------------------------------------------------------------- |
---|
| 220 | |
---|
[347] | 221 | CGrid* CField::getRelGrid(void) const |
---|
[219] | 222 | { |
---|
| 223 | return (this->grid); |
---|
| 224 | } |
---|
| 225 | |
---|
| 226 | //---------------------------------------------------------------- |
---|
| 227 | |
---|
[347] | 228 | CFile* CField::getRelFile(void) const |
---|
[219] | 229 | { |
---|
| 230 | return (this->file); |
---|
| 231 | } |
---|
[266] | 232 | |
---|
| 233 | StdSize CField::getNStep(void) const |
---|
| 234 | { |
---|
| 235 | return (this->nstep); |
---|
| 236 | } |
---|
| 237 | |
---|
| 238 | void CField::incrementNStep(void) |
---|
| 239 | { |
---|
| 240 | this->nstep++; |
---|
| 241 | } |
---|
[321] | 242 | |
---|
| 243 | void CField::resetNStep(void) |
---|
| 244 | { |
---|
| 245 | this->nstep=0; |
---|
| 246 | } |
---|
[219] | 247 | |
---|
| 248 | //---------------------------------------------------------------- |
---|
| 249 | |
---|
[347] | 250 | CField* CField::getDirectFieldReference(void) const |
---|
[219] | 251 | { |
---|
| 252 | if (this->field_ref.isEmpty()) |
---|
| 253 | return (this->getBaseFieldReference()); |
---|
| 254 | |
---|
[346] | 255 | if (! CField::has(this->field_ref.getValue())) |
---|
[219] | 256 | ERROR("CField::getDirectFieldReference(void)", |
---|
| 257 | << "[ ref_name = " << this->field_ref.getValue() << "]" |
---|
| 258 | << " invalid field name !"); |
---|
| 259 | |
---|
[346] | 260 | return (CField::get(this->field_ref.getValue())); |
---|
[219] | 261 | } |
---|
| 262 | |
---|
| 263 | //---------------------------------------------------------------- |
---|
| 264 | |
---|
[347] | 265 | CField* CField::getBaseFieldReference(void) const |
---|
[219] | 266 | { |
---|
| 267 | return (baseRefObject); |
---|
| 268 | } |
---|
| 269 | |
---|
| 270 | //---------------------------------------------------------------- |
---|
| 271 | |
---|
[347] | 272 | const std::vector<CField*>& CField::getAllReference(void) const |
---|
[219] | 273 | { |
---|
| 274 | return (refObject); |
---|
| 275 | } |
---|
| 276 | |
---|
| 277 | //---------------------------------------------------------------- |
---|
| 278 | |
---|
| 279 | const StdString & CField::getBaseFieldId(void) const |
---|
| 280 | { |
---|
| 281 | return (this->getBaseFieldReference()->getId()); |
---|
| 282 | } |
---|
| 283 | |
---|
| 284 | //---------------------------------------------------------------- |
---|
| 285 | |
---|
[343] | 286 | const CDuration & CField::getFreqOperation(void) const |
---|
[219] | 287 | { |
---|
| 288 | return (this->freq_operation); |
---|
| 289 | } |
---|
| 290 | |
---|
| 291 | //---------------------------------------------------------------- |
---|
[343] | 292 | const CDuration & CField::getFreqWrite(void) const |
---|
[219] | 293 | { |
---|
| 294 | return (this->freq_write); |
---|
| 295 | } |
---|
| 296 | |
---|
| 297 | //---------------------------------------------------------------- |
---|
| 298 | |
---|
| 299 | boost::shared_ptr<func::CFunctor> CField::getFieldOperation(void) const |
---|
| 300 | { |
---|
| 301 | return (this->foperation); |
---|
| 302 | } |
---|
| 303 | |
---|
| 304 | //---------------------------------------------------------------- |
---|
| 305 | |
---|
| 306 | bool CField::hasDirectFieldReference(void) const |
---|
| 307 | { |
---|
[310] | 308 | return (!this->field_ref.isEmpty()); |
---|
[219] | 309 | } |
---|
| 310 | |
---|
[310] | 311 | bool CField::isActive(void) const |
---|
| 312 | { |
---|
| 313 | return (!this->refObject.empty()); |
---|
| 314 | } |
---|
[219] | 315 | //---------------------------------------------------------------- |
---|
| 316 | |
---|
[369] | 317 | CArray<double, 1> CField::getData(void) const |
---|
[219] | 318 | { |
---|
| 319 | return(this->data); |
---|
| 320 | } |
---|
| 321 | |
---|
| 322 | //---------------------------------------------------------------- |
---|
| 323 | |
---|
[343] | 324 | boost::shared_ptr<CDate> CField::getLastWriteDate(void) const |
---|
[219] | 325 | { |
---|
| 326 | return(this->last_Write); |
---|
| 327 | } |
---|
| 328 | |
---|
| 329 | //---------------------------------------------------------------- |
---|
| 330 | |
---|
[343] | 331 | boost::shared_ptr<CDate> CField::getLastOperationDate(void) const |
---|
[219] | 332 | { |
---|
| 333 | return(this->last_operation); |
---|
| 334 | } |
---|
| 335 | |
---|
| 336 | //---------------------------------------------------------------- |
---|
| 337 | |
---|
[459] | 338 | void CField::processEnabledField(void) |
---|
| 339 | { |
---|
| 340 | if (!processed) |
---|
| 341 | { |
---|
| 342 | processed=true ; |
---|
| 343 | solveRefInheritance(true) ; |
---|
| 344 | solveOperation() ; |
---|
| 345 | solveGridReference() ; |
---|
| 346 | |
---|
| 347 | if (hasDirectFieldReference()) baseRefObject->processEnabledField() ; |
---|
| 348 | buildExpression(); |
---|
| 349 | active=true; |
---|
| 350 | } |
---|
| 351 | } |
---|
| 352 | |
---|
[445] | 353 | void CField::solveRefInheritance(bool apply) |
---|
[219] | 354 | { |
---|
| 355 | std::set<CField *> sset; |
---|
[347] | 356 | CField* refer_sptr; |
---|
[219] | 357 | CField * refer_ptr = this; |
---|
| 358 | |
---|
[459] | 359 | if (this->hasDirectFieldReference()) baseRefObject = getDirectFieldReference(); |
---|
| 360 | else baseRefObject = CField::get(this); |
---|
[219] | 361 | |
---|
| 362 | while (refer_ptr->hasDirectFieldReference()) |
---|
| 363 | { |
---|
| 364 | refer_sptr = refer_ptr->getDirectFieldReference(); |
---|
[347] | 365 | refer_ptr = refer_sptr; |
---|
[219] | 366 | |
---|
| 367 | if(sset.end() != sset.find(refer_ptr)) |
---|
| 368 | { |
---|
| 369 | DEBUG (<< "Dépendance circulaire stoppée pour l'objet de type CField sur " |
---|
| 370 | << "\"" + refer_ptr->getId() + "\" !"); |
---|
| 371 | break; |
---|
| 372 | } |
---|
| 373 | |
---|
[445] | 374 | SuperClassAttribute::setAttributes(refer_ptr, apply); |
---|
[219] | 375 | sset.insert(refer_ptr); |
---|
[459] | 376 | //ym baseRefObject = refer_sptr; |
---|
[286] | 377 | //ym refObject.push_back(refer_sptr); |
---|
[219] | 378 | } |
---|
[459] | 379 | |
---|
| 380 | if (hasDirectFieldReference()) baseRefObject->addReference(this) ; |
---|
[219] | 381 | } |
---|
| 382 | |
---|
| 383 | //---------------------------------------------------------------- |
---|
| 384 | |
---|
| 385 | void CField::solveOperation(void) |
---|
| 386 | { |
---|
| 387 | using namespace func; |
---|
[459] | 388 | |
---|
| 389 | if (!hasOutputFile) return ; |
---|
| 390 | |
---|
| 391 | StdString id ; |
---|
| 392 | if (hasId()) id=getId(); |
---|
| 393 | else if (!name.isEmpty()) id=name ; |
---|
| 394 | else if (hasDirectFieldReference()) id=baseRefObject->getId() ; |
---|
| 395 | |
---|
[347] | 396 | CContext* context = CContext::getCurrent(); |
---|
[436] | 397 | |
---|
| 398 | if (freq_op.isEmpty()) freq_op=string("1ts") ; |
---|
| 399 | |
---|
[459] | 400 | if (operation.isEmpty() ) |
---|
[219] | 401 | { |
---|
| 402 | ERROR("CField::solveOperation(void)", |
---|
| 403 | << "[ id = " << id << "]" |
---|
[421] | 404 | << "Impossible to define an operation for this field !"); |
---|
[219] | 405 | } |
---|
[278] | 406 | |
---|
| 407 | CDuration freq_offset_ = NoneDu; |
---|
| 408 | if (!freq_offset.isEmpty()) |
---|
| 409 | { |
---|
| 410 | freq_offset_ = CDuration::FromString(freq_offset.getValue()); |
---|
| 411 | } |
---|
| 412 | else |
---|
| 413 | { |
---|
| 414 | freq_offset.setValue(NoneDu.toString()); |
---|
| 415 | } |
---|
[219] | 416 | |
---|
[300] | 417 | // if (CXIOSManager::GetStatus() == CXIOSManager::LOC_SERVER) |
---|
| 418 | if (context->hasServer) |
---|
[219] | 419 | { |
---|
[300] | 420 | this->freq_operation_srv = |
---|
[219] | 421 | CDuration::FromString(this->file->output_freq.getValue()); |
---|
[300] | 422 | this->freq_write_srv = |
---|
[219] | 423 | CDuration::FromString(this->file->output_freq.getValue()); |
---|
[343] | 424 | this->lastlast_Write_srv = boost::shared_ptr<CDate> |
---|
| 425 | (new CDate(context->getCalendar()->getInitDate())); |
---|
| 426 | this->last_Write_srv = boost::shared_ptr<CDate> |
---|
| 427 | (new CDate(context->getCalendar()->getInitDate())); |
---|
| 428 | this->last_operation_srv = boost::shared_ptr<CDate> |
---|
| 429 | (new CDate(context->getCalendar()->getInitDate())); |
---|
[300] | 430 | // this->foperation_srv = |
---|
| 431 | // boost::shared_ptr<func::CFunctor>(new CInstant(this->data_srv)); |
---|
[278] | 432 | |
---|
[300] | 433 | const CDuration toffset = this->freq_operation_srv - freq_offset_ - context->getCalendar()->getTimeStep(); |
---|
| 434 | *this->last_operation_srv = *this->last_operation_srv - toffset; |
---|
[219] | 435 | } |
---|
[300] | 436 | |
---|
[449] | 437 | // if (context->hasClient) |
---|
| 438 | // { |
---|
[219] | 439 | this->freq_operation = CDuration::FromString(freq_op.getValue()); |
---|
| 440 | this->freq_write = CDuration::FromString(this->file->output_freq.getValue()); |
---|
[343] | 441 | this->last_Write = boost::shared_ptr<CDate> |
---|
| 442 | (new CDate(context->getCalendar()->getInitDate())); |
---|
| 443 | this->last_operation = boost::shared_ptr<CDate> |
---|
| 444 | (new CDate(context->getCalendar()->getInitDate())); |
---|
[278] | 445 | |
---|
[300] | 446 | const CDuration toffset = this->freq_operation - freq_offset_ - context->getCalendar()->getTimeStep(); |
---|
[278] | 447 | *this->last_operation = *this->last_operation - toffset; |
---|
[436] | 448 | |
---|
| 449 | if (operation.get()=="once") isOnceOperation=true ; |
---|
| 450 | else isOnceOperation=false; |
---|
| 451 | isFirstOperation=true; |
---|
[439] | 452 | |
---|
[219] | 453 | #define DECLARE_FUNCTOR(MType, mtype) \ |
---|
| 454 | if (operation.getValue().compare(#mtype) == 0) \ |
---|
| 455 | { \ |
---|
| 456 | boost::shared_ptr<func::CFunctor> \ |
---|
| 457 | foperation_(new C##MType(this->data)); \ |
---|
| 458 | this->foperation = foperation_; \ |
---|
| 459 | return; \ |
---|
| 460 | } |
---|
| 461 | |
---|
| 462 | #include "functor_type.conf" |
---|
| 463 | |
---|
| 464 | ERROR("CField::solveOperation(void)", |
---|
| 465 | << "[ operation = " << operation.getValue() << "]" |
---|
[421] | 466 | << "The operation is not defined !"); |
---|
[449] | 467 | // } |
---|
[436] | 468 | |
---|
| 469 | |
---|
[219] | 470 | } |
---|
| 471 | |
---|
| 472 | //---------------------------------------------------------------- |
---|
[369] | 473 | /* |
---|
[219] | 474 | void CField::fromBinary(StdIStream & is) |
---|
| 475 | { |
---|
| 476 | SuperClass::fromBinary(is); |
---|
| 477 | #define CLEAR_ATT(name_)\ |
---|
[369] | 478 | SuperClassAttribute::operator[](#name_)->reset() |
---|
[219] | 479 | |
---|
| 480 | CLEAR_ATT(domain_ref); |
---|
| 481 | CLEAR_ATT(axis_ref); |
---|
| 482 | #undef CLEAR_ATT |
---|
| 483 | |
---|
| 484 | } |
---|
[369] | 485 | */ |
---|
[219] | 486 | //---------------------------------------------------------------- |
---|
| 487 | |
---|
| 488 | void CField::solveGridReference(void) |
---|
| 489 | { |
---|
[347] | 490 | CDomain* domain; |
---|
| 491 | CAxis* axis; |
---|
[219] | 492 | |
---|
| 493 | if (!domain_ref.isEmpty()) |
---|
| 494 | { |
---|
[346] | 495 | if (CDomain::has(domain_ref.getValue())) |
---|
| 496 | domain = CDomain::get(domain_ref.getValue()) ; |
---|
[219] | 497 | else |
---|
| 498 | ERROR("CField::solveGridReference(void)", |
---|
[421] | 499 | << "Reference to the domain \'" |
---|
| 500 | << domain_ref.getValue() << "\' is wrong") ; |
---|
[219] | 501 | } |
---|
| 502 | |
---|
| 503 | if (!axis_ref.isEmpty()) |
---|
| 504 | { |
---|
[346] | 505 | if (CAxis::has(axis_ref.getValue())) |
---|
| 506 | axis = CAxis::get(axis_ref.getValue()) ; |
---|
[219] | 507 | else |
---|
| 508 | ERROR("CField::solveGridReference(void)", |
---|
[421] | 509 | << "Reference to the axis \'" |
---|
| 510 | << axis_ref.getValue() <<"\' is wrong") ; |
---|
[219] | 511 | } |
---|
| 512 | |
---|
| 513 | if (!grid_ref.isEmpty()) |
---|
| 514 | { |
---|
[346] | 515 | if (CGrid::has(grid_ref.getValue())) |
---|
| 516 | this->grid = CGrid::get(grid_ref.getValue()) ; |
---|
[219] | 517 | else |
---|
| 518 | ERROR("CField::solveGridReference(void)", |
---|
[421] | 519 | << "Reference to the grid \'" |
---|
| 520 | << grid_ref.getValue() << "\' is wrong"); |
---|
[219] | 521 | } |
---|
[418] | 522 | |
---|
| 523 | if (grid_ref.isEmpty() && domain_ref.isEmpty()) |
---|
[219] | 524 | { |
---|
| 525 | ERROR("CField::solveGridReference(void)", |
---|
[421] | 526 | << "The horizontal domain for this field is not defined"); |
---|
[418] | 527 | |
---|
| 528 | } |
---|
| 529 | |
---|
| 530 | CType<string> goodDomain ; |
---|
| 531 | CType<string> goodAxis ; |
---|
| 532 | if (!grid_ref.isEmpty()) |
---|
| 533 | { |
---|
| 534 | if (!grid->domain_ref.isEmpty()) goodDomain=grid->domain_ref ; |
---|
| 535 | if (!grid->axis_ref.isEmpty()) goodAxis=grid->axis_ref ; |
---|
| 536 | } |
---|
| 537 | if (!domain_ref.isEmpty()) goodDomain=domain_ref ; |
---|
| 538 | if (!axis_ref.isEmpty()) goodAxis=axis_ref ; |
---|
| 539 | |
---|
| 540 | |
---|
| 541 | if (goodDomain.isEmpty()) |
---|
| 542 | { |
---|
[421] | 543 | ERROR("CField::solveGridReference(void)", << "The horizontal domain for this field is not defined"); |
---|
[418] | 544 | } |
---|
| 545 | else |
---|
| 546 | { |
---|
| 547 | if (CDomain::has(goodDomain)) domain = CDomain::get(goodDomain) ; |
---|
[421] | 548 | else ERROR("CField::solveGridReference(void)",<< "Reference to the domain \'"<<goodDomain.get() << "\' is wrong") ; |
---|
[418] | 549 | } |
---|
| 550 | |
---|
| 551 | if (!goodAxis.isEmpty()) |
---|
| 552 | { |
---|
| 553 | if (CAxis::has(goodAxis)) axis = CAxis::get(goodAxis) ; |
---|
[421] | 554 | else ERROR("CField::solveGridReference(void)", << "Reference to the axis \'" |
---|
| 555 | << goodAxis.get() <<"\' is wrong") ; |
---|
[418] | 556 | } |
---|
| 557 | |
---|
| 558 | bool nothingToDo=false ; |
---|
| 559 | |
---|
| 560 | if (!grid_ref.isEmpty()) |
---|
| 561 | { |
---|
| 562 | if (!grid->domain_ref.isEmpty() && goodDomain.get() == grid->domain_ref.get()) |
---|
| 563 | if (goodAxis.isEmpty()) nothingToDo=true ; |
---|
| 564 | else if (!grid->axis_ref.isEmpty()) |
---|
| 565 | if (grid->axis_ref.get()==goodAxis.get()) nothingToDo=true ; |
---|
| 566 | } |
---|
| 567 | |
---|
| 568 | if (!nothingToDo) |
---|
| 569 | { |
---|
| 570 | if (!goodAxis.isEmpty()) |
---|
| 571 | { |
---|
| 572 | this->grid = CGrid::createGrid(domain, axis) ; |
---|
| 573 | this->grid_ref.setValue(this->grid->getId()); |
---|
| 574 | } |
---|
| 575 | else |
---|
| 576 | { |
---|
| 577 | this->grid = CGrid::createGrid(domain) ; |
---|
| 578 | this->grid_ref.setValue(this->grid->getId()); |
---|
| 579 | } |
---|
| 580 | } |
---|
| 581 | |
---|
| 582 | grid->solveReference() ; |
---|
[459] | 583 | |
---|
[219] | 584 | } |
---|
| 585 | |
---|
| 586 | |
---|
| 587 | ///------------------------------------------------------------------- |
---|
| 588 | |
---|
| 589 | template <> |
---|
| 590 | void CGroupTemplate<CField, CFieldGroup, CFieldAttributes>::solveRefInheritance(void) |
---|
| 591 | { |
---|
| 592 | if (this->group_ref.isEmpty()) return; |
---|
| 593 | StdString gref = this->group_ref.getValue(); |
---|
| 594 | |
---|
[346] | 595 | if (!CFieldGroup::has(gref)) |
---|
[219] | 596 | ERROR("CGroupTemplate<CField, CFieldGroup, CFieldAttributes>::solveRefInheritance(void)", |
---|
| 597 | << "[ gref = " << gref << "]" |
---|
| 598 | << " invalid group name !"); |
---|
| 599 | |
---|
[347] | 600 | CFieldGroup* group = CFieldGroup::get(gref); |
---|
| 601 | CFieldGroup* owner = CFieldGroup::get(boost::polymorphic_downcast<CFieldGroup*>(this)); |
---|
[219] | 602 | |
---|
[347] | 603 | std::vector<CField*> allChildren = group->getAllChildren(); |
---|
| 604 | std::vector<CField*>::iterator |
---|
[219] | 605 | it = allChildren.begin(), end = allChildren.end(); |
---|
| 606 | |
---|
| 607 | for (; it != end; it++) |
---|
| 608 | { |
---|
[347] | 609 | CField* child = *it; |
---|
[346] | 610 | if (child->hasId()) owner->createChild()->field_ref.setValue(child->getId()) ; |
---|
| 611 | |
---|
[219] | 612 | } |
---|
| 613 | } |
---|
[300] | 614 | |
---|
[369] | 615 | void CField::outputField(CArray<double,3>& fieldOut) |
---|
[300] | 616 | { |
---|
[369] | 617 | map<int, CArray<double,1>* >::iterator it; |
---|
[300] | 618 | for(it=data_srv.begin();it!=data_srv.end();it++) |
---|
[369] | 619 | grid->outputField(it->first,*it->second, fieldOut) ; |
---|
[300] | 620 | |
---|
| 621 | } |
---|
| 622 | |
---|
[369] | 623 | void CField::outputField(CArray<double,2>& fieldOut) |
---|
[300] | 624 | { |
---|
[369] | 625 | map<int, CArray<double,1>* >::iterator it; |
---|
[219] | 626 | |
---|
[300] | 627 | for(it=data_srv.begin();it!=data_srv.end();it++) |
---|
| 628 | { |
---|
[369] | 629 | grid->outputField(it->first,*it->second, fieldOut) ; |
---|
[300] | 630 | } |
---|
| 631 | } |
---|
[219] | 632 | ///------------------------------------------------------------------- |
---|
| 633 | |
---|
[459] | 634 | void CField::parse(xml::CXMLNode & node) |
---|
| 635 | { |
---|
| 636 | SuperClass::parse(node); |
---|
| 637 | node.getContent(this->content) ; |
---|
| 638 | } |
---|
| 639 | |
---|
| 640 | CArray<double,1>* CField::getInstantData(void) |
---|
| 641 | { |
---|
| 642 | if (!hasInstantData) |
---|
| 643 | { |
---|
| 644 | instantData.resize(grid->storeIndex_client.numElements()) ; |
---|
| 645 | hasInstantData=true ; |
---|
| 646 | } |
---|
| 647 | return &instantData ; |
---|
| 648 | } |
---|
| 649 | |
---|
| 650 | void CField::addReference(CField* field) |
---|
| 651 | { |
---|
| 652 | refObject.push_back(field) ; |
---|
| 653 | } |
---|
| 654 | |
---|
| 655 | void CField::addDependency(CField* field, int slotId) |
---|
| 656 | { |
---|
| 657 | fieldDependency.push_back(pair<CField*,int>(field,slotId)) ; |
---|
| 658 | } |
---|
| 659 | |
---|
| 660 | void CField::buildExpression(void) |
---|
| 661 | { |
---|
| 662 | if (content.size() > 0) |
---|
| 663 | { |
---|
| 664 | CSimpleNodeExpr* simpleExpr=parseExpr(content+'\0') ; |
---|
| 665 | expression=CFieldNode::newNode(simpleExpr) ; |
---|
| 666 | delete simpleExpr ; |
---|
| 667 | set<string> fieldIds ; |
---|
| 668 | expression->getFieldIds(fieldIds) ; |
---|
| 669 | for (set<string>::iterator it=fieldIds.begin() ; it!=fieldIds.end();++it) if (*it!="this") CField::get(*it)->processEnabledField() ; |
---|
| 670 | |
---|
| 671 | expression->reduce(this) ; |
---|
| 672 | |
---|
| 673 | slots.resize(fieldIds.size()) ; |
---|
| 674 | resetSlots() ; |
---|
| 675 | int slotId=0 ; |
---|
| 676 | set<CField*> fields ; |
---|
| 677 | expression->getFields(fields) ; |
---|
| 678 | for (set<CField*>::iterator it=fields.begin() ; it!=fields.end();++it,++slotId) (*it)->addDependency(this,slotId) ; |
---|
| 679 | hasExpression=true; |
---|
| 680 | } |
---|
| 681 | } |
---|
| 682 | |
---|
| 683 | void CField::resetSlots(void) |
---|
| 684 | { |
---|
| 685 | for(vector<bool>::iterator it=slots.begin();it!=slots.end();++it) *it=false ; |
---|
| 686 | } |
---|
| 687 | |
---|
| 688 | bool CField::slotsFull(void) |
---|
| 689 | { |
---|
| 690 | bool ret=true ; |
---|
| 691 | for(vector<bool>::iterator it=slots.begin();it!=slots.end();++it) ret &= *it; |
---|
| 692 | return ret ; |
---|
| 693 | } |
---|
| 694 | |
---|
| 695 | |
---|
| 696 | void CField::setSlot(int slotId) |
---|
| 697 | { |
---|
| 698 | CContext* context = CContext::getCurrent() ; |
---|
| 699 | const CDate & currDate = context->getCalendar()->getCurrentDate(); |
---|
| 700 | if (slotUpdateDate==NULL || currDate!=*slotUpdateDate) |
---|
| 701 | { |
---|
| 702 | resetSlots() ; |
---|
| 703 | if (slotUpdateDate==NULL) slotUpdateDate=new CDate(currDate) ; |
---|
| 704 | else *slotUpdateDate=currDate ; |
---|
| 705 | } |
---|
| 706 | slots[slotId]=true ; |
---|
| 707 | if (slotsFull()) |
---|
| 708 | { |
---|
| 709 | CArray<double,1> expr(expression->compute()) ; |
---|
| 710 | |
---|
| 711 | if (hasInstantData) |
---|
| 712 | { |
---|
| 713 | instantData=expr ; |
---|
| 714 | for(list< pair<CField *,int> >::iterator it=fieldDependency.begin(); it!=fieldDependency.end(); ++it) |
---|
| 715 | if (it->first!=this) it->first->setSlot(it->second) ; |
---|
| 716 | } |
---|
| 717 | |
---|
| 718 | if (hasOutputFile) updateDataFromExpression(expr) ; |
---|
| 719 | |
---|
| 720 | } |
---|
| 721 | } |
---|
| 722 | |
---|
[335] | 723 | } // namespace xios |
---|