package GlucoseInsulinRegulator

model GlucoseInsulinEquations
    input Real glucosein "optional inflow of glucose mg/s";
    Real x(start = 0.81) "concentration of glucose";
    Real qRL "renal loss rate of glucose";
    Real mg "amount of glucose in ECF";
    Real Qtuii "tissues insulin independence";
    Real Qtuid "tissues insulin dependence";
    Real y(start = 0.056) "insulin concentration mU/mg";
    Real mi "amount of insulin in ECF";
    Real Qip "insulin production rate";
    Real Qid "insulin destruction rate";
    parameter Real Mu = 7200/3600 "7200ml/s as renal loss rate";
    parameter Real Teta = 2.5 "2.5mg/ml as threshold triggering renal loss";
    parameter Real VECF = 15000 "Volume of ECF";
    parameter Real Qg = 8400/3600 "mg/s glucose production rate";
    parameter Real landa = 2470/3600 "2470 ml/h tissue utilization rate factor";
    parameter Real beta = 1430/3600 "1430mU.ml (mg.s) as production of insulin rate factor";
    parameter Real phi = 0.51 "mg/ml as threshold triggering insulin production";
    parameter Real alfa = 7600/3600 "insulin destruction";
    parameter Real v = 139000/3600 "ml^2/mU.s tissue utilization rate factor dependent on insulin";
equation
    if x > Teta then
      qRL = Mu*(x - Teta);
    else
      qRL = 0;
    end if;
    x = mg/VECF;
    der(mg) = glucosein + Qg - qRL - Qtuii - Qtuid;
    Qtuii = landa*x;
    y = mi/VECF;
    der(mi) = Qip - Qid;
    if x > phi then
      Qip = beta*(x - phi);
    else
      Qip = 0;
    end if;
    Qid = alfa*y;
    Qtuid = v*x*y;
    annotation (
      Diagram);
end GlucoseInsulinEquations;

  package Type
   type MassFlowRate = Modelica.Units.SI.MassFlowRate (
                                                     displayUnit="mg/hour", nominal=(1e-6)/3600);
    type Volume =  Modelica.Units.SI.Volume (
                                           displayUnit="ml", nominal=1e-6, min=0);
   type Mass = Modelica.Units.SI.Mass (
                                     displayUnit="mg", nominal=1e-6, min=0);
    type MassConcentration =
                   Modelica.Units.SI.MassConcentration (
                                                      displayUnit="mg/l", nominal=1e-3, min=0);
   type InsulinIU = Real (
       quantity="insulinIU",
       final unit="IU",
       displayUnit = "IU",
       min=0);
    type InsulinConcentration =
                   Real (
                   quantity="insulinConcentrationIU",
                   final unit="IU/m3",
                   displayUnit="IU/l",
                   nominal=1e-3,
                   min=0);
   type InsulinFlowRate =
                       Real (
                       quantity="InsulunFlowRate",
                       final unit="IU/s",
                       displayUnit="IU/hour",
                       nominal=1/3600) annotation ();
    connector VolumeInput=input Volume annotation (
      Icon(graphics={  Polygon(origin = {0, 1}, fillColor = {0, 0, 127},
              fillPattern =                                                            FillPattern.Solid, points = {{-100, 99}, {100, -1}, {-100, -99}, {-100, 99}, {-100, 99}})}));
    connector MassFlowRateInput=input MassFlowRate annotation (
      Icon(graphics={  Polygon(origin = {0, 1}, fillColor = {0, 0, 127},
              fillPattern =                                                            FillPattern.Solid, points = {{-100, 99}, {100, -1}, {-100, -99}, {-100, 99}, {-100, 99}})}));
    connector MassConcentrationInput = MassConcentration annotation (
      Icon(graphics={  Polygon(origin = {0, 1}, fillColor = {0, 0, 127},
              fillPattern =                                                            FillPattern.Solid, points = {{-100, 99}, {100, -1}, {-100, -99}, {-100, 99}, {-100, 99}})}));
    connector InsulinConcentrationInput =
                          input InsulinConcentration annotation (
      Icon(graphics={  Polygon(origin = {0, 1}, fillColor = {0, 0, 127},
              fillPattern =                                                            FillPattern.Solid, points = {{-100, 99}, {100, -1}, {-100, -99}, {-100, 99}, {-100, 99}})}));
    connector MassConcentrationOutput=output MassConcentration annotation (
      Icon(graphics={  Polygon(origin = {-1, 0}, fillColor = {255, 255, 255},
              fillPattern =                                                                 FillPattern.Solid, points = {{-99, 100}, {99, 0}, {-99, -100}, {-99, 100}})}));
    connector MassFlowRateOutput =
                                output MassFlowRate annotation (Icon(graphics={
                       Polygon(origin={-3,0},    fillColor = {255, 255, 255},
              fillPattern =                                                                 FillPattern.Solid, points = {{-99, 100}, {99, 0}, {-99, -100}, {-99, 100}})}));
    connector VolumeOutput =
                          output Volume annotation (Icon(graphics={
                       Polygon(origin={-1,0},    fillColor = {255, 255, 255},
              fillPattern =                                                                 FillPattern.Solid, points = {{-99, 100}, {99, 0}, {-99, -100}, {-99, 100}})}));
    connector InsulinFlowRateOutput =
                          output InsulinFlowRate annotation (Icon(graphics={
                       Polygon(origin={-1,0},    fillColor = {255, 255, 255},
              fillPattern =                                                                 FillPattern.Solid, points = {{-99, 100}, {99, 0}, {-99, -100}, {-99, 100}})}));
    connector InsulinConcentrationOutput =
                          output InsulinConcentration annotation (Icon(graphics={
                       Polygon(origin={-1,0},    fillColor = {255, 255, 255},
              fillPattern =                                                                 FillPattern.Solid, points = {{-99, 100}, {99, 0}, {-99, -100}, {-99, 100}})}));
    connector MassOutput =output Mass annotation (Icon(graphics={
                       Polygon(origin={-1,0},    fillColor = {255, 255, 255},
              fillPattern =                                                                 FillPattern.Solid, points = {{-99, 100}, {99, 0}, {-99, -100}, {-99, 100}})}));
    connector InsulinIUOutput =
                          output InsulinIU annotation (Icon(graphics={
                       Polygon(origin={-1,0},    fillColor = {255, 255, 255},
              fillPattern =                                                                 FillPattern.Solid, points = {{-99, 100}, {99, 0}, {-99, -100}, {-99, 100}})}));
    connector MassFlow
      flow MassFlowRate q;
      MassConcentration c;
                                          annotation (
        Icon(graphics={  Polygon(fillColor = {255, 0, 255}, fillPattern = FillPattern.Solid, points = {{0, 100}, {-100, 0}, {0, -100}, {100, 0}, {0, 100}, {0, 100}})}));
    end MassFlow;

    connector InsulinFlow
      flow InsulinFlowRate q;
      InsulinConcentration c;
                                          annotation (
        Icon(graphics={  Polygon(fillColor = {255, 0, 255}, fillPattern = FillPattern.Solid, points = {{0, 100}, {-100, 0}, {0, -100}, {100, 0}, {0, 100}, {0, 100}})}));
    end InsulinFlow;

    connector InsulinFLowRateInput =
                          input InsulinFlowRate annotation (
      Icon(graphics={  Polygon(origin = {0, 1}, fillColor = {0, 0, 127},
              fillPattern =                                                            FillPattern.Solid, points = {{-100, 99}, {100, -1}, {-100, -99}, {-100, 99}, {-100, 99}})}));
    connector MassInput = input Mass annotation (
      Icon(graphics={  Polygon(origin = {0, 1}, fillColor = {0, 0, 127},
              fillPattern =                                                            FillPattern.Solid, points = {{-100, 99}, {100, -1}, {-100, -99}, {-100, 99}, {-100, 99}})}));
    connector InsulinIUInput =
                          input InsulinIU annotation (
      Icon(graphics={  Polygon(origin = {0, 1}, fillColor = {0, 0, 127},
              fillPattern =                                                            FillPattern.Solid, points = {{-100, 99}, {100, -1}, {-100, -99}, {-100, 99}, {-100, 99}})}));
  annotation (
        Icon);
  end Type;

  package Components

    model Compartment
      parameter Type.Mass initialMass;
      Type.MassFlow massFlow annotation (Placement(transformation(extent={{-10,76},{
                10,96}}), iconTransformation(extent={{-10,76},{10,96}})));
      Type.MassConcentrationOutput massConcentrationOutput annotation (Placement(
            transformation(extent={{92,-8},{112,12}}), iconTransformation(extent={{92,
                -8},{112,12}})));
      Type.VolumeInput volumeInput annotation (Placement(transformation(extent={{-110,
                -8},{-90,12}}), iconTransformation(extent={{-110,-8},{-90,12}})));
      Type.MassOutput massOutput annotation (Placement(transformation(
            extent={{-10,-10},{10,10}},
            rotation=270,
            origin={0,-92}), iconTransformation(
            extent={{-10,-10},{10,10}},
            rotation=270,
            origin={0,-92})));
      Type.Mass mass(start=initialMass);
    equation
      der(mass) = massFlow.q;
      massFlow.c = mass / volumeInput;
      massConcentrationOutput= massFlow.c;
      massOutput=mass;
        annotation (Placement(
          visible=true,
          transformation(
            origin={0,0},
            extent={{-10,-10},{10,10}},
            rotation=0),
          iconTransformation(
            origin={-59,-19},
            extent={{-41,-41},{41,41}},
            rotation=0)),
        Icon(graphics={  Text(origin = {1, -121}, extent = {{-281, 19}, {277, -19}}, textString = "%name"), Polygon(origin = {-1, 0}, fillColor = {238, 238, 236},
                fillPattern =                                                                                                                                                    FillPattern.Solid, points = {{-97, 88}, {-97, 72}, {-95, -88}, {93, -88}, {97, 74}, {95, 88}, {-97, 88}, {-97, 88}}, smooth = Smooth.Bezier), Polygon(origin = {-9, -24}, fillColor = {173, 127, 168}, pattern = LinePattern.None,
                fillPattern =                                                                                                                                                                                                        FillPattern.Solid, points = {{-85, 64}, {-91, 46}, {-73, -56}, {83, -56}, {101, 42}, {101, 56}, {69, 56}, {-85, 64}}, smooth = Smooth.Bezier)}, coordinateSystem(initialScale = 0.1)));
    end Compartment;

    model InsulinCompartment
      parameter Type.InsulinIU initialInsulinIU;
      Type.InsulinIU insulinMass(start=initialInsulinIU);
      Type.InsulinFlow insulinFlow annotation (Placement(transformation(extent={{-212,
                16},{-192,36}}), iconTransformation(extent={{-8,78},{12,98}})));
      Type.VolumeInput volumeInput annotation (Placement(transformation(extent={{-214,
                16},{-194,36}}), iconTransformation(extent={{-110,-10},{-90,10}})));
      Type.InsulinConcentrationOutput insulinConcentrationOutput annotation (
          Placement(transformation(extent={{-214,-32},{-194,-12}}),
            iconTransformation(extent={{92,-2},{112,18}})));
      Type.InsulinIUOutput insulinIUOutput annotation (Placement(transformation(
              extent={{-356,8},{-336,28}}), iconTransformation(
            extent={{-10,-10},{10,10}},
            rotation=270,
            origin={-8,-94})));
    equation
      der(insulinMass) = insulinFlow.q;
      insulinFlow.c = insulinMass / volumeInput;
      insulinConcentrationOutput= insulinFlow.c;
      insulinIUOutput=insulinMass;
        annotation (Placement(
          visible=true,
          transformation(
            origin={0,0},
            extent={{-10,-10},{10,10}},
            rotation=0),
          iconTransformation(
            origin={-59,-19},
            extent={{-41,-41},{41,41}},
            rotation=0)),
        Icon(graphics={  Text(origin = {1, -121}, extent = {{-281, 19}, {277, -19}}, textString = "%name"), Polygon(origin = {-1, 0}, fillColor = {238, 238, 236},
                fillPattern =                                                                                                                                                    FillPattern.Solid, points = {{-97, 88}, {-97, 72}, {-95, -88}, {93, -88}, {97, 74}, {95, 88}, {-97, 88}, {-97, 88}}, smooth = Smooth.Bezier), Polygon(origin = {-9, -24}, fillColor = {173, 127, 168}, pattern = LinePattern.None,
                fillPattern =                                                                                                                                                                                                        FillPattern.Solid, points = {{-85, 64}, {-91, 46}, {-73, -56}, {83, -56}, {101, 42}, {101, 56}, {69, 56}, {-85, 64}}, smooth = Smooth.Bezier)}, coordinateSystem(initialScale = 0.1)));
    end InsulinCompartment;

    model fromInsulinUI
      Type.MassOutput massOutput annotation (Placement(transformation(extent={{-244,
                -14},{-224,6}}), iconTransformation(extent={{100,-10},{120,10}})));
      Type.InsulinIUInput insulinIUInput annotation (Placement(transformation(
              extent={{-222,-18},{-202,2}}), iconTransformation(extent={{-120,-10},{
                -100,10}})));
    equation
       //Insulin: 1 IU is equivalent to 0.0347 mg of human insulin, 1 mU = 0.0347 * 1e-9 kg
       massOutput=0.0347*1e-9*insulinIUInput;

      annotation (Icon(coordinateSystem(preserveAspectRatio=false), graphics={
            Rectangle(
              extent={{-100,40},{100,-40}},
              lineColor={28,108,200},
              lineThickness=1),
            Text(
              extent={{-102,32},{-2,-32}},
              textColor={28,108,200},
              textString="UI"),
            Polygon(
              points={{-8,30},{-8,-28},{76,0},{-8,30}},
              lineColor={28,108,200},
              lineThickness=1,
              fillColor={28,108,200},
              fillPattern=FillPattern.Solid)}), Diagram(coordinateSystem(
              preserveAspectRatio=false)));
    end fromInsulinUI;

    model ToInsulinUI
      Type.MassInput massInput annotation (Placement(transformation(extent={{-222,16},
                {-202,36}}), iconTransformation(extent={{-120,-10},{-100,10}})));
      Type.InsulinIUOutput insulinIUOutput annotation (Placement(transformation(
              extent={{-220,32},{-200,52}}), iconTransformation(extent={{98,-8},{118,
                12}})));
    equation
       //Insulin: 1 IU is equivalent to 0.0347 mg of human insulin, 1 mU = 0.0347 * 1e-9 kg
       massInput=0.0347*1e-9*insulinIUOutput;

      annotation (Icon(coordinateSystem(preserveAspectRatio=false), graphics={
            Rectangle(
              extent={{-100,40},{100,-40}},
              lineColor={28,108,200},
              lineThickness=1),
            Text(
              extent={{10,32},{110,-32}},
              textColor={28,108,200},
              textString="UI"),
            Polygon(
              points={{-70,32},{-70,-26},{14,2},{-70,32}},
              lineColor={28,108,200},
              lineThickness=1,
              fillColor={28,108,200},
              fillPattern=FillPattern.Solid)}), Diagram(coordinateSystem(
              preserveAspectRatio=false)));
    end ToInsulinUI;

    model fromInsulinUIConcentration
      Type.InsulinConcentrationInput insulinConcentrationInput annotation (
          Placement(transformation(extent={{-220,28},{-200,48}}),
            iconTransformation(extent={{-120,-10},{-100,10}})));
      Type.MassConcentrationOutput massConcentrationOutput annotation (Placement(
            transformation(extent={{-220,32},{-200,52}}), iconTransformation(extent=
               {{100,-10},{120,10}})));
    equation
       //Insulin: 1 IU is equivalent to 0.0347 mg of human insulin, 1 mU = 0.0347 * 1e-9 kg
       massConcentrationOutput=0.0347*1e-9*insulinConcentrationInput;

      annotation (Icon(coordinateSystem(preserveAspectRatio=false), graphics={
            Rectangle(
              extent={{-100,40},{100,-40}},
              lineColor={28,108,200},
              lineThickness=1),
            Text(
              extent={{-98,32},{2,-32}},
              textColor={28,108,200},
              textString="UI c"),
            Polygon(
              points={{10,32},{10,-26},{94,2},{10,32}},
              lineColor={28,108,200},
              lineThickness=1,
              fillColor={28,108,200},
              fillPattern=FillPattern.Solid)}), Diagram(coordinateSystem(
              preserveAspectRatio=false)));
    end fromInsulinUIConcentration;

    model ToInsulinUIConcentration
      Type.MassConcentrationInput massConcentrationInput annotation (Placement(
            transformation(extent={{-222,42},{-202,62}}), iconTransformation(extent=
               {{-120,-10},{-100,10}})));
      Type.InsulinConcentrationOutput insulinConcentrationOutput annotation (
          Placement(transformation(extent={{-222,-16},{-202,4}}),
            iconTransformation(extent={{100,-8},{120,12}})));
    equation
       //Insulin: 1 IU is equivalent to 0.0347 mg of human insulin, 1 mU = 0.0347 * 1e-9 kg
       massConcentrationInput=0.0347*1e-9*insulinConcentrationOutput;

      annotation (Icon(coordinateSystem(preserveAspectRatio=false), graphics={
            Rectangle(
              extent={{-100,40},{100,-40}},
              lineColor={28,108,200},
              lineThickness=1),
            Text(
              extent={{-14,36},{86,-28}},
              textColor={28,108,200},
              textString="UI c"),
            Polygon(
              points={{-90,30},{-90,-28},{-6,0},{-90,30}},
              lineColor={28,108,200},
              lineThickness=1,
              fillColor={28,108,200},
              fillPattern=FillPattern.Solid)}), Diagram(coordinateSystem(
              preserveAspectRatio=false)));
    end ToInsulinUIConcentration;

    model InitialInsulinContent
      parameter Type.InsulinIU initialInsulinIU=0.056;
      Type.MassOutput massOutput=initialInsulinIU*0.0347e-9 annotation (Placement(transformation(extent={{110,0},
                {130,20}}), iconTransformation(extent={{100,-10},{120,10}})));
      annotation (Icon(coordinateSystem(preserveAspectRatio=false), graphics={
            Rectangle(
              extent={{-100,46},{100,-34}},
              lineColor={28,108,200},
              lineThickness=1),
            Text(
              extent={{-104,-52},{140,-72}},
              textColor={28,108,200},
              textString="%name"),
            Text(
              extent={{34,32},{100,-26}},
              textColor={28,108,200},
              textString="IU")}),                                    Diagram(
            coordinateSystem(preserveAspectRatio=false)));
    end InitialInsulinContent;

    model VolumeConstant
      parameter Type.Volume k;

      Type.VolumeOutput volume annotation (Placement(transformation(extent={{-340,
                -26},{-320,-6}}), iconTransformation(extent={{100,-10},{120,10}})));

    equation
      volume=k;
      annotation (Icon(coordinateSystem(preserveAspectRatio=false), graphics={
              Rectangle(
              extent={{-100,40},{100,-42}},
              lineColor={28,108,200},
              lineThickness=1), Text(
              extent={{-124,-56},{128,-76}},
              textColor={28,108,200},
              textString="%name"),
            Text(
              extent={{-144,24},{144,-26}},
              textColor={28,108,200},
              textString="%k")}),    Diagram(coordinateSystem(preserveAspectRatio=false)));
    end VolumeConstant;
  end Components;

  package Tests
    model CompartmentTest
      Components.Compartment insulinCompartment(initialMass(displayUnit="kg") = 0.056
          *0.0347*1e-9)
        annotation (Placement(transformation(extent={{-8,-48},{30,-10}})));
      Components.ToInsulinUI toInsulinUI
        annotation (Placement(transformation(extent={{36,-92},{56,-72}})));
      Components.VolumeConstant volumeConstant(k=0.001)
        annotation (Placement(transformation(extent={{-116,-22},{-60,36}})));
      Components.ToInsulinUIConcentration toInsulinUIConcentration
        annotation (Placement(transformation(extent={{60,-38},{80,-18}})));
    equation
      connect(toInsulinUI.massInput, insulinCompartment.massOutput)
        annotation (Line(points={{35,-82},{11,-82},{11,-46.48}},
                                                              color={0,0,0}));
      connect(insulinCompartment.volumeInput, volumeConstant.volume)
        annotation (Line(points={{-8,-28.62},{-48,-28.62},{-48,7},{-57.2,7}},
            color={0,0,0}));
      connect(insulinCompartment.massConcentrationOutput,
        toInsulinUIConcentration.massConcentrationInput) annotation (Line(
            points={{30.38,-28.62},{44.69,-28.62},{44.69,-28},{59,-28}}, color=
              {0,0,0}));
      annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
            coordinateSystem(preserveAspectRatio=false)));
    end CompartmentTest;
  end Tests;
  annotation (uses(Modelica(version="4.0.0"), Metabolism(version="1")));
end GlucoseInsulinRegulator;
