OpalData.cpp 19.7 KB
Newer Older
gsell's avatar
gsell committed
1
//
2
// Class OpalData
gsell's avatar
gsell committed
3 4
//   The global OPAL structure.
//   The OPAL object holds all global data required for a OPAL execution.
5 6 7
//   In particular it contains the main Directory, which allows retrieval
//   of command objects by their name.  For other data refer to the
//   implementation file.
gsell's avatar
gsell committed
8
//
9 10
// Copyright (c) 200x - 2021, Paul Scherrer Institut, Villigen PSI, Switzerland
// All rights reserved
gsell's avatar
gsell committed
11
//
12 13 14 15 16 17 18 19 20
// This file is part of OPAL.
//
// OPAL is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// You should have received a copy of the GNU General Public License
// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
gsell's avatar
gsell committed
21 22
//
#include "AbstractObjects/OpalData.h"
23

gsell's avatar
gsell committed
24 25
#include "AbstractObjects/Attribute.h"
#include "AbstractObjects/Directory.h"
26
#include "AbstractObjects/Expressions.h"
gsell's avatar
gsell committed
27 28 29 30
#include "AbstractObjects/Object.h"
#include "AbstractObjects/ObjectFunction.h"
#include "AbstractObjects/Table.h"
#include "AbstractObjects/ValueDefinition.h"
31 32 33 34 35 36 37
#include "Algorithms/PartBunchBase.h"
#include "Attributes/Attributes.h"
#include "OpalParser/OpalParser.h"
#include "Parser/FileStream.h"
#include "Parser/StringStream.h"
#include "Structure/DataSink.h"
#include "Structure/BoundaryGeometry.h"
gsell's avatar
gsell committed
38 39 40
#include "Utilities/OpalException.h"
#include "Utilities/Options.h"
#include "Utilities/RegularExpression.h"
41 42 43
#include "ValueDefinitions/RealVariable.h"
#include "ValueDefinitions/StringConstant.h"

gsell's avatar
gsell committed
44 45 46
#include <iostream>
#include <list>
#include <set>
47
#include <algorithm>
gsell's avatar
gsell committed
48 49


50
#define MAX_NUM_INSTANCES 10
51

gsell's avatar
gsell committed
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81

void OpalData::ClearReference::operator()(Object *object) const {
    object->clear();
}


// Struct OpalDataImpl.
// ------------------------------------------------------------------------
struct OpalDataImpl {
    OpalDataImpl();
    ~OpalDataImpl();

    // The main object directory.
    Directory mainDirectory;

    // The value of the global momentum.
    ValueDefinition *referenceMomentum;

    // The flag telling that something has changed.
    bool modified;

    // Directory of tables, for recalculation when something changes.
    std::list<Table *> tableDirectory;
    typedef std::list<Table *>::iterator tableIterator;

    // The set of expressions to be invalidated when something changes.
    std::set <AttributeBase *> exprDirectory;
    typedef std::set<AttributeBase *>::iterator exprIterator;

    // The page title from the latest TITLE command.
82 83 84
    std::string itsTitle_m;

    bool hasPriorRun_m;
gsell's avatar
gsell committed
85 86

    // true if we restart a simulation
87
    bool isRestart_m;
gsell's avatar
gsell committed
88 89

    // Where to resume in a restart run
90
    int restartStep_m;
gsell's avatar
gsell committed
91 92

    // Where to resume in a restart run
93
    std::string restartFn_m;
gsell's avatar
gsell committed
94 95 96 97 98 99 100

    // true if the name of a restartFile is specified
    bool hasRestartFile_m;

    // dump frequency as found in restart file
    int restart_dump_freq_m;

101 102 103 104 105
    // Input file name
    std::string inputFn_m;

    std::set<std::string> outFiles_m;

106 107 108
    /// Mode for writing files
    OpalData::OPENMODE openMode_m = OpalData::OPENMODE::WRITE;

gsell's avatar
gsell committed
109 110 111 112 113
    // last step of a run
    int last_step_m;

    bool hasBunchAllocated_m;
    // The particle bunch to be tracked.
114
    PartBunchBase<double, 3> *bunch_m;
gsell's avatar
gsell committed
115

116 117
    bool hasDataSinkAllocated_m;

gsell's avatar
gsell committed
118 119 120 121 122 123 124
    DataSink *dataSink_m;

    // In units of seconds. This is half of tEmission
    double gPhaseShift_m;

    BoundaryGeometry *bg_m;

125
    std::vector<MaxPhasesT> maxPhases_m;
126
    energyEvolution_t energyEvolution_m;
127

128 129 130 131 132 133 134 135
    // The cartesian mesh
    Mesh_t *mesh_m;

    // The field layout f
    FieldLayout_t *FL_m;

    // The particle layout
    Layout_t *PL_m;
136 137

    // the accumulated (over all TRACKs) number of steps
138
    unsigned long long maxTrackSteps_m;
139 140 141

    bool isInOPALCyclMode_m;
    bool isInOPALTMode_m;
142
    bool isOptimizerFlag_m;
143
    bool isInPrepState_m;
144

adelmann's avatar
adelmann committed
145 146
    std::map<std::string, unsigned int> problemSize_m;

147
    std::vector<std::string> arguments_m;
gsell's avatar
gsell committed
148 149 150 151
};


OpalDataImpl::OpalDataImpl():
152
    mainDirectory(), referenceMomentum(0), modified(false), itsTitle_m(),
Christof Metzger-Kraus's avatar
Christof Metzger-Kraus committed
153 154
    hasPriorRun_m(false),
    isRestart_m(false),
snuverink_j's avatar
snuverink_j committed
155
    restartStep_m(0),
Christof Metzger-Kraus's avatar
Christof Metzger-Kraus committed
156
    hasRestartFile_m(false),
157
    restart_dump_freq_m(1), last_step_m(0),
Christof Metzger-Kraus's avatar
Christof Metzger-Kraus committed
158 159 160 161
    hasBunchAllocated_m(false),
    hasDataSinkAllocated_m(false),
    gPhaseShift_m(0.0),
    maxTrackSteps_m(0),
162 163
    isInOPALCyclMode_m(false),
    isInOPALTMode_m(false),
kraus's avatar
kraus committed
164
    isOptimizerFlag_m(false),
adelmann's avatar
adelmann committed
165
    isInPrepState_m(false)
166
{
167 168 169 170 171 172
    bunch_m    = nullptr;
    dataSink_m = nullptr;
    bg_m       = nullptr;
    mesh_m     = nullptr;
    FL_m       = nullptr;
    PL_m       = nullptr;
gsell's avatar
gsell committed
173 174 175 176 177
}

OpalDataImpl::~OpalDataImpl() {
    // Make sure the main directory is cleared before the directories
    // for tables and expressions are deleted.
178
    delete mesh_m;// somehow this needs to be deleted first
snuverink_j's avatar
snuverink_j committed
179
    delete FL_m;
180
    //delete PL_m; //this gets deleted by FL_m
181

182
    delete bunch_m;
ext-rogers_c's avatar
ext-rogers_c committed
183
    delete bg_m;
184 185
    delete dataSink_m;

gsell's avatar
gsell committed
186 187 188 189 190
    mainDirectory.erase();
    tableDirectory.clear();
    exprDirectory.clear();
}

191
bool OpalData::isInstantiated = false;
192
OpalData *OpalData::instance = nullptr;
193
std::stack<OpalData*> OpalData::stashedInstances;
gsell's avatar
gsell committed
194 195

OpalData *OpalData::getInstance() {
196
    if (!isInstantiated) {
gsell's avatar
gsell committed
197
        instance = new OpalData();
198
        isInstantiated = true;
gsell's avatar
gsell committed
199 200 201 202 203 204 205 206
        return instance;
    } else {
        return instance;
    }
}

void OpalData::deleteInstance() {
    delete instance;
207
    instance = nullptr;
208 209 210 211 212 213 214 215 216 217
    isInstantiated = false;
}

void OpalData::stashInstance() {
    if (!isInstantiated) return;
    if (stashedInstances.size() + 1 > MAX_NUM_INSTANCES) {
        throw OpalException("OpalData::stashInstance()",
                            "too many OpalData instances stashed");
    }
    stashedInstances.push(instance);
218
    instance = nullptr;
219 220 221 222 223 224 225 226 227 228 229 230 231 232
    isInstantiated = false;
}

OpalData *OpalData::popInstance() {
    if (stashedInstances.size() == 0) {
        throw OpalException("OpalData::popInstance()",
                            "no OpalData instances stashed");
    }
    if (isInstantiated) deleteInstance();
    instance = stashedInstances.top();
    isInstantiated = true;
    stashedInstances.pop();

    return instance;
gsell's avatar
gsell committed
233 234
}

235
unsigned long long OpalData::getMaxTrackSteps() {
236
    return p->maxTrackSteps_m;
237 238 239
}

void OpalData::setMaxTrackSteps(unsigned long long s) {
240
    p->maxTrackSteps_m = s;
241 242
}

243
void OpalData::incMaxTrackSteps(unsigned long long s) {
244
    p->maxTrackSteps_m += s;
245 246
}

gsell's avatar
gsell committed
247 248 249 250 251 252 253 254 255 256 257
OpalData::OpalData() {
    p = new OpalDataImpl();
}

OpalData::~OpalData() {
    delete p;
}

void OpalData::reset() {
    delete p;
    p = new OpalDataImpl();
258 259
    p->hasPriorRun_m = false;
    p->isRestart_m = false;
gsell's avatar
gsell committed
260 261 262 263 264
    p->hasRestartFile_m = false;
    p->hasBunchAllocated_m = false;
    p->hasDataSinkAllocated_m = false;
    p->gPhaseShift_m = 0.0;
    p->maxPhases_m.clear();
265 266
    p->isInOPALCyclMode_m = false;
    p->isInOPALTMode_m = false;
267
    p->isInPrepState_m = false;
268
    p->isOptimizerFlag_m = false;
269 270 271
}

bool OpalData::isInOPALCyclMode() {
272
    return p->isInOPALCyclMode_m;
273 274 275
}

bool OpalData::isInOPALTMode() {
276
    return  p->isInOPALTMode_m;
277
}
278

279 280 281 282
bool OpalData::isOptimizerRun() {
    return p->isOptimizerFlag_m;
}

283
void OpalData::setInOPALCyclMode() {
284
    p->isInOPALCyclMode_m = true;
gsell's avatar
gsell committed
285 286
}

287
void OpalData::setInOPALTMode() {
288
    p->isInOPALTMode_m = true;
289
}
290

291 292 293 294
void OpalData::setOptimizerFlag() {
    p->isOptimizerFlag_m = true;
}

295 296 297 298 299 300 301 302 303 304 305 306 307 308
bool OpalData::isInPrepState() {
    return p->isInPrepState_m;
}

void OpalData::setInPrepState(bool state) {
    p->isInPrepState_m = state;
}

bool OpalData::hasPriorTrack() {
    return p->hasPriorRun_m;
}

void OpalData::setPriorTrack(const bool &value) {
    p->hasPriorRun_m = value;
309
}
310

gsell's avatar
gsell committed
311
bool OpalData::inRestartRun() {
312
    return p->isRestart_m;
gsell's avatar
gsell committed
313 314 315
}

void OpalData::setRestartRun(const bool &value) {
316
    p->isRestart_m = value;
gsell's avatar
gsell committed
317 318 319
}

void OpalData::setRestartStep(int s) {
320
    p->restartStep_m = s;
gsell's avatar
gsell committed
321 322 323
}

int OpalData::getRestartStep() {
324
    return p->restartStep_m;
gsell's avatar
gsell committed
325 326
}

327
std::string OpalData::getRestartFileName() {
328
    return p->restartFn_m;
gsell's avatar
gsell committed
329 330
}

331
void OpalData::setRestartFileName(std::string s) {
332
    p->restartFn_m = s;
gsell's avatar
gsell committed
333 334 335 336 337 338 339 340 341 342 343 344 345 346 347
    p->hasRestartFile_m = true;
}

bool OpalData::hasRestartFile() {
    return p->hasRestartFile_m;
}

void OpalData::setRestartDumpFreq(const int &N) {
    p->restart_dump_freq_m = N;
}

int OpalData::getRestartDumpFreq() const {
    return p->restart_dump_freq_m;
}

348 349 350 351 352 353 354 355
void OpalData::setOpenMode(OPENMODE openMode) {
    p->openMode_m = openMode;
}

OpalData::OPENMODE OpalData::getOpenMode() const {
    return p->openMode_m;
}

gsell's avatar
gsell committed
356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371
void OpalData::setLastStep(const int &step) {
    p->last_step_m = step;
}

int OpalData::getLastStep() const {
    return p->last_step_m;
}

bool OpalData::hasBunchAllocated() {
    return p->hasBunchAllocated_m;
}

void OpalData::bunchIsAllocated() {
    p->hasBunchAllocated_m = true;
}

372
void OpalData::setPartBunch(PartBunchBase<double, 3> *b) {
gsell's avatar
gsell committed
373 374 375
    p->bunch_m = b;
}

376
PartBunchBase<double, 3> *OpalData::getPartBunch() {
gsell's avatar
gsell committed
377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392
    return p->bunch_m;
}

bool OpalData::hasDataSinkAllocated() {
    return p->hasDataSinkAllocated_m;
}

void OpalData::setDataSink(DataSink *s) {
    p->dataSink_m = s;
    p->hasDataSinkAllocated_m = true;
}

DataSink *OpalData::getDataSink() {
    return p->dataSink_m;
}

393
void OpalData::setMaxPhase(std::string elName, double phi) {
gsell's avatar
gsell committed
394 395 396
    p->maxPhases_m.push_back(MaxPhasesT(elName, phi));
}

397
std::vector<MaxPhasesT>::iterator OpalData::getFirstMaxPhases() {
gsell's avatar
gsell committed
398 399 400
    return p->maxPhases_m.begin();
}

401
std::vector<MaxPhasesT>::iterator OpalData::getLastMaxPhases() {
gsell's avatar
gsell committed
402 403 404 405 406 407 408
    return p->maxPhases_m.end();
}

int OpalData::getNumberOfMaxPhases() {
    return p->maxPhases_m.size();
}

409 410 411 412 413 414 415 416 417 418 419 420
void OpalData::addEnergyData(double spos, double ekin) {
    p->energyEvolution_m.insert(std::make_pair(spos, ekin));
}

energyEvolution_t::iterator OpalData::getFirstEnergyData() {
    return p->energyEvolution_m.begin();
}

energyEvolution_t::iterator OpalData::getLastEnergyData() {
    return p->energyEvolution_m.end();
}

gsell's avatar
gsell committed
421

422
// Mesh_t* OpalData::getMesh() {
kraus's avatar
kraus committed
423
//  return p->mesh_m;
424
// }
425

426
// FieldLayout_t* OpalData::getFieldLayout() {
kraus's avatar
kraus committed
427
//  return p->FL_m;
428
// }
gsell's avatar
gsell committed
429

430
// Layout_t* OpalData::getLayout() {
kraus's avatar
kraus committed
431
//  return p->PL_m;
432
// }
gsell's avatar
gsell committed
433

434
// void OpalData::setMesh(Mesh_t *mesh) {
kraus's avatar
kraus committed
435
//  p->mesh_m = mesh;
436
// }
437

438
// void OpalData::setFieldLayout(FieldLayout_t *fieldlayout) {
kraus's avatar
kraus committed
439
//  p->FL_m = fieldlayout;
440
// }
441

442
// void OpalData::setLayout(Layout_t *layout) {
kraus's avatar
kraus committed
443
//  p->PL_m = layout;
444
// }
gsell's avatar
gsell committed
445 446 447 448 449 450 451 452 453 454 455

void OpalData::setGlobalPhaseShift(double shift) {
    /// units: (sec)
    p->gPhaseShift_m = shift;
}

double OpalData::getGlobalPhaseShift() {
    /// units: (sec)
    return p->gPhaseShift_m;
}

456
void OpalData::setGlobalGeometry(BoundaryGeometry *bg) {
gsell's avatar
gsell committed
457 458 459 460 461 462 463
    p->bg_m = bg;
}

BoundaryGeometry *OpalData::getGlobalGeometry() {
    return p->bg_m;
}

464
bool OpalData::hasGlobalGeometry() {
465
    return p->bg_m != nullptr;
466 467
}

gsell's avatar
gsell committed
468
void OpalData::apply(const ObjectFunction &fun) {
469
    for (ObjectDir::iterator i = p->mainDirectory.begin();
gsell's avatar
gsell committed
470 471 472 473 474 475 476
        i != p->mainDirectory.end(); ++i) {
        fun(&*i->second);
    }
}

void OpalData::create(Object *newObject) {
    // Test for existing node with same name.
477
    const std::string name = newObject->getOpalName();
gsell's avatar
gsell committed
478 479
    Object *oldObject = p->mainDirectory.find(name);

480
    if (oldObject != nullptr) {
gsell's avatar
gsell committed
481 482 483 484 485 486 487 488 489
        throw OpalException("OpalData::create()",
                            "You cannot replace the object \"" + name + "\".");
    } else {
        p->mainDirectory.insert(name, newObject);
    }
}

void OpalData::define(Object *newObject) {
    // Test for existing node with same name.
490
    const std::string name = newObject->getOpalName();
gsell's avatar
gsell committed
491 492
    Object *oldObject = p->mainDirectory.find(name);

493
    if (oldObject != nullptr  &&  oldObject != newObject) {
gsell's avatar
gsell committed
494
        // Attempt to replace an object.
495
        if (oldObject->isBuiltin()  ||  ! oldObject->canReplaceBy(newObject)) {
gsell's avatar
gsell committed
496 497 498
            throw OpalException("OpalData::define()",
                                "You cannot replace the object \"" + name + "\".");
        } else {
499
            if (Options::info) {
500
                INFOMSG("Replacing the object \"" << name << "\"." << endl);
gsell's avatar
gsell committed
501 502 503 504 505 506 507 508
            }

            // Erase all tables which depend on the new object.
            OpalDataImpl::tableIterator i = p->tableDirectory.begin();
            while(i != p->tableDirectory.end()) {
                // We must increment i before calling erase(name),
                // since erase(name) removes "this" from "tables".
                Table *table = *i++;
509
                const std::string &tableName = table->getOpalName();
gsell's avatar
gsell committed
510

511 512
                if (table->isDependent(name)) {
                    if (Options::info) {
513 514
                    	std::cerr << std::endl << "Erasing dependent table \""
                                  << tableName << "\"." << std::endl;
gsell's avatar
gsell committed
515 516 517 518 519 520 521 522 523 524
                    }

                    // Remove table from directory.
                    // This erases the table from the main directory,
                    // and its destructor unregisters it from the table directory.
                    erase(tableName);
                }
            }

            // Replace all references to this object.
525
            for (ObjectDir::iterator i = p->mainDirectory.begin();
gsell's avatar
gsell committed
526 527 528 529 530 531 532 533 534 535 536 537 538 539 540
                i != p->mainDirectory.end(); ++i) {
                (*i).second->replace(oldObject, newObject);
            }

            // Remove old object.
            erase(name);
        }
    }

    // Force re-evaluation of expressions.
    p->modified = true;
    newObject->setDirty(true);
    p->mainDirectory.insert(name, newObject);

    // If this is a new definition of "P0", insert its definition.
541 542
    if (name == "P0") {
        if (ValueDefinition *p0 = dynamic_cast<ValueDefinition *>(newObject)) {
gsell's avatar
gsell committed
543 544 545 546 547
            setP0(p0);
        }
    }
}

548
void OpalData::erase(const std::string &name) {
gsell's avatar
gsell committed
549 550
    Object *oldObject = p->mainDirectory.find(name);

551
    if (oldObject != nullptr) {
gsell's avatar
gsell committed
552
        // Relink all children of "this" to "this->getParent()".
553
        for (ObjectDir::iterator i = p->mainDirectory.begin();
gsell's avatar
gsell committed
554 555
            i != p->mainDirectory.end(); ++i) {
            Object *child = &*i->second;
556
            if (child->getParent() == oldObject) {
gsell's avatar
gsell committed
557 558 559 560 561 562 563 564
                child->setParent(oldObject->getParent());
            }
        }
        // Remove the object.
        p->mainDirectory.erase(name);
    }
}

565
Object *OpalData::find(const std::string &name) {
gsell's avatar
gsell committed
566 567 568 569 570 571 572 573 574 575
    return p->mainDirectory.find(name);
}

double OpalData::getP0() const {
    static const double energy_scale = 1.0e+9;
    return p->referenceMomentum->getReal() * energy_scale;
}

void OpalData::makeDirty(Object *obj) {
    p->modified = true;
576
    if (obj) obj->setDirty(true);
gsell's avatar
gsell committed
577 578
}

579
void OpalData::printNames(std::ostream &os, const std::string &pattern) {
gsell's avatar
gsell committed
580 581
    int column = 0;
    RegularExpression regex(pattern);
582 583
    os << std::endl << "Object names matching the pattern \""
       << pattern << "\":" << std::endl;
gsell's avatar
gsell committed
584

585
    for (ObjectDir::const_iterator index = p->mainDirectory.begin();
snuverink_j's avatar
snuverink_j committed
586
        index != p->mainDirectory.end(); ++index) {
587
        const std::string name = (*index).first;
gsell's avatar
gsell committed
588

589
        if (! name.empty()  &&  regex.match(name)) {
gsell's avatar
gsell committed
590 591
            os << name;

592
            if (column < 80) {
gsell's avatar
gsell committed
593 594 595 596 597 598 599
                column += name.length();

                do {
                    os << ' ';
                    column++;
                } while((column % 20) != 0);
            } else {
600
                os << std::endl;
gsell's avatar
gsell committed
601 602 603 604 605
                column = 0;
            }
        }
    }

606
    if (column) os << std::endl;
607
    os << std::endl;
gsell's avatar
gsell committed
608 609 610 611 612 613 614
}

void OpalData::registerTable(Table *table) {
    p->tableDirectory.push_back(table);
}

void OpalData::unregisterTable(Table *table) {
615
    for (OpalDataImpl::tableIterator i = p->tableDirectory.begin();
gsell's avatar
gsell committed
616 617
        i != p->tableDirectory.end();) {
        OpalDataImpl::tableIterator j = i++;
618
        if (*j == table) p->tableDirectory.erase(j);
gsell's avatar
gsell committed
619 620 621 622 623 624 625 626 627 628 629 630 631 632 633
    }
}

void OpalData::registerExpression(AttributeBase *expr) {
    p->exprDirectory.insert(expr);
}

void OpalData::unregisterExpression(AttributeBase *expr) {
    p->exprDirectory.erase(expr);
}

void OpalData::setP0(ValueDefinition *p0) {
    p->referenceMomentum = p0;
}

634
void OpalData::storeTitle(const std::string &title) {
635
    p->itsTitle_m = title;
gsell's avatar
gsell committed
636 637
}

638
void OpalData::storeInputFn(const std::string &fn) {
639
    p->inputFn_m = fn;
gsell's avatar
gsell committed
640 641 642
}

void OpalData::printTitle(std::ostream &os) {
643
    os << p->itsTitle_m;
gsell's avatar
gsell committed
644 645
}

646
std::string OpalData::getTitle() {
647
    return p->itsTitle_m;
gsell's avatar
gsell committed
648 649
}

frey_m's avatar
frey_m committed
650
std::string OpalData::getAuxiliaryOutputDirectory() const {
651 652 653
    return "data";
}

654
std::string OpalData::getInputFn() {
655
    return p->inputFn_m;
gsell's avatar
gsell committed
656 657
}

658
std::string OpalData::getInputBasename() {
659
    std::string & fn = p->inputFn_m;
660 661 662
    int const pdot = fn.rfind(".");
    return fn.substr(0, pdot);
}
gsell's avatar
gsell committed
663

664 665 666 667 668 669 670 671 672 673
void OpalData::checkAndAddOutputFileName(const std::string &outfn) {
    if (p->outFiles_m.count(outfn) == 0) {
        p->outFiles_m.insert(outfn);
    } else {
        throw OpalException(
                "OpalData::checkAndAddOutputFileName",
                "Duplicate file name for output, '" + outfn + "', detected");
    }
}

gsell's avatar
gsell committed
674 675
void OpalData::update() {
    Inform msg("OpalData ");
676
    if (p->modified) {
gsell's avatar
gsell committed
677
        // Force re-evaluation of expressions.
678
        for (OpalDataImpl::exprIterator i = p->exprDirectory.begin();
gsell's avatar
gsell committed
679 680 681 682 683
            i != p->exprDirectory.end(); ++i) {
            (*i)->invalidate();
        }

        // Force refilling of dynamic tables.
684
        for (OpalDataImpl::tableIterator i = p->tableDirectory.begin();
gsell's avatar
gsell committed
685 686 687 688 689
            i != p->tableDirectory.end(); ++i) {
            (*i)->invalidate();
        }

        // Update all definitions.
690
        for (ObjectDir::iterator i = p->mainDirectory.begin();
gsell's avatar
gsell committed
691 692 693 694 695 696 697 698 699
            i != p->mainDirectory.end(); ++i) {
            (*i).second->update();
        }

        // Definitions are up-to-date.
        p->modified = false;
    }
}

700 701 702 703
std::map<std::string, std::string> OpalData::getVariableData() {
    std::map<std::string, std::string> udata;
    std::vector<std::string> uvars = this->getVariableNames();
    for (auto& uvar : uvars) {
704
        Object *tmpObject = OpalData::getInstance()->find(uvar);
frey_m's avatar
frey_m committed
705 706 707 708 709 710
        if (dynamic_cast<RealVariable*>(tmpObject)) {
            RealVariable* variable = dynamic_cast<RealVariable*>(OpalData::getInstance()->find(uvar));
            udata[uvar] = std::to_string(variable->getReal());
        } else if (dynamic_cast<StringConstant*>(tmpObject)) {
            StringConstant* variable = dynamic_cast<StringConstant*>(OpalData::getInstance()->find(uvar));
            udata[uvar] = variable->getString();
711 712 713 714 715
        } else {
            throw OpalException("OpalData::getVariableData()",
                                "Type of '" + uvar + "' not supported. "
                                "Only support for REAL and STRING.");
        }
716 717 718 719
    }
    return udata;
}

720 721 722
std::vector<std::string> OpalData::getVariableNames() {
    std::vector<std::string> result;

723
    for (ObjectDir::const_iterator index = p->mainDirectory.begin();
724 725 726 727
        index != p->mainDirectory.end(); ++index) {
        std::string tmpName = (*index).first;
        if (!tmpName.empty()) {
            Object *tmpObject = OpalData::getInstance()->find(tmpName);
frey_m's avatar
frey_m committed
728 729 730 731 732 733
            if (tmpObject) {
                if (!tmpObject || tmpObject->isBuiltin())
                    continue;
                if (tmpObject->getCategory() == "VARIABLE") {
                    result.push_back(tmpName);
                }
734 735 736 737 738 739
            }
        }
    }
    return result;
}

adelmann's avatar
adelmann committed
740 741 742 743 744 745 746 747 748 749 750 751
void OpalData::addProblemCharacteristicValue(const std::string &name, unsigned int value) {
    if (p->problemSize_m.find(name) != p->problemSize_m.end()) {
        p->problemSize_m.insert(std::make_pair(name, value));
    } else {
        p->problemSize_m[name] = value;
    }
}

const std::map<std::string, unsigned int> &OpalData::getProblemCharacteristicValues() const {
    return p->problemSize_m;
}

752 753 754 755 756 757 758 759 760
void OpalData::storeArguments(int argc, char *argv[]) {
    p->arguments_m.clear();
    for (int i = 0; i < argc; ++ i) {
        p->arguments_m.push_back(argv[i]);
    }
}

std::vector<std::string> OpalData::getArguments() {
    return p->arguments_m;
761
}