FDSMeshStorage.cpp 11.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
/**
 * \file        FDSMeshStorage.h
 * \date        Jan 1, 2014
 * \version     v0.7
 * \copyright   <2009-2015> Forschungszentrum Jülich GmbH. All rights reserved.
 *
 * \section License
 * This file is part of JuPedSim.
 *
 * JuPedSim is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * JuPedSim is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with JuPedSim. If not, see <http://www.gnu.org/licenses/>.
 *
 * \section Description
 * Container to store all FDSMeshs. Sorted first by coordinates of the corresponding door,
 * secondly by simulation's global time
 *
 *
 **/
#include "FDSMeshStorage.h"
//#include <unistd.h>
//#include <glob.h>
32 33 34 35
// #include <filesystem>
#include <boost/filesystem.hpp>
namespace fs = boost::filesystem;
//namespace fs = std::experimental::filesystem;
36 37 38 39 40 41 42 43 44 45 46

FDSMeshStorage::FDSMeshStorage()
{

}

FDSMeshStorage::FDSMeshStorage(const std::string &filepath, const double &finalTime, const double &updateIntervall, const std::string &study, const std::string &irritant) :
    _filepath(filepath), _finalTime(finalTime),
    _updateIntervall(updateIntervall), _study(study),
    _elevationlist(), _timelist(), _irritant(irritant)
{
Mohcine Chraibi's avatar
Mohcine Chraibi committed
47
    ///Check if _filepath exists
48
        fs::path p(_filepath);
49 50
                p = fs::canonical(p).make_preferred(); //remove ..
                _filepath = p.string(); // TODO: refactor this class. Use path instead of string
51
        std::cout << "\nFDSMeshStorage: <" << p << ">\n";
52
    if (fs::exists(p) )
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
    {
        std::cout << "\nCreating QuantityList..." << std::endl;
        CreateQuantityList();
        std::cout << "Success!" << std::endl;
        std::cout << "\nCreating ElevationList..." << std::endl;
        CreateElevationList();
        std::cout << "Success!" << std::endl;
        std::cout << "\nCreating DoorList..." << std::endl;
        CreateDoorList();
        std::cout << "Success!" << std::endl;
        std::cout << "\nCreating TimeList..." << std::endl;
        CreateTimeList();
        std::cout << "Success!" << std::endl;
        std::cout << "\nCreating FDSMeshes..." << std::endl;
        CreateFDSMeshes();
        std::cout << "Success!" << std::endl;
    }
Ben Hein's avatar
Ben Hein committed
70
    else {
71
        Log->Write("ERROR:\tCould not find directory <%s>\n", _filepath.c_str());
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
        exit(EXIT_FAILURE);
    }
}


FDSMeshStorage::~FDSMeshStorage()
{

}

bool FDSMeshStorage::CreateQuantityList()
{
    /// Create quantity list
    _quantitylist.clear();
    fs::directory_iterator end ;
    for( fs::directory_iterator iter(_filepath) ; iter != end ; ++iter ) {
      if ( fs::is_directory( *iter ) )
      {
90
                  std::string quant_dir = iter->path().string();
91
          quant_dir =  quant_dir.substr( quant_dir.find_last_of("/\\") + 1 );
Ben Hein's avatar
Ben Hein committed
92
          //std::cout << quant_dir << std::endl;
93 94 95 96 97 98 99 100
           _quantitylist.push_back(quant_dir);
      }
    }
    if (_quantitylist.size() == 0) {
        Log->Write("ERROR:\tCould not find suitable quantities in %s", _filepath.c_str());
        exit(EXIT_FAILURE);
        return false;
    }
101
        std::cout << "_quantitylist.size(): " << _quantitylist.size() << "\n";
102 103 104 105 106 107 108 109 110
    return true;
}


bool FDSMeshStorage::CreateElevationList()
{
    /// Create elevation list out of the available Z_* dirs for each quantity
    _elevationlist.clear();
    fs::directory_iterator end ;
111 112
        fs::path q(_filepath);
        q /= fs::path(_quantitylist[0]);
113
    for( fs::directory_iterator iter(q) ; iter != end ; ++iter ) {
114 115 116 117 118 119 120 121 122 123 124 125 126
      if ( fs::is_directory( *iter ) )
      {
          std::string elev_dir = iter->path().string();
          double elev =  std::stod(elev_dir.substr( elev_dir.rfind("_") + 1 ));
          //std::cout << elev << std::endl;
          _elevationlist.push_back(elev);
      }
    }
    if (_elevationlist.size() == 0) {
        Log->Write("ERROR:\tCould not find suitable grid elevations in %s", _filepath.c_str());
        exit(EXIT_FAILURE);
        return false;
    }
127
        std::cout << "_elevationlist.size(): " << _elevationlist.size() << "\n";
128 129 130 131 132 133 134 135 136
    return true;
}


void FDSMeshStorage::CreateDoorList()
{
    /// Create door list only neceassry if smoke sensor is active
    _doorlist.clear();
    fs::directory_iterator end ;
137 138
        fs::path q(_filepath);
        q /= fs::path(_quantitylist[0]);
139 140
    for( auto &elv:_elevationlist){
        std::string elvAsString = std::to_string(elv);
141
        for( fs::directory_iterator iter(q) ; iter != end ; ++iter ) {
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
           if ( !fs::is_directory( *iter ) )
                continue;

           // skip directories not starting with Z_
           if (iter->path().string().find("Z_") == std::string::npos)
                continue;
           // Skip if different elevation
           double this_elev =  std::stod(elvAsString.substr( elvAsString.rfind("_") + 1 ));
           if(this_elev != elv) continue;
           // iterate over "Z_/" directories
           for( fs::directory_iterator i(iter->path() ) ; i != end ; ++i ) {
                if ( ! fs::is_directory( *i ) ) continue;
                std::string tempString = i->path().string();
                tempString = tempString.substr(0, tempString.find_last_of("/\\"));
                unsigned long startChar = tempString.find_last_of("/\\") + 1;
                tempString = i->path().string();
                tempString = tempString.substr(startChar);
159
                                std::replace(tempString.begin(), tempString.end(), '\\', '/'); // fox for windows Z_1\Door_X_2_Y_6 -> Z_1/Door_X_2_Y_6
160
                _doorlist.push_back(tempString);
161 162
           }
        }
Mohcine Chraibi's avatar
Mohcine Chraibi committed
163
    }
164
        std::cout << "_doorlist.size(): " << _doorlist.size() << "\n";
Mohcine Chraibi's avatar
Mohcine Chraibi committed
165
}
166 167 168 169
void FDSMeshStorage::CreateTimeList()
{
    /// Create time list for mesh refreshment
    _timelist.clear();
170
    double i=0;
171 172 173 174 175 176 177 178
    while (i<=_finalTime)
    {
        _timelist.push_back(i);
        i+=_updateIntervall;
    }

    ///Check if specified final and update times are compliant with available data
    for(auto elem : _timelist) {
179
                fs::path npz_file(_filepath);
180
        if (_doorlist.size() > 0) {     // Smoke sensor active
181
                        npz_file = npz_file / _quantitylist[0] / _doorlist[0] / ("t_" + std::to_string(elem) + ".npz");
182 183
        }
        else if (_doorlist.size() == 0) {   // Smoke sensor not active
184
                        npz_file = npz_file / _quantitylist[0] / ("Z_" + std::to_string(_elevationlist[0])) / ("t_" + std::to_string(elem) + ".npz");
185 186
        }

187
        if (fs::exists(npz_file) == false)
188
        {
189 190
            Log->Write("ERROR:\tSpecified times are not compliant with JPSfire data " + npz_file.string());
             std::cout << "\n\nCreateTimeList(): File not found: " << npz_file.string() << std::endl;
191 192
            exit(EXIT_FAILURE);
        }
193
        //std::cout << "LEAVING \n" ;
194
    }
195
        std::cout << "_timelist.size(): " << _timelist.size() << "\n";
196 197 198 199
}

void FDSMeshStorage::CreateFDSMeshes()
{
200
        std::cout << "Enter CreateFDSMeshes\n";
201 202 203
    _fMContainer.clear();
    if (_doorlist.size() > 0) {     // Smoke sensor active
        for (auto &h:_quantitylist)     //list of quantities
204
        {
205
                for (auto &j:_doorlist)         //list of doors
206
                {
207 208 209
                    //std::cout << "door " << j << std::endl;
                    for (auto &k:_timelist)         //list of times
                    {
210
                        fs::path npz_file(_filepath);
211 212
                        npz_file = npz_file / h / j / ("t_" + std::to_string(k) + ".npz");
                        npz_file = fs::canonical(npz_file).make_preferred(); // correct sep and remove ..
213 214
                        FDSMesh mesh(npz_file.string());
                        _fMContainer.insert(std::make_pair(npz_file.string(), mesh));
215 216 217 218 219 220 221 222 223 224 225 226
                    }
                }
       }
   }
   else if (_doorlist.size() == 0) {     // Smoke sensor not active
        for (auto &h:_quantitylist)     //list of quantities
        {
            for (auto &i:_elevationlist)    //list of elevations
            {
                //std::cout << "i " << i << std::endl;
                for (auto &k:_timelist)         //list of times
                {
227 228 229 230
                     fs::path npz_file(_filepath);
                     npz_file = npz_file / h / ("Z_" + std::to_string(i)) / ("t_" + std::to_string(k) + ".npz");
                     npz_file = fs::canonical(npz_file).make_preferred(); // correct sep and remove ..
                     FDSMesh mesh(npz_file.string());
231
                    _fMContainer.insert(std::make_pair(npz_file.string(), mesh));
232 233 234 235
                }
            }
       }
   }
236 237
   std::cout << "_fdcontainer.size(): " << _fMContainer.size() << "\n";

238 239 240 241 242 243 244 245 246 247 248 249 250 251
}

const FDSMesh &FDSMeshStorage::GetFDSMesh(const double &simTime, const double &pedElev, const std::string &quantity) throw (int)
{
    //Smoke Sensor NOT active
    int simT=simTime/_updateIntervall;
    simT*=_updateIntervall;
    _PedEyeHeight = pedElev + 1.8;
    GetNearestHeight(_PedEyeHeight);

    if (simT>=_finalTime)
        simT=_finalTime;

    //std::cout << "\t" << quantity << std::endl;
252 253 254
        fs::path Ztime(quantity);
        Ztime = Ztime / ("Z_" + std::to_string(_NearestHeight)) / ("t_" + std::to_string(simT) + ".000000.npz");
        Ztime = _filepath / Ztime;
255
        Ztime = fs::canonical(Ztime).make_preferred();
256
    if (_fMContainer.count(Ztime.string()) == 0) {
257
        //std::cout << str << std::endl;
258
        std::cout << "\n time ERROR: requested grid not available: " << Ztime.string() << std::endl;
259 260
        throw -1;
    }
261
    return _fMContainer.at(Ztime.string());
262 263 264 265 266 267 268 269 270 271 272 273 274 275 276

//    TODO
//    if(_fMContainer.??(str) ) {
//        return _fMContainer.at(str);
//    }
//    else {
//        Log->Write("ERROR:\tCould find no appropriate FDS mesh: ", quantity.string(), pedElev, simT);
//        exit(EXIT_FAILURE);
    //    }
}

const FDSMesh &FDSMeshStorage::GetFDSMesh(const double &pedElev, const Point &doorCentre, const double &simTime) throw (int)
{
    //Smoke Sensor active

Ben Hein's avatar
Ben Hein committed
277
     std::string quantity = "EXTINCTION_COEFFICIENT";
Ben Hein's avatar
Ben Hein committed
278

279 280 281 282 283 284 285 286
    _PedEyeHeight = pedElev + 1.8;
    GetNearestHeight(_PedEyeHeight);

    int simT=simTime/_updateIntervall;
    simT*=_updateIntervall;

    if (simT>=_finalTime)
        simT=_finalTime;
287
    // @todo: what if the files have the format Z_%.2f ?
288 289 290 291 292 293
        fs::path door_xy(quantity);
        door_xy = door_xy / ("Z_" + std::to_string(_NearestHeight)) /
                ("Door_X_" + std::to_string(doorCentre._x) + "_Y_" + std::to_string(doorCentre._y)) /
                ("t_" + std::to_string(simT) + ".000000.npz");

        door_xy = _filepath / door_xy;
294
        door_xy = fs::canonical(door_xy).make_preferred();
295 296
    if (_fMContainer.count(door_xy.string()) == 0) {
        std::cout << "\n > ERROR: requested sfgrid not available: " << door_xy.string() << std::endl;
297 298 299
        throw -1;
    }

300 301 302
    // if (_fMContainer.count(str) == 1) {
    //      std::cout << "INFO: requested sfgrid: " << str << std::endl;
    // }
303
    return _fMContainer.at(door_xy.string());
304 305
}

Mohcine Chraibi's avatar
Mohcine Chraibi committed
306
double FDSMeshStorage::GetNearestHeight(double PedEyeHeight)
307 308
{
    ///find the nearest height in the JPSfire data related to the ped elevation
Mohcine Chraibi's avatar
Mohcine Chraibi committed
309 310
     double min_val = FLT_MAX;// std::numeric_limits<double>::max();
     int index = 0;
311

Mohcine Chraibi's avatar
Mohcine Chraibi committed
312 313
    for(unsigned int i=0;i < _elevationlist.size() ;++i) {
        double diff = std::abs(_elevationlist[i] - PedEyeHeight);
314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332
        if(diff < min_val) {
            min_val = diff;
            index = i;
        }
    }
    _NearestHeight = _elevationlist[index];
    //std::cout << "NEAREST: " << _NearestHeight << std::endl;
    return _NearestHeight;
}

std::string FDSMeshStorage::GetStudy() const
{
    return _study;
}

std::string FDSMeshStorage::IrritantOrNot() const
{
    return _irritant;
}