LCOV - code coverage report
Current view: top level - src/modules - Module.hpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 10 15 66.7 %
Date: 2023-04-08 04:19:02 Functions: 5 6 83.3 %

          Line data    Source code
       1             : /*
       2             :  * Module.hpp
       3             :  *
       4             :  *  Created on: 29 Nov 2019
       5             :  *   Author(s): Jorn Reniers, Volkan Kumtepeli
       6             :  */
       7             : 
       8             : #pragma once
       9             : 
      10             : #include "../StorageUnit.hpp"
      11             : #include "../cooling/cooling.hpp"
      12             : #include "../types/State.hpp"
      13             : #include "../settings/settings.hpp"
      14             : #include "../utility/utility.hpp"
      15             : 
      16             : 
      17             : #include <vector>
      18             : #include <cstdlib>
      19             : #include <memory>
      20             : #include <iostream>
      21             : #include <span>
      22             : 
      23             : 
      24             : namespace slide {
      25             : struct ModuleThermalParam
      26             : {
      27             :   double k_cell2cell{ 5 };                             //!< conductive heat transfer coefficient for heat transfer betweenthe child SUs
      28             :   double A{ 0.0042 * 10 * settings::MODULE_NSUs_MAX }; //!< thermally active surface area of this module. The first number is the thermal active surface area of a cell
      29             :   double Qcontact{ 0 };                                //!< heat energy generated in the contact resistances since the last time the thermal model was solved
      30             :   double time{ 0 };                                    //!< time since the last update of the thermal model [s]
      31             : };
      32             : 
      33             : class Module : public StorageUnit
      34             : {
      35             : 
      36             : public:
      37             :   //!< connected child SUs
      38             :   using SU_t = Deep_ptr<StorageUnit>; // #TODO in future it should store directly storage unit itself.
      39             :   using SUs_t = std::vector<SU_t>;
      40             :   using SUs_span_t = std::span<SU_t>;
      41             :   using CoolSystem_t = Deep_ptr<CoolSystem>;
      42             : 
      43             : protected:
      44             :   SUs_t SUs;
      45             :   std::vector<double> Rcontact; //!< array with the contact resistance for cell i
      46             : 
      47             :   //!< thermal model
      48             :   CoolSystem_t cool{ nullptr }; //!< cooling system of this module //!< make<CoolSystem>(settings::MODULE_NSUs_MAX, 1);
      49             :   ModuleThermalParam therm;
      50             : 
      51             :   //!< voltage
      52             :   size_t Ncells;               //!< Number of cells this module contains.
      53             :   double Vmodule{ 0 };         //!< voltage of the module
      54             :   bool Vmodule_valid{ false }; //!< boolean indicating if stored the voltage of the module is valid
      55             :   bool par{ true };            //!< if true, some functions will be calculated parallel using multithreaded computing
      56             :                                //!< data storage
      57             : 
      58             :   State<0, settings::data::N_CumulativeModule> st_module;
      59             :   std::vector<double> data; //!< Time data
      60             : 
      61             : 
      62             :   size_t calculateNcells() override
      63             :   {
      64             :     /*  return the number of cells connected to this module
      65             :      *  e.g. if this module has 3 child-modules, each with 2 cells.
      66             :      *  then getNSUs = 3 but getNcells = 6
      67             :      */
      68             :     //!< #TODO this function needs to call parent to update their number of cells if they are module.
      69             :     return Ncells = transform_sum(SUs, free::get_Ncells<SU_t>);
      70             :   }
      71             : 
      72             :   double thermalModel_cell();
      73             :   double thermalModel_coupled(int Nneighbours, double Tneighbours[], double Kneighbours[], double Aneighb[], double tim);
      74             : 
      75             : public:
      76             :   Module() : StorageUnit("Module") {}
      77           2 :   Module(std::string_view ID_) : StorageUnit(ID_) {}
      78             :   Module(std::string_view ID_, double Ti, bool print, bool pari, int Ncells, int coolControl, int cooltype);
      79             :   Module(std::string_view ID_, double Ti, bool print, bool pari, int Ncells, CoolSystem_t &&coolControlPtr, int cooltype);
      80             : 
      81             :   //!< common implementation for all base-modules
      82    25486909 :   size_t getNSUs() { return SUs.size(); } //!< note that these child-SUs can be modules themselves (or they can be cells)
      83          18 :   SUs_t &getSUs() { return SUs; }
      84             : 
      85             :   const auto &operator[](size_t i) const { return SUs[i]; }
      86             :   auto &operator[](size_t i) { return SUs[i]; }
      87             : 
      88             :   virtual Status checkVoltage(double &v, bool print) noexcept override; //!< get the voltage and check if it is valid
      89             :   double getVhigh() override;                                           //!< return the voltage of the cell with the highest voltage
      90             :   double getVlow() override;                                            //!< return the voltage of the cell with the lowest voltage
      91             :   void getStates(getStates_t &s) override;                              //!< returns one long array with the states: getStates-array of each cell followed by the states of the module (Tmod)
      92             :                                                                         //      [s0 s1 s2 ... sn T], where s1 = cells[0].getStates()
      93             : 
      94             :   //    int Vstatus
      95             : 
      96             :   virtual bool validStates(bool print = true) override; //!< check if a state-array is valid for this module (uses setStates)
      97             :   virtual Status setStates(setStates_t s, bool checkV = true, bool print = true) override;
      98             :   //!< Set the states of this module to the given one
      99             :   //!< note: setStates is the master function to check if states and cells are valid
     100             :   //!< if checkV=true, then also the cell and module voltages are checked
     101             :   //!< the other functions just call setStates to check validity
     102             : 
     103             :   //!< thermal model
     104             :   double T() override { return cool->T(); } //!< get the temperature of this module
     105             : 
     106             :   double getThermalSurface() override { return therm.A; };
     107             :   double getCoolingLoad(); //!< return the energy required to run the entire coolingsystem of this module and all its children
     108             :   double thermalModel(int Nneighbours, double Tneighbours[], double Kneighbours[], double Aneighb[], double tim) override;
     109             : 
     110             :   virtual void setSUs(SUs_span_t c, bool checkCells = true, bool print = true);
     111             :   //!< Sets the cells of this module. Checks module-constraints
     112             :   //!< does not check if the states of cells are valid, nor the voltages of the cells and module
     113             :   //!< it only checks whether the cells are ok for this module (same current if series, same voltage if parallel)
     114             :   //!< note on virtual functions, see StorageUnit.hpp
     115             : 
     116     1408305 :   CoolSystem *getCoolSystem() { return cool.get(); }
     117             : 
     118          11 :   void setRcontact(std::span<double> Rc) //!< #TODO if ok.
     119             :   {
     120             :     /*
     121             :      * Set the contact resistance of each cell.
     122             :      * In parallel modules, this is the 'horizontal' resistance through which all currents of the cells 'behind it' goes.
     123             :      */
     124          11 :     assert(Rc.size() == getNSUs());
     125          11 :     Rcontact.resize(Rc.size());
     126          11 :     std::copy(Rc.begin(), Rc.end(), Rcontact.begin());
     127          11 :     Vmodule_valid = false; //!< we are changing the resistance, so the stored voltage is no longer valid
     128          11 :   }
     129             : 
     130             :   virtual Module *copy() override = 0;
     131             : 
     132             :   void storeData() override
     133             :   {
     134             :     for (const auto &SU : SUs) //!< Tell all connected cells to store their data
     135             :       SU->storeData();
     136             : 
     137             :     //!< Store data for the coolsystem
     138             :     cool->storeData(getNcells());
     139             : 
     140             :     if constexpr (settings::DATASTORE_MODULE >= settings::moduleDataStorageLevel::storeTimeData) //!< Store data of this module
     141             :       data.insert(data.end(), { st_module.Ah(), st_module.Wh(), st_module.time(), I(), V(), T() });
     142             :   }
     143             : 
     144             :   void writeData(const std::string &prefix) override
     145             :   {
     146             :     for (const auto &SU : SUs) //!< Tell all connected cells to write their data
     147             :       SU->writeData(prefix);
     148             : 
     149             : 
     150             :     if constexpr (settings::DATASTORE_MODULE >= settings::moduleDataStorageLevel::storeTimeData) //!< Write data for this module
     151             :     {
     152             :       std::string name = prefix + "_" + getFullID() + "_ModuleData.csv"; //!< name of the file, start with the full hierarchy-ID to identify this cell
     153             : 
     154             :       //!< append the new data to the existing file
     155             :       std::ofstream file(name, std::ios_base::app); // #TODO if first time open + header, if not append.
     156             : 
     157             :       if (!file.is_open()) {
     158             :         std::cerr << "ERROR in Module::writeData, could not open file " << name << '\n';
     159             :         throw 11;
     160             :       }
     161             : 
     162             :       free::write_data(file, data, 6);
     163             : 
     164             :       file.close();
     165             :     }
     166             : 
     167             : //!< Write data for the cooling system
     168             : #if 0 //!< (DATASTORE_COOL > 0)
     169             :                         cool->writeData(prefix + '_' + getFullID()); //!< append the ID to the prefix since the cooling system does not have the ID of this module
     170             : #endif
     171             :   }
     172             : 
     173           0 :   void setBlockDegAndTherm(bool block)
     174             :   {
     175           0 :     for (auto &SU : SUs)
     176           0 :       SU->setBlockDegAndTherm(block);
     177             : 
     178           0 :     blockDegAndTherm = block;
     179           0 :   }
     180             : 
     181             :   /*****************************************************************
     182             :    * Set the temperature of the coolant in this module.
     183             :    * Note that it does NOT immediately change the temperatures of the child-SUs.
     184             :    * That is done by the thermal model over time
     185             :    *****************************************************************/
     186             :   void setT(double Tnew) override { cool->setT(Tnew); } //!< set a module temperature
     187             : 
     188             :   /*****************************************************************
     189             :    * return the number of cells connected to this module
     190             :    * e.g. if this module has 3 child-modules, each with 2 cells.
     191             :    * then getNSUs = 3 but getNcells = 6
     192             :    *****************************************************************/
     193             :   size_t getNcells() override { return Ncells; }
     194             : 
     195             :   //!< Return the temperature of the hottest element of the module.
     196             :   //!< Note that this will be the T of a cell, since child-modules will pass on
     197             :   //!< this function to their cells
     198             :   double getThotSpot() override //!< get the maximum temperature of the cells or the module
     199             :   {
     200             :     double Thot = cool->T();
     201             :     for (const auto &SU : SUs)
     202             :       Thot = std::max(Thot, SU->getThotSpot());
     203             : 
     204             :     return Thot;
     205             :   }
     206             : };
     207             : } // namespace slide

Generated by: LCOV version 1.14