LCOV - code coverage report
Current view: top level - models/glct_secir - model.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 147 147 100.0 %
Date: 2025-01-17 12:16:22 Functions: 6 6 100.0 %

          Line data    Source code
       1             : /* 
       2             : * Copyright (C) 2020-2025 MEmilio
       3             : *
       4             : * Authors: Lena Ploetzke
       5             : *
       6             : * Contact: Martin J. Kuehn <Martin.Kuehn@DLR.de>
       7             : *
       8             : * Licensed under the Apache License, Version 2.0 (the "License");
       9             : * you may not use this file except in compliance with the License.
      10             : * You may obtain a copy of the License at
      11             : *
      12             : *     http://www.apache.org/licenses/LICENSE-2.0
      13             : *
      14             : * Unless required by applicable law or agreed to in writing, software
      15             : * distributed under the License is distributed on an "AS IS" BASIS,
      16             : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      17             : * See the License for the specific language governing permissions and
      18             : * limitations under the License.
      19             : */
      20             : 
      21             : #ifndef MIO_GLCT_SECIR_MODEL_H
      22             : #define MIO_GLCT_SECIR_MODEL_H
      23             : 
      24             : #include "glct_secir/parameters.h"
      25             : #include "glct_secir/infection_state.h"
      26             : #include "memilio/epidemiology/lct_infection_state.h"
      27             : #include "memilio/compartments/compartmentalmodel.h"
      28             : #include "memilio/epidemiology/populations.h"
      29             : #include "memilio/config.h"
      30             : #include "memilio/utils/logging.h"
      31             : #include "memilio/utils/time_series.h"
      32             : #include "memilio/math/eigen.h"
      33             : 
      34             : namespace mio
      35             : {
      36             : namespace glsecir
      37             : {
      38             : 
      39             : /**
      40             :  * @brief Class that defines an GLCT-SECIR model.
      41             :  *
      42             :  * @tparam NumExposed The number of subcompartments used for the Exposed compartment.
      43             :  * @tparam NumInfectedNoSymptoms The number of subcompartments used for the InfectedNoSymptoms compartment. 
      44             :  * @tparam NumInfectedSymptoms The number of subcompartments used for the InfectedSymptoms compartment.
      45             :  * @tparam NumInfectedSevere The number of subcompartments used for the InfectedSevere compartment.
      46             :  * @tparam NumInfectedCritical The number of subcompartments used for the InfectedCritical compartment.
      47             :  */
      48             : template <size_t NumExposed, size_t NumInfectedNoSymptoms, size_t NumInfectedSymptoms, size_t NumInfectedSevere,
      49             :           size_t NumInfectedCritical>
      50             : class Model
      51             :     : public CompartmentalModel<
      52             :           ScalarType,
      53             :           LctInfectionState<InfectionState, 1, NumExposed, NumInfectedNoSymptoms, NumInfectedSymptoms,
      54             :                             NumInfectedSevere, NumInfectedCritical, 1, 1>,
      55             :           mio::Populations<ScalarType,
      56             :                            LctInfectionState<InfectionState, 1, NumExposed, NumInfectedNoSymptoms, NumInfectedSymptoms,
      57             :                                              NumInfectedSevere, NumInfectedCritical, 1, 1>>,
      58             :           Parameters>
      59             : {
      60             : 
      61             : public:
      62             :     using LctState =
      63             :         LctInfectionState<InfectionState, 1, NumExposed, NumInfectedNoSymptoms, NumInfectedSymptoms, NumInfectedSevere,
      64             :                           NumInfectedCritical, 1, 1>; ///< This class specifies the number of subcompartments.
      65             :     using Base = CompartmentalModel<ScalarType, LctState, mio::Populations<ScalarType, LctState>, Parameters>;
      66             :     using typename Base::ParameterSet;
      67             :     using typename Base::Populations;
      68             : 
      69             :     /// @brief Default constructor.
      70           5 :     Model()
      71           5 :         : Base(Populations({Index<LctState>(LctState::Count)}, 0.), ParameterSet())
      72             :     {
      73           5 :     }
      74             : 
      75             :     /**
      76             :      * @brief Checks that the model satisfies all constraints (e.g. parameter or population constraints), and 
      77             :      *  logs an error if constraints are not satisfied.
      78             :      *
      79             :      * @return Returns true if one or more constraints are not satisfied, false otherwise.
      80             :      */
      81           7 :     bool check_constraints() const
      82             :     {
      83           7 :         auto params = this->parameters;
      84             : 
      85             :         // --- Check that the dimensions are consistent. ---
      86          14 :         if ((Eigen::Index)LctState::template get_num_subcompartments<InfectionState::Exposed>() !=
      87           7 :             params.template get<StartingProbabilitiesExposed>().rows()) {
      88           1 :             log_error("Constraint check: Dimension of the parameters does not match the number of subcompartments for "
      89             :                       "the Exposed "
      90             :                       "compartment.");
      91           1 :             return true;
      92             :         }
      93          12 :         if ((Eigen::Index)LctState::template get_num_subcompartments<InfectionState::InfectedNoSymptoms>() !=
      94           6 :             params.template get<StartingProbabilitiesInfectedNoSymptoms>().rows()) {
      95           1 :             log_error(
      96             :                 "Constraint check: Dimension of the parameters does not match the number of subcompartments for the "
      97             :                 "InfectedNoSymptoms compartment.");
      98           1 :             return true;
      99             :         }
     100          10 :         if ((Eigen::Index)LctState::template get_num_subcompartments<InfectionState::InfectedSymptoms>() !=
     101           5 :             params.template get<StartingProbabilitiesInfectedSymptoms>().rows()) {
     102           1 :             log_error(
     103             :                 "Constraint check: Dimension of the parameters does not match the number of subcompartments for the "
     104             :                 "InfectedSymptoms compartment.");
     105           1 :             return true;
     106             :         }
     107           8 :         if ((Eigen::Index)LctState::template get_num_subcompartments<InfectionState::InfectedSevere>() !=
     108           4 :             params.template get<StartingProbabilitiesInfectedSevere>().rows()) {
     109           1 :             log_error("Constraint check: Dimension of the parameters does not match the number of subcompartments for "
     110             :                       "the InfectedSevere "
     111             :                       "compartment.");
     112           1 :             return true;
     113             :         }
     114           6 :         if ((Eigen::Index)LctState::template get_num_subcompartments<InfectionState::InfectedCritical>() !=
     115           3 :             params.template get<StartingProbabilitiesInfectedCritical>().rows()) {
     116           1 :             log_error(
     117             :                 "Constraint check: Dimension of the parameters does not match the number of subcompartments for the "
     118             :                 "InfectedCritical compartment.");
     119           1 :             return true;
     120             :         }
     121             : 
     122           2 :         return (params.check_constraints() || this->populations.check_constraints());
     123           7 :     }
     124             : 
     125             :     /**
     126             :      * @brief Evaluates the right-hand-side f of the GLCT dydt = f(y, t).
     127             :      *
     128             :      * The GLCT-SECIR model is defined through ordinary differential equations of the form dydt = f(y, t). 
     129             :      * y is a vector containing number of individuals for each (sub-) compartment.
     130             :      * This function evaluates the right-hand-side f of the ODE and can be used in an ODE solver.
     131             :      *
     132             :      * @param[in] pop The current state of the population in the geographic unit we are considering.
     133             :      * @param[in] y The current state of the model (or a subpopulation) as a flat array.
     134             :      * @param[in] t The current time.
     135             :      * @param[out] dydt A reference to the calculated output.
     136             :      */
     137          85 :     void get_derivatives(Eigen::Ref<const Eigen::VectorX<ScalarType>> pop,
     138             :                          Eigen::Ref<const Eigen::VectorX<ScalarType>> y, ScalarType t,
     139             :                          Eigen::Ref<Eigen::VectorX<ScalarType>> dydt) const override
     140             :     {
     141          85 :         dydt.setZero();
     142             : 
     143          85 :         auto params           = this->parameters;
     144          85 :         auto total_population = pop.sum() - pop[LctState::template get_first_index<InfectionState::Dead>()];
     145             : 
     146             :         // Calculate sum of all subcompartments for InfectedNoSymptoms.
     147          85 :         ScalarType InfectedNoSymptoms_sum =
     148          85 :             pop.segment(LctState::template get_first_index<InfectionState::InfectedNoSymptoms>(),
     149             :                         LctState::template get_num_subcompartments<InfectionState::InfectedNoSymptoms>())
     150          85 :                 .sum();
     151             :         // Calculate sum of all subcompartments for InfectedSymptoms.
     152          85 :         ScalarType InfectedSymptoms_sum =
     153          85 :             pop.segment(LctState::template get_first_index<InfectionState::InfectedSymptoms>(),
     154             :                         LctState::template get_num_subcompartments<InfectionState::InfectedSymptoms>())
     155          85 :                 .sum();
     156             : 
     157             :         // --- Susceptibles. ---
     158          85 :         ScalarType season_val = 1 + params.template get<Seasonality>() *
     159          85 :                                         sin(3.141592653589793 * ((params.template get<StartDay>() + t) / 182.5 + 0.5));
     160         170 :         dydt[0] = -y[0] / total_population * season_val * params.template get<TransmissionProbabilityOnContact>() *
     161         170 :                   params.template get<ContactPatterns>().get_cont_freq_mat().get_matrix_at(t)(0, 0) *
     162          85 :                   (params.template get<RelativeTransmissionNoSymptoms>() * InfectedNoSymptoms_sum +
     163          85 :                    params.template get<RiskOfInfectionFromSymptomatic>() * InfectedSymptoms_sum);
     164             : 
     165             :         // --- Exposed. ---
     166         255 :         dydt.segment(LctState::template get_first_index<InfectionState::Exposed>(),
     167         255 :                      LctState::template get_num_subcompartments<InfectionState::Exposed>()) -=
     168          85 :             dydt[0] * params.template get<StartingProbabilitiesExposed>();
     169         255 :         dydt.segment(LctState::template get_first_index<InfectionState::Exposed>(),
     170          85 :                      LctState::template get_num_subcompartments<InfectionState::Exposed>()) +=
     171         255 :             params.template get<TransitionMatrixExposedToInfectedNoSymptoms>().transpose() *
     172         170 :             y.segment(LctState::template get_first_index<InfectionState::Exposed>(),
     173             :                       LctState::template get_num_subcompartments<InfectionState::Exposed>());
     174             : 
     175             :         // --- InfectedNoSymptoms. ---
     176             :         // Flow from Exposed To InfectedNoSymptoms.
     177         255 :         dydt.segment(LctState::template get_first_index<InfectionState::InfectedNoSymptoms>(),
     178         510 :                      LctState::template get_num_subcompartments<InfectionState::InfectedNoSymptoms>()) =
     179          85 :             -(params.template get<TransitionMatrixExposedToInfectedNoSymptoms>() *
     180          85 :               Eigen::VectorX<ScalarType>::Ones(LctState::template get_num_subcompartments<InfectionState::Exposed>()))
     181             :                  .transpose() *
     182         170 :             y.segment(LctState::template get_first_index<InfectionState::Exposed>(),
     183             :                       LctState::template get_num_subcompartments<InfectionState::Exposed>()) *
     184          85 :             params.template get<StartingProbabilitiesInfectedNoSymptoms>();
     185             :         // Flow from InfectedNoSymptoms To InfectedSymptoms.
     186          85 :         size_t dimensionInfectedNoSymptomsToInfectedSymptoms =
     187          85 :             params.template get<TransitionMatrixInfectedNoSymptomsToInfectedSymptoms>().rows();
     188         255 :         dydt.segment(LctState::template get_first_index<InfectionState::InfectedNoSymptoms>(),
     189          85 :                      dimensionInfectedNoSymptomsToInfectedSymptoms) +=
     190         255 :             params.template get<TransitionMatrixInfectedNoSymptomsToInfectedSymptoms>().transpose() *
     191         170 :             y.segment(LctState::template get_first_index<InfectionState::InfectedNoSymptoms>(),
     192             :                       dimensionInfectedNoSymptomsToInfectedSymptoms);
     193             :         // Flow from InfectedNoSymptoms To Recovered.
     194          85 :         size_t dimensionInfectedNoSymptomsToRecovered =
     195          85 :             params.template get<TransitionMatrixInfectedNoSymptomsToRecovered>().rows();
     196         255 :         dydt.segment(LctState::template get_first_index<InfectionState::InfectedNoSymptoms>() +
     197             :                          dimensionInfectedNoSymptomsToInfectedSymptoms,
     198          85 :                      dimensionInfectedNoSymptomsToRecovered) +=
     199         255 :             params.template get<TransitionMatrixInfectedNoSymptomsToRecovered>().transpose() *
     200         170 :             y.segment(LctState::template get_first_index<InfectionState::InfectedNoSymptoms>() +
     201             :                           dimensionInfectedNoSymptomsToInfectedSymptoms,
     202             :                       dimensionInfectedNoSymptomsToRecovered);
     203             :         // Add flow directly to Recovered compartment.
     204         255 :         dydt[LctState::template get_first_index<InfectionState::Recovered>()] +=
     205          85 :             -(params.template get<TransitionMatrixInfectedNoSymptomsToRecovered>() *
     206             :               Eigen::VectorX<ScalarType>::Ones(dimensionInfectedNoSymptomsToRecovered))
     207             :                  .transpose() *
     208         170 :             y.segment(LctState::template get_first_index<InfectionState::InfectedNoSymptoms>() +
     209             :                           dimensionInfectedNoSymptomsToInfectedSymptoms,
     210             :                       dimensionInfectedNoSymptomsToRecovered);
     211             : 
     212             :         // --- InfectedSymptoms. ---
     213             :         // Flow from InfectedNoSymptoms To InfectedSymptoms.
     214         255 :         dydt.segment(LctState::template get_first_index<InfectionState::InfectedSymptoms>(),
     215         510 :                      LctState::template get_num_subcompartments<InfectionState::InfectedSymptoms>()) =
     216          85 :             -params.template get<StartingProbabilitiesInfectedSymptoms>() *
     217          85 :             (params.template get<TransitionMatrixInfectedNoSymptomsToInfectedSymptoms>() *
     218             :              Eigen::VectorX<ScalarType>::Ones(dimensionInfectedNoSymptomsToInfectedSymptoms))
     219             :                 .transpose() *
     220         170 :             y.segment(LctState::template get_first_index<InfectionState::InfectedNoSymptoms>(),
     221             :                       dimensionInfectedNoSymptomsToInfectedSymptoms);
     222             :         // Flow from InfectedSymptoms To InfectedSevere.
     223          85 :         size_t dimensionInfectedSymptomsToInfectedSevere =
     224          85 :             params.template get<TransitionMatrixInfectedSymptomsToInfectedSevere>().rows();
     225         255 :         dydt.segment(LctState::template get_first_index<InfectionState::InfectedSymptoms>(),
     226          85 :                      dimensionInfectedSymptomsToInfectedSevere) +=
     227         255 :             params.template get<TransitionMatrixInfectedSymptomsToInfectedSevere>().transpose() *
     228         170 :             y.segment(LctState::template get_first_index<InfectionState::InfectedSymptoms>(),
     229             :                       dimensionInfectedSymptomsToInfectedSevere);
     230             :         // Flow from InfectedSymptoms To Recovered.
     231          85 :         size_t dimensionInfectedSymptomsToRecovered =
     232          85 :             params.template get<TransitionMatrixInfectedSymptomsToRecovered>().rows();
     233         255 :         dydt.segment(LctState::template get_first_index<InfectionState::InfectedSymptoms>() +
     234             :                          dimensionInfectedSymptomsToInfectedSevere,
     235          85 :                      dimensionInfectedSymptomsToRecovered) +=
     236         255 :             params.template get<TransitionMatrixInfectedSymptomsToRecovered>().transpose() *
     237         170 :             y.segment(LctState::template get_first_index<InfectionState::InfectedSymptoms>() +
     238             :                           dimensionInfectedSymptomsToInfectedSevere,
     239             :                       dimensionInfectedSymptomsToRecovered);
     240             :         // Add flow directly to Recovered compartment.
     241         255 :         dydt[LctState::template get_first_index<InfectionState::Recovered>()] +=
     242          85 :             -(params.template get<TransitionMatrixInfectedSymptomsToRecovered>() *
     243             :               Eigen::VectorX<ScalarType>::Ones(dimensionInfectedSymptomsToRecovered))
     244             :                  .transpose() *
     245         170 :             y.segment(LctState::template get_first_index<InfectionState::InfectedSymptoms>() +
     246             :                           dimensionInfectedSymptomsToInfectedSevere,
     247             :                       dimensionInfectedSymptomsToRecovered);
     248             : 
     249             :         // --- InfectedSevere. ---
     250             :         // Flow from InfectedSymptoms To InfectedSevere.
     251         255 :         dydt.segment(LctState::template get_first_index<InfectionState::InfectedSevere>(),
     252         510 :                      LctState::template get_num_subcompartments<InfectionState::InfectedSevere>()) =
     253          85 :             -params.template get<StartingProbabilitiesInfectedSevere>() *
     254          85 :             (params.template get<TransitionMatrixInfectedSymptomsToInfectedSevere>() *
     255             :              Eigen::VectorX<ScalarType>::Ones(dimensionInfectedSymptomsToInfectedSevere))
     256             :                 .transpose() *
     257         170 :             y.segment(LctState::template get_first_index<InfectionState::InfectedSymptoms>(),
     258             :                       dimensionInfectedSymptomsToInfectedSevere);
     259             :         // Flow from InfectedSevere To InfectedCritical.
     260          85 :         size_t dimensionInfectedSevereToInfectedCritical =
     261          85 :             params.template get<TransitionMatrixInfectedSevereToInfectedCritical>().rows();
     262         255 :         dydt.segment(LctState::template get_first_index<InfectionState::InfectedSevere>(),
     263          85 :                      dimensionInfectedSevereToInfectedCritical) +=
     264         255 :             params.template get<TransitionMatrixInfectedSevereToInfectedCritical>().transpose() *
     265         170 :             y.segment(LctState::template get_first_index<InfectionState::InfectedSevere>(),
     266             :                       dimensionInfectedSevereToInfectedCritical);
     267             :         // Flow from InfectedSevere To Recovered.
     268          85 :         size_t dimensionInfectedSevereToRecovered =
     269          85 :             params.template get<TransitionMatrixInfectedSevereToRecovered>().rows();
     270         255 :         dydt.segment(LctState::template get_first_index<InfectionState::InfectedSevere>() +
     271             :                          dimensionInfectedSevereToInfectedCritical,
     272          85 :                      dimensionInfectedSevereToRecovered) +=
     273         255 :             params.template get<TransitionMatrixInfectedSevereToRecovered>().transpose() *
     274         170 :             y.segment(LctState::template get_first_index<InfectionState::InfectedSevere>() +
     275             :                           dimensionInfectedSevereToInfectedCritical,
     276             :                       dimensionInfectedSevereToRecovered);
     277             :         // Add flow directly to Recovered compartment.
     278         255 :         dydt[LctState::template get_first_index<InfectionState::Recovered>()] +=
     279          85 :             -(params.template get<TransitionMatrixInfectedSevereToRecovered>() *
     280             :               Eigen::VectorX<ScalarType>::Ones(dimensionInfectedSevereToRecovered))
     281             :                  .transpose() *
     282         170 :             y.segment(LctState::template get_first_index<InfectionState::InfectedSevere>() +
     283             :                           dimensionInfectedSevereToInfectedCritical,
     284             :                       dimensionInfectedSevereToRecovered);
     285             : 
     286             :         // --- InfectedCritical. ---
     287             :         // Flow from InfectedSevere To InfectedCritical.
     288         255 :         dydt.segment(LctState::template get_first_index<InfectionState::InfectedCritical>(),
     289         510 :                      LctState::template get_num_subcompartments<InfectionState::InfectedCritical>()) =
     290          85 :             -params.template get<StartingProbabilitiesInfectedCritical>() *
     291          85 :             (params.template get<TransitionMatrixInfectedSevereToInfectedCritical>() *
     292             :              Eigen::VectorX<ScalarType>::Ones(dimensionInfectedSevereToInfectedCritical))
     293             :                 .transpose() *
     294         170 :             y.segment(LctState::template get_first_index<InfectionState::InfectedSevere>(),
     295             :                       dimensionInfectedSevereToInfectedCritical);
     296             :         // Flow from InfectedCritical To Dead.
     297          85 :         size_t dimensionInfectedCriticalToDead = params.template get<TransitionMatrixInfectedCriticalToDead>().rows();
     298         255 :         dydt.segment(LctState::template get_first_index<InfectionState::InfectedCritical>(),
     299          85 :                      dimensionInfectedCriticalToDead) +=
     300         255 :             params.template get<TransitionMatrixInfectedCriticalToDead>().transpose() *
     301         170 :             y.segment(LctState::template get_first_index<InfectionState::InfectedCritical>(),
     302             :                       dimensionInfectedCriticalToDead);
     303             :         // Flow from InfectedCritical To Recovered.
     304          85 :         size_t dimensionInfectedCriticalToRecovered =
     305          85 :             params.template get<TransitionMatrixInfectedCriticalToRecovered>().rows();
     306         255 :         dydt.segment(LctState::template get_first_index<InfectionState::InfectedCritical>() +
     307             :                          dimensionInfectedCriticalToDead,
     308          85 :                      dimensionInfectedCriticalToRecovered) +=
     309         255 :             params.template get<TransitionMatrixInfectedCriticalToRecovered>().transpose() *
     310         170 :             y.segment(LctState::template get_first_index<InfectionState::InfectedCritical>() +
     311             :                           dimensionInfectedCriticalToDead,
     312             :                       dimensionInfectedCriticalToRecovered);
     313             :         // Add flow directly to Recovered compartment.
     314         255 :         dydt[LctState::template get_first_index<InfectionState::Recovered>()] +=
     315          85 :             -(params.template get<TransitionMatrixInfectedCriticalToRecovered>() *
     316             :               Eigen::VectorX<ScalarType>::Ones(dimensionInfectedCriticalToRecovered))
     317             :                  .transpose() *
     318         170 :             y.segment(LctState::template get_first_index<InfectionState::InfectedCritical>() +
     319             :                           dimensionInfectedCriticalToDead,
     320             :                       dimensionInfectedCriticalToRecovered);
     321             : 
     322             :         // --- Dead. ---
     323         255 :         dydt[LctState::template get_first_index<InfectionState::Dead>()] =
     324          85 :             -(params.template get<TransitionMatrixInfectedCriticalToDead>() *
     325             :               Eigen::VectorX<ScalarType>::Ones(dimensionInfectedCriticalToDead))
     326             :                  .transpose() *
     327         170 :             y.segment(LctState::template get_first_index<InfectionState::InfectedCritical>(),
     328             :                       dimensionInfectedCriticalToDead);
     329         170 :     }
     330             : 
     331             :     /**
     332             :      * @brief Cumulates a simulation result with subcompartments to produce a result that divides the population only
     333             :      *   into the infection states defined in InfectionState.
     334             :      *
     335             :      * If the model is used for simulation, we will get a result in form of a TimeSeries with infection states divided 
     336             :      * in subcompartments.
     337             :      * The function calculates a TimeSeries without subcompartments from another TimeSeries with subcompartments. 
     338             :      * This is done by summing up the corresponding subcompartments.
     339             :      * @param[in] subcompartments_ts Result of a simulation with the model.
     340             :      * @return Result of the simulation divided in infection states without subcompartments. 
     341             :      *  Returns TimeSeries with values -1 if calculation is not possible.
     342             :      */
     343           2 :     TimeSeries<ScalarType> calculate_compartments(const TimeSeries<ScalarType>& subcompartments_ts) const
     344             :     {
     345           2 :         TimeSeries<ScalarType> compartments_ts((Eigen::Index)InfectionState::Count);
     346           2 :         if (!(LctState::Count == subcompartments_ts.get_num_elements())) {
     347           1 :             log_error("Result does not match InfectionStates of the model.");
     348             :             // Return a TimeSeries with values -1.
     349           1 :             Eigen::VectorX<ScalarType> error_output =
     350             :                 Eigen::VectorX<ScalarType>::Constant((Eigen::Index)InfectionState::Count, -1);
     351           1 :             compartments_ts.add_time_point(-1, error_output);
     352           1 :             return compartments_ts;
     353           1 :         }
     354           1 :         Eigen::VectorX<ScalarType> compartments((Eigen::Index)InfectionState::Count);
     355          14 :         for (Eigen::Index i = 0; i < subcompartments_ts.get_num_time_points(); ++i) {
     356          13 :             compartments_ts.add_time_point(subcompartments_ts.get_time(i),
     357             :                                            LctState::calculate_compartments(subcompartments_ts[i]));
     358             :         }
     359           1 :         return compartments_ts;
     360           2 :     }
     361             : };
     362             : 
     363             : } // namespace glsecir
     364             : } // namespace mio
     365             : 
     366             : #endif // MIO_GLCT_SECIR_MODEL_H

Generated by: LCOV version 1.14