/*
 * Model.cpp
 *
 * Code generation for model "Model".
 *
 * Model version              : 1.2
 * Simulink Coder version : 9.7 (R2022a) 13-Nov-2021
 * C++ source code generated on : Sat Mar 28 11:28:04 2026
 *
 * Target selection: grt.tlc
 * Note: GRT includes extra infrastructure and instrumentation for prototyping
 * Embedded hardware selection: Intel->x86-64 (Windows64)
 * Code generation objectives: Unspecified
 * Validation result: Not run
 */

#include "Model.h"
#include "rtwtypes.h"
#include "Model_private.h"

extern "C" {

#include "rt_nonfinite.h"

}
/*
 * This function updates continuous states using the ODE3 fixed-step
 * solver algorithm
 */
  void Model::rt_ertODEUpdateContinuousStates(RTWSolverInfo *si )
{
  /* Solver Matrices */
  static const real_T rt_ODE3_A[3]{
    1.0/2.0, 3.0/4.0, 1.0
  };

  static const real_T rt_ODE3_B[3][3]{
    { 1.0/2.0, 0.0, 0.0 },

    { 0.0, 3.0/4.0, 0.0 },

    { 2.0/9.0, 1.0/3.0, 4.0/9.0 }
  };

  time_T t { rtsiGetT(si) };

  time_T tnew { rtsiGetSolverStopTime(si) };

  time_T h { rtsiGetStepSize(si) };

  real_T *x { rtsiGetContStates(si) };

  ODE3_IntgData *id { static_cast<ODE3_IntgData *>(rtsiGetSolverData(si)) };

  real_T *y { id->y };

  real_T *f0 { id->f[0] };

  real_T *f1 { id->f[1] };

  real_T *f2 { id->f[2] };

  real_T hB[3];
  int_T i;
  int_T nXc { 3 };

  rtsiSetSimTimeStep(si,MINOR_TIME_STEP);

  /* Save the state values at time t in y, we'll use x as ynew. */
  (void) std::memcpy(y, x,
                     static_cast<uint_T>(nXc)*sizeof(real_T));

  /* Assumes that rtsiSetT and ModelOutputs are up-to-date */
  /* f0 = f(t,y) */
  rtsiSetdX(si, f0);
  Model_derivatives();

  /* f(:,2) = feval(odefile, t + hA(1), y + f*hB(:,1), args(:)(*)); */
  hB[0] = h * rt_ODE3_B[0][0];
  for (i = 0; i < nXc; i++) {
    x[i] = y[i] + (f0[i]*hB[0]);
  }

  rtsiSetT(si, t + h*rt_ODE3_A[0]);
  rtsiSetdX(si, f1);
  this->step();
  Model_derivatives();

  /* f(:,3) = feval(odefile, t + hA(2), y + f*hB(:,2), args(:)(*)); */
  for (i = 0; i <= 1; i++) {
    hB[i] = h * rt_ODE3_B[1][i];
  }

  for (i = 0; i < nXc; i++) {
    x[i] = y[i] + (f0[i]*hB[0] + f1[i]*hB[1]);
  }

  rtsiSetT(si, t + h*rt_ODE3_A[1]);
  rtsiSetdX(si, f2);
  this->step();
  Model_derivatives();

  /* tnew = t + hA(3);
     ynew = y + f*hB(:,3); */
  for (i = 0; i <= 2; i++) {
    hB[i] = h * rt_ODE3_B[2][i];
  }

  for (i = 0; i < nXc; i++) {
    x[i] = y[i] + (f0[i]*hB[0] + f1[i]*hB[1] + f2[i]*hB[2]);
  }

  rtsiSetT(si, tnew);
  rtsiSetSimTimeStep(si,MAJOR_TIME_STEP);
}

