<?xml version="1.0" encoding="UTF-8"?>
<!--
**************************************************************************

Beagle Pup Icing (JSBSim)

Copyright (c) 2016 Richard Senior

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.

This program 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 General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

**************************************************************************
-->

<system name="Icing">

  <property value="0">/systems/electrical/outputs/pitot-heater</property>
  <property value="0">/systems/pitot/total-pressure-inhg</property>

  <channel name="Carburettor">

    <!-- Temperature -->

    <!--
    Continental engines have the carburettor mounted away from the
    heat of the engine and are prone to carb icing, whereas the
    Lycoming engines fitted to the Pup 150 and 160 have the
    carburettor mounted close to the engine, which keeps it warm.
    Values are no more than wild guesses.
    -->
    <switch name="systems/carburettor/compartment-coefficient">
      <default value="10"/>
      <test value="5">
        propulsion/engine/manufacturer-code EQ 0
      </test>
    </switch>

    <fcs_function name="systems/carburettor/compartment-effect-degC">
      <function>
        <product>
          <quotient>
            <property>propulsion/engine/cht-degC</property>
            <value>260</value> <!-- Max CHT -->
          </quotient>
          <table>
            <!-- Compartment heat buildup at low airspeeds -->
            <independentVar lookup="row">velocities/vt-fps</independentVar>
            <tableData>
                0 4.0
               25 2.0
               50 1.0
            </tableData>
          </table>
          <property>systems/carburettor/compartment-coefficient</property>
        </product>
      </function>
    </fcs_function>

    <fcs_function name="systems/carburettor/venturi-effect-degC">
      <function>
        <product>
          <difference>
            <property>/engines/engine/mp-inhg</property>
            <property>/environment/pressure-inhg</property>
          </difference>
          <quotient>
            <value>20</value>   <!-- Max temp drop ~ 70*F -->
            <difference>
              <value>29.5</value> <!-- Max MP -->
              <value>8.5</value>  <!-- Min MP -->
            </difference>
          </quotient>
        </product>
      </function>
      <clipto>
        <min>-20.0</min>
        <max>0.0</max>
      </clipto>
    </fcs_function>

    <fcs_function name="systems/carburettor/carb-heat-effect-degC">
      <function>
        <product>
          <quotient>
            <property>propulsion/engine/egt-degC</property>
            <value>860</value> <!-- Max EGT -->
          </quotient>
          <value>30</value>
          <property>/controls/anti-ice/engine/carb-heat-norm</property>
        </product>
      </function>
      <clipto>
        <min>0.0</min>
        <max>30.0</max>
      </clipto>
    </fcs_function>

    <summer name="systems/carburettor/carb-temp-target-degC">
      <input>systems/carburettor/carb-heat-effect-degC</input>
      <input>systems/carburettor/compartment-effect-degC</input>
      <input>systems/carburettor/venturi-effect-degC</input>
      <input>/environment/temperature-degc</input>
    </summer>

    <fcs_function name="systems/carburettor/carb-temp-degC">
      <function>
        <sum>
          <property>systems/carburettor/carb-temp-degC</property>
          <quotient>
            <difference>
              <property>systems/carburettor/carb-temp-target-degC</property>
              <property>systems/carburettor/carb-temp-degC</property>
            </difference>
            <product>
              <value>60</value>
              <value>120</value>
            </product>
          </quotient>
        </sum>
      </function>
    </fcs_function>

    <!-- Icing -->

    <switch name="systems/carburettor/icing-phase">
      <!-- Ice thawing if present -->
      <default value="0"/>
      <test logic="AND" value="1">
        <!-- Ice not forming, but not thawing -->
        /sim/model/preferences/realism/carb-ice NE 0
        systems/carburettor/carb-temp-degC LE 0.0
        systems/carburettor/carb-temp-degC GT /environment/dewpoint-degc
      </test>
      <test logic="AND" value="2">
        <!-- Ice forming -->
        /sim/model/preferences/realism/carb-ice NE 0
        systems/carburettor/carb-temp-degC LE 0.0
        systems/carburettor/carb-temp-degC LE /environment/dewpoint-degc
      </test>
    </switch>

    <switch name="systems/carburettor/icing-delta">
      <default value="0"/>
      <test logic="AND" value="systems/carburettor/carb-temp-degC">
        /sim/model/preferences/realism/carb-ice NE 0
        systems/carburettor/icing-phase NE 1
      </test>
    </switch>

    <fcs_function name="systems/carburettor/carb-ice-norm">
      <function>
        <sum>
          <property>systems/carburettor/carb-ice-norm</property>
          <quotient>
            <product>
              <property>systems/carburettor/icing-delta</property>
              <value>-1.0</value>
            </product>
            <product>
              <value>300</value>
              <value>120</value>
            </product>
          </quotient>
        </sum>
      </function>
      <clipto>
        <min>0.0</min>
        <max>1.0</max>
      </clipto>
    </fcs_function>

    <!-- Air Intake Impedance -->

    <pure_gain name="Intake Impedance">
      <input>systems/carburettor/carb-ice-norm</input>
      <output>propulsion/engine/air-intake-impedance-factor</output>
      <gain>20.0</gain>
      <clipto>
        <min>0.05</min> <!-- Should match engine definition -->
        <max>20.0</max>
      </clipto>
    </pure_gain>

    <!--
    Adding hot air to the carburettor effectively leans the mixture and
    reduces RPM and power. Model this by modifying the efficiency. RPM
    drop at full carb heat should be around 100rpm, less so with the
    mixture leaned.
    -->
    <fcs_function name="Volumetric Efficiency">
      <function>
        <difference>
          <value>0.89</value> <!-- Base volumetric efficiency -->
          <product>
            <property>systems/carburettor/carb-heat-effect-degC</property>
            <value>0.0035</value>
            <table>
              <independentVar lookup="row">propulsion/engine/egt-degC</independentVar>
              <tableData>
                  0 1.0
                780 1.0
                860 0.0
              </tableData>
            </table>
          </product>
        </difference>
      </function>
      <output>propulsion/engine/volumetric-efficiency</output>
    </fcs_function>

  </channel>

  <channel name="Pitot">

    <!-- Temperature -->

    <switch name="systems/pitot/pitot-heat-effect-degC">
      <default value="0"/>
      <test value="30">
        /systems/electrical/outputs/pitot-heater GT 0.0
      </test>
    </switch>

    <summer name="systems/pitot/pitot-temp-target-degC">
      <input>systems/pitot/pitot-heat-effect-degC</input>
      <input>/environment/temperature-degc</input>
    </summer>

    <fcs_function name="systems/pitot/pitot-temp-degC">
      <function>
        <sum>
          <property>systems/pitot/pitot-temp-degC</property>
          <quotient>
            <difference>
              <property>systems/pitot/pitot-temp-target-degC</property>
              <property>systems/pitot/pitot-temp-degC</property>
            </difference>
            <product>
              <value>60</value>
              <value>120</value>
            </product>
          </quotient>
        </sum>
      </function>
    </fcs_function>

    <switch name="systems/pitot/icing-phase">
      <!-- Ice thawing if present -->
      <default value="0"/>
      <test logic="AND" value="1">
        <!-- Ice not forming, but not thawing -->
        /sim/model/preferences/realism/pitot-ice NE 0
        systems/pitot/pitot-temp-degC LE 0.0
        systems/pitot/pitot-temp-degC GT /environment/dewpoint-degc
      </test>
      <test logic="AND" value="2">
        <!-- Ice forming -->
        /sim/model/preferences/realism/pitot-ice NE 0
        systems/pitot/pitot-temp-degC LE 0.0
        systems/pitot/pitot-temp-degC LE /environment/dewpoint-degc
      </test>
    </switch>

    <switch name="systems/pitot/icing-delta">
      <default value="0"/>
      <test logic="AND" value="systems/pitot/pitot-temp-degC">
        /sim/model/preferences/realism/pitot-ice NE 0
        systems/pitot/icing-phase NE 1
      </test>
    </switch>

    <fcs_function name="systems/pitot/pitot-ice-norm">
      <function>
        <sum>
          <property>systems/pitot/pitot-ice-norm</property>
          <quotient>
            <product>
              <property>systems/pitot/icing-delta</property>
              <value>-1.0</value>
            </product>
            <product>
              <value>600</value>
              <value>120</value>
            </product>
          </quotient>
        </sum>
      </function>
      <clipto>
        <min>0.0</min>
        <max>1.0</max>
      </clipto>
    </fcs_function>

    <!-- Apply a linear impedance to the pressure measured by the pitot system.
         The dymamic pressure is constantly calculated but the reported
         pressure may stick if the tube is blocked. See below. -->
    <fcs_function name="systems/pitot/total-pressure-inhg-dynamic">
      <function>
        <difference>
          <property>/systems/pitot/total-pressure-inhg</property>
          <product>
            <property>systems/pitot/pitot-ice-norm</property>
            <value>0.33</value>
          </product>
        </difference>
      </function>
    </fcs_function>

    <!-- If the water drain hole and the port are both blocked by ice,
         the pressure reported by the pitot system sticks at whatever
         pressure it was at when blocked.
    -->
    <switch name="systems/pitot/total-pressure-inhg">
      <default value="systems/pitot/total-pressure-inhg-dynamic"/>
      <test value="systems/pitot/total-pressure-inhg">
        systems/pitot/pitot-ice-norm EQ 1.0
      </test>
    </switch>

  </channel>

</system>