/* Model step function */
void Model::step()
{
  real_T rtb_Gain1;
  real_T rtb_Gain4;
  if (rtmIsMajorTimeStep((&Model_M))) {
    /* set solver stop time */
    if (!((&Model_M)->Timing.clockTick0+1)) {
      rtsiSetSolverStopTime(&(&Model_M)->solverInfo, (((&Model_M)
        ->Timing.clockTickH0 + 1) * (&Model_M)->Timing.stepSize0 * 4294967296.0));
    } else {
      rtsiSetSolverStopTime(&(&Model_M)->solverInfo, (((&Model_M)
        ->Timing.clockTick0 + 1) * (&Model_M)->Timing.stepSize0 + (&Model_M)
        ->Timing.clockTickH0 * (&Model_M)->Timing.stepSize0 * 4294967296.0));
    }
  }                                    /* end MajorTimeStep */

  /* Update absolute time of base rate at minor time step */
  if (rtmIsMinorTimeStep((&Model_M))) {
    (&Model_M)->Timing.t[0] = rtsiGetT(&(&Model_M)->solverInfo);
  }

  /* Outport: '<Root>/Temperatur' incorporates:
   *  Integrator: '<S1>/Integrator1'
   */
  Model_Y.Temperatur = Model_X.Integrator1_CSTATE;

  /* Gain: '<S1>/Gain1' incorporates:
   *  Integrator: '<S1>/Integrator'
   *  Integrator: '<S1>/Integrator1'
   *  Sum: '<S1>/Plus1'
   */
  rtb_Gain1 = Model_P.alphaHD * Model_P.AHD * (Model_X.Integrator_CSTATE -
    Model_X.Integrator1_CSTATE);

  /* Gain: '<S1>/Gain' incorporates:
   *  Inport: '<Root>/Stellgrad'
   *  Sum: '<S1>/Plus'
   */
  Model_B.Gain = 1.0 / (Model_P.mHD * Model_P.CHD) * (Model_U.Stellgrad -
    rtb_Gain1);

  /* Gain: '<S1>/Gain4' incorporates:
   *  Integrator: '<S1>/Integrator1'
   *  Integrator: '<S1>/Integrator2'
   *  Sum: '<S1>/Plus4'
   */
  rtb_Gain4 = Model_P.alphaSW * Model_P.Ai * (Model_X.Integrator1_CSTATE -
    Model_X.Integrator2_CSTATE);

  /* Gain: '<S1>/Gain2' incorporates:
   *  Sum: '<S1>/Plus2'
   */
  Model_B.Gain2 = 1.0 / (Model_P.ml * Model_P.Cl + Model_P.mES * Model_P.CES) *
    (rtb_Gain1 - rtb_Gain4);

  /* Gain: '<S1>/Gain5' incorporates:
   *  Constant: '<Root>/Constant'
   *  Gain: '<S1>/Gain7'
   *  Integrator: '<S1>/Integrator2'
   *  Sum: '<S1>/Plus5'
   *  Sum: '<S1>/Plus7'
   */
  Model_B.Gain5 = (rtb_Gain4 - Model_P.alpha_aussen * Model_P.A_Aussen *
                   (Model_X.Integrator2_CSTATE - Model_P.Constant_Value)) * (1.0
    / (Model_P.mSW * Model_P.CSW));
  if (rtmIsMajorTimeStep((&Model_M))) {
    /* Matfile logging */
    rt_UpdateTXYLogVars((&Model_M)->rtwLogInfo, ((&Model_M)->Timing.t));
  }                                    /* end MajorTimeStep */

  if (rtmIsMajorTimeStep((&Model_M))) {
    /* signal main to stop simulation */
    {                                  /* Sample time: [0.0s, 0.0s] */
      if ((rtmGetTFinal((&Model_M))!=-1) &&
          !((rtmGetTFinal((&Model_M))-((((&Model_M)->Timing.clockTick1+(&Model_M)
               ->Timing.clockTickH1* 4294967296.0)) * 0.05)) > ((((&Model_M)
              ->Timing.clockTick1+(&Model_M)->Timing.clockTickH1* 4294967296.0))
            * 0.05) * (DBL_EPSILON))) {
        rtmSetErrorStatus((&Model_M), "Simulation finished");
      }
    }

    rt_ertODEUpdateContinuousStates(&(&Model_M)->solverInfo);

    /* Update absolute time for base rate */
    /* The "clockTick0" counts the number of times the code of this task has
     * been executed. The absolute time is the multiplication of "clockTick0"
     * and "Timing.stepSize0". Size of "clockTick0" ensures timer will not
     * overflow during the application lifespan selected.
     * Timer of this task consists of two 32 bit unsigned integers.
     * The two integers represent the low bits Timing.clockTick0 and the high bits
     * Timing.clockTickH0. When the low bit overflows to 0, the high bits increment.
     */
    if (!(++(&Model_M)->Timing.clockTick0)) {
      ++(&Model_M)->Timing.clockTickH0;
    }

    (&Model_M)->Timing.t[0] = rtsiGetSolverStopTime(&(&Model_M)->solverInfo);

    {
      /* Update absolute timer for sample time: [0.05s, 0.0s] */
      /* The "clockTick1" counts the number of times the code of this task has
       * been executed. The resolution of this integer timer is 0.05, which is the step size
       * of the task. Size of "clockTick1" ensures timer will not overflow during the
       * application lifespan selected.
       * Timer of this task consists of two 32 bit unsigned integers.
       * The two integers represent the low bits Timing.clockTick1 and the high bits
       * Timing.clockTickH1. When the low bit overflows to 0, the high bits increment.
       */
      (&Model_M)->Timing.clockTick1++;
      if (!(&Model_M)->Timing.clockTick1) {
        (&Model_M)->Timing.clockTickH1++;
      }
    }
  }                                    /* end MajorTimeStep */
}

/* Derivatives for root system: '<Root>' */
void Model::Model_derivatives()
{
  XDot_Model_T *_rtXdot;
  _rtXdot = ((XDot_Model_T *) (&Model_M)->derivs);

  /* Derivatives for Integrator: '<S1>/Integrator1' */
  _rtXdot->Integrator1_CSTATE = Model_B.Gain2;

  /* Derivatives for Integrator: '<S1>/Integrator' */
  _rtXdot->Integrator_CSTATE = Model_B.Gain;

  /* Derivatives for Integrator: '<S1>/Integrator2' */
  _rtXdot->Integrator2_CSTATE = Model_B.Gain5;
}

/* Model initialize function */
void Model::initialize()
{
  /* Registration code */

  /* initialize non-finites */
  rt_InitInfAndNaN(sizeof(real_T));

  {
    /* Setup solver object */
    rtsiSetSimTimeStepPtr(&(&Model_M)->solverInfo, &(&Model_M)
                          ->Timing.simTimeStep);
    rtsiSetTPtr(&(&Model_M)->solverInfo, &rtmGetTPtr((&Model_M)));
    rtsiSetStepSizePtr(&(&Model_M)->solverInfo, &(&Model_M)->Timing.stepSize0);
    rtsiSetdXPtr(&(&Model_M)->solverInfo, &(&Model_M)->derivs);
    rtsiSetContStatesPtr(&(&Model_M)->solverInfo, (real_T **) &(&Model_M)
                         ->contStates);
    rtsiSetNumContStatesPtr(&(&Model_M)->solverInfo, &(&Model_M)
      ->Sizes.numContStates);
    rtsiSetNumPeriodicContStatesPtr(&(&Model_M)->solverInfo, &(&Model_M)
      ->Sizes.numPeriodicContStates);
    rtsiSetPeriodicContStateIndicesPtr(&(&Model_M)->solverInfo, &(&Model_M)
      ->periodicContStateIndices);
    rtsiSetPeriodicContStateRangesPtr(&(&Model_M)->solverInfo, &(&Model_M)
      ->periodicContStateRanges);
    rtsiSetErrorStatusPtr(&(&Model_M)->solverInfo, (&rtmGetErrorStatus((&Model_M))));
    rtsiSetRTModelPtr(&(&Model_M)->solverInfo, (&Model_M));
  }

  rtsiSetSimTimeStep(&(&Model_M)->solverInfo, MAJOR_TIME_STEP);
  (&Model_M)->intgData.y = (&Model_M)->odeY;
  (&Model_M)->intgData.f[0] = (&Model_M)->odeF[0];
  (&Model_M)->intgData.f[1] = (&Model_M)->odeF[1];
  (&Model_M)->intgData.f[2] = (&Model_M)->odeF[2];
  (&Model_M)->contStates = ((X_Model_T *) &Model_X);
  rtsiSetSolverData(&(&Model_M)->solverInfo, static_cast<void *>(&(&Model_M)
    ->intgData));
  rtsiSetIsMinorTimeStepWithModeChange(&(&Model_M)->solverInfo, false);
  rtsiSetSolverName(&(&Model_M)->solverInfo,"ode3");
  rtmSetTPtr((&Model_M), &(&Model_M)->Timing.tArray[0]);
  rtmSetTFinal((&Model_M), 10.0);
  (&Model_M)->Timing.stepSize0 = 0.05;

  /* Setup for data logging */
  {
    static RTWLogInfo rt_DataLoggingInfo;
    rt_DataLoggingInfo.loggingInterval = (nullptr);
    (&Model_M)->rtwLogInfo = &rt_DataLoggingInfo;
  }

  /* Setup for data logging */
  {
    rtliSetLogXSignalInfo((&Model_M)->rtwLogInfo, (nullptr));
    rtliSetLogXSignalPtrs((&Model_M)->rtwLogInfo, (nullptr));
    rtliSetLogT((&Model_M)->rtwLogInfo, "tout");
    rtliSetLogX((&Model_M)->rtwLogInfo, "");
    rtliSetLogXFinal((&Model_M)->rtwLogInfo, "");
    rtliSetLogVarNameModifier((&Model_M)->rtwLogInfo, "rt_");
    rtliSetLogFormat((&Model_M)->rtwLogInfo, 4);
    rtliSetLogMaxRows((&Model_M)->rtwLogInfo, 0);
    rtliSetLogDecimation((&Model_M)->rtwLogInfo, 1);
    rtliSetLogY((&Model_M)->rtwLogInfo, "");
    rtliSetLogYSignalInfo((&Model_M)->rtwLogInfo, (nullptr));
    rtliSetLogYSignalPtrs((&Model_M)->rtwLogInfo, (nullptr));
  }

  /* Matfile logging */
  rt_StartDataLoggingWithStartTime((&Model_M)->rtwLogInfo, 0.0, rtmGetTFinal
    ((&Model_M)), (&Model_M)->Timing.stepSize0, (&rtmGetErrorStatus((&Model_M))));

  /* InitializeConditions for Integrator: '<S1>/Integrator1' */
  Model_X.Integrator1_CSTATE = Model_P.T_amb;

  /* InitializeConditions for Integrator: '<S1>/Integrator' */
  Model_X.Integrator_CSTATE = Model_P.T_amb;

  /* InitializeConditions for Integrator: '<S1>/Integrator2' */
  Model_X.Integrator2_CSTATE = Model_P.T_amb;
}

/* Model terminate function */
void Model::terminate()
{
  /* (no terminate code required) */
}

/* Constructor */
Model::Model() :
  Model_U(),
  Model_Y(),
  Model_B(),
  Model_X(),
  Model_M()
{
  /* Currently there is no constructor body generated.*/
}

/* Destructor */
Model::~Model()
{
  /* Currently there is no destructor body generated.*/
}

/* Real-Time Model get method */
RT_MODEL_Model_T * Model::getRTM()
{
  return (&Model_M);
}
