Пример #1
0
        /// <summary>
        /// Processes an IfcDerivedUnit.
        /// </summary>
        /// <param name="unitHnd">The unit handle.</param>
        void ProcessIFCDerivedUnit(IFCAnyHandle unitHnd)
        {
            List <IFCAnyHandle> elements =
                IFCAnyHandleUtil.GetAggregateInstanceAttribute <List <IFCAnyHandle> >(unitHnd, "Elements");

            IList <KeyValuePair <IFCUnit, int> > derivedElementUnitHnds = new List <KeyValuePair <IFCUnit, int> >();

            foreach (IFCAnyHandle subElement in elements)
            {
                IFCAnyHandle derivedElementUnitHnd = IFCImportHandleUtil.GetRequiredInstanceAttribute(subElement, "Unit", false);
                IFCUnit      subUnit = IFCAnyHandleUtil.IsNullOrHasNoValue(derivedElementUnitHnd) ? null : IFCUnit.ProcessIFCUnit(derivedElementUnitHnd);
                if (subUnit != null)
                {
                    bool found;
                    int  exponent = IFCImportHandleUtil.GetRequiredIntegerAttribute(subElement, "Exponent", out found);
                    if (found)
                    {
                        derivedElementUnitHnds.Add(new KeyValuePair <IFCUnit, int>(subUnit, exponent));
                    }
                }
            }

            // the DerivedUnitExpectedTypes object is a description of one possible set of base units for a particular derived unit.
            // The IList allows for possible different interpretations.  For example, Volumetric Flow Rate could be defined by m^3/s (length ^ 3 / time) or L/s (volume / time).
            IList <DerivedUnitExpectedTypes> expectedTypesList = new List <DerivedUnitExpectedTypes>();

            string unitType = IFCAnyHandleUtil.GetEnumerationAttribute(unitHnd, "UnitType");

            if (string.Compare(unitType, "LINEARVELOCITYUNIT", true) == 0)
            {
                Spec       = SpecTypeId.HvacVelocity;
                UnitSystem = UnitSystem.Metric;

                // Support only m / s.
                DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.MetersPerSecond, SymbolTypeId.MPerS);
                expectedTypes.AddExpectedType(1, SpecTypeId.Length);
                expectedTypes.AddCustomExpectedType(-1, "TIMEUNIT");
                expectedTypesList.Add(expectedTypes);
            }
            else if (string.Compare(unitType, "THERMALTRANSMITTANCEUNIT", true) == 0)
            {
                Spec       = SpecTypeId.HeatTransferCoefficient;
                UnitSystem = UnitSystem.Metric;

                // Support W / (K * m^2) or kg / (K * s^3)
                DerivedUnitExpectedTypes expectedTypesWinvKinvM2 = new DerivedUnitExpectedTypes(UnitTypeId.WattsPerSquareMeterKelvin, SymbolTypeId.WPerMSup2K);
                expectedTypesWinvKinvM2.AddExpectedType(1, SpecTypeId.HvacPower); // UT_Electrical_Wattage is similar, but UT_HVAC_Power is the one we map to.
                expectedTypesWinvKinvM2.AddExpectedType(-1, SpecTypeId.HvacTemperature);
                expectedTypesWinvKinvM2.AddExpectedType(-2, SpecTypeId.Length);
                expectedTypesList.Add(expectedTypesWinvKinvM2);

                DerivedUnitExpectedTypes expectedTypesWinvKinvArea = new DerivedUnitExpectedTypes(UnitTypeId.WattsPerSquareMeterKelvin, SymbolTypeId.WPerMSup2K);
                expectedTypesWinvKinvArea.AddExpectedType(1, SpecTypeId.HvacPower); // UT_Electrical_Wattage is similar, but UT_HVAC_Power is the one we map to.
                expectedTypesWinvKinvArea.AddExpectedType(-1, SpecTypeId.HvacTemperature);
                expectedTypesWinvKinvArea.AddExpectedType(-1, SpecTypeId.Area);
                expectedTypesList.Add(expectedTypesWinvKinvArea);

                DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.WattsPerSquareMeterKelvin, SymbolTypeId.WPerMSup2K);
                expectedTypes.AddExpectedType(1, SpecTypeId.Mass);
                expectedTypes.AddExpectedType(-1, SpecTypeId.HvacTemperature);
                expectedTypes.AddCustomExpectedType(-3, "TIMEUNIT");
                expectedTypesList.Add(expectedTypes);
            }
            else if (string.Compare(unitType, "VOLUMETRICFLOWRATEUNIT", true) == 0)
            {
                Spec       = SpecTypeId.AirFlow;
                UnitSystem = UnitSystem.Metric;

                // Support L / s or m^3 / s in the IFC file.

                // L / s
                DerivedUnitExpectedTypes expectedTypesLPerS = new DerivedUnitExpectedTypes(UnitTypeId.LitersPerSecond, SymbolTypeId.LPerS);
                expectedTypesLPerS.AddExpectedType(1, SpecTypeId.Volume);
                expectedTypesLPerS.AddCustomExpectedType(-1, "TIMEUNIT");
                expectedTypesList.Add(expectedTypesLPerS);

                // m^3 / s.
                DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.CubicMetersPerSecond, SymbolTypeId.MSup3PerS);
                expectedTypes.AddExpectedType(3, SpecTypeId.Length);
                expectedTypes.AddCustomExpectedType(-1, "TIMEUNIT");
                expectedTypesList.Add(expectedTypes);
            }
            else if (string.Compare(unitType, "MASSDENSITYUNIT", true) == 0)
            {
                Spec       = SpecTypeId.MassDensity;
                UnitSystem = UnitSystem.Metric;

                // Support kg / m^3 in the IFC file.

                // kg / m^3.
                DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.KilogramsPerCubicMeter, SymbolTypeId.KgPerMSup3);
                expectedTypes.AddExpectedType(1, SpecTypeId.Mass);
                expectedTypes.AddExpectedType(-3, SpecTypeId.Length);
                expectedTypesList.Add(expectedTypes);
            }
            else if (string.Compare(unitType, "LINEARFORCEUNIT", true) == 0)
            {
                Spec       = SpecTypeId.LinearForce;
                UnitSystem = UnitSystem.Metric;

                // Support N / m in the IFC file.
                DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.NewtonsPerMeter, SymbolTypeId.NPerM);
                expectedTypes.AddExpectedType(1, SpecTypeId.LinearForce);
                expectedTypesList.Add(expectedTypes);

                // Support N / m in basic units
                DerivedUnitExpectedTypes expectedTypes2 = new DerivedUnitExpectedTypes(UnitTypeId.NewtonsPerMeter, SymbolTypeId.NPerM);
                expectedTypes2.AddExpectedType(1, SpecTypeId.Mass);
                expectedTypes2.AddExpectedType(1, SpecTypeId.Length);
                expectedTypes2.AddCustomExpectedType(-2, "TIMEUNIT");
                expectedTypes2.AddExpectedType(-1, SpecTypeId.Length);
                expectedTypesList.Add(expectedTypes2);
            }
            else if (string.Compare(unitType, "PLANARFORCEUNIT", true) == 0)
            {
                Spec       = SpecTypeId.AreaForce;
                UnitSystem = UnitSystem.Metric;

                // Support N / m^2 in the IFC file.
                DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.NewtonsPerSquareMeter, SymbolTypeId.NPerMSup2);
                expectedTypes.AddExpectedType(1, SpecTypeId.AreaForce);
                expectedTypesList.Add(expectedTypes);

                // Support N / m in basic units
                DerivedUnitExpectedTypes expectedTypes2 = new DerivedUnitExpectedTypes(UnitTypeId.NewtonsPerSquareMeter, SymbolTypeId.NPerMSup2);
                expectedTypes2.AddExpectedType(1, SpecTypeId.Mass);
                expectedTypes2.AddExpectedType(1, SpecTypeId.Length);
                expectedTypes2.AddCustomExpectedType(-2, "TIMEUNIT");
                expectedTypes2.AddExpectedType(-2, SpecTypeId.Length);
                expectedTypesList.Add(expectedTypes2);
            }
            else if (string.Compare(unitType, "USERDEFINED", true) == 0)
            {
                // Look at the sub-types to see what we support.
                string userDefinedType = IFCImportHandleUtil.GetOptionalStringAttribute(unitHnd, "UserDefinedType", null);
                if (!string.IsNullOrWhiteSpace(userDefinedType))
                {
                    if (string.Compare(userDefinedType, "Luminous Efficacy", true) == 0)
                    {
                        Spec       = SpecTypeId.Efficacy;
                        UnitSystem = UnitSystem.Metric;

                        // Support only lm / W.
                        DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.LumensPerWatt, SymbolTypeId.LmPerW);
                        expectedTypes.AddExpectedType(-1, SpecTypeId.Mass);
                        expectedTypes.AddExpectedType(-2, SpecTypeId.Length);
                        expectedTypes.AddCustomExpectedType(3, "TIMEUNIT");
                        expectedTypes.AddExpectedType(1, SpecTypeId.LuminousFlux);
                        expectedTypesList.Add(expectedTypes);
                    }
                    else if (string.Compare(userDefinedType, "Friction Loss", true) == 0)
                    {
                        Spec       = SpecTypeId.HvacFriction;
                        UnitSystem = UnitSystem.Metric;

                        // Support only Pa / m.
                        DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitTypeId.PascalsPerMeter, SymbolTypeId.PaPerM);
                        expectedTypes.AddExpectedType(-2, SpecTypeId.Length);
                        expectedTypes.AddExpectedType(1, SpecTypeId.Mass);
                        expectedTypes.AddCustomExpectedType(-2, "TIMEUNIT");
                        expectedTypesList.Add(expectedTypes);
                    }
                }
            }

            foreach (DerivedUnitExpectedTypes derivedUnitExpectedTypes in expectedTypesList)
            {
                double scaleFactor = 1.0;
                if (derivedUnitExpectedTypes.Matches(derivedElementUnitHnds, out scaleFactor))
                {
                    // Found a match.
                    Unit        = derivedUnitExpectedTypes.Unit;
                    Symbol      = derivedUnitExpectedTypes.Symbol;
                    ScaleFactor = scaleFactor;
                    return;
                }
            }

            Importer.TheLog.LogUnhandledUnitTypeError(unitHnd, unitType);
        }
Пример #2
0
        /// <summary>
        /// Processes an IfcDerivedUnit.
        /// </summary>
        /// <param name="unitHnd">The unit handle.</param>
        void ProcessIFCDerivedUnit(IFCAnyHandle unitHnd)
        {
            List <IFCAnyHandle> elements =
                IFCAnyHandleUtil.GetAggregateInstanceAttribute <List <IFCAnyHandle> >(unitHnd, "Elements");

            IList <KeyValuePair <IFCUnit, int> > derivedElementUnitHnds = new List <KeyValuePair <IFCUnit, int> >();

            foreach (IFCAnyHandle subElement in elements)
            {
                IFCAnyHandle derivedElementUnitHnd = IFCImportHandleUtil.GetRequiredInstanceAttribute(subElement, "Unit", false);
                IFCUnit      subUnit = IFCAnyHandleUtil.IsNullOrHasNoValue(derivedElementUnitHnd) ? null : IFCUnit.ProcessIFCUnit(derivedElementUnitHnd);
                if (subUnit != null)
                {
                    bool found;
                    int  exponent = IFCImportHandleUtil.GetRequiredIntegerAttribute(subElement, "Exponent", out found);
                    if (found)
                    {
                        derivedElementUnitHnds.Add(new KeyValuePair <IFCUnit, int>(subUnit, exponent));
                    }
                }
            }

            // the DerivedUnitExpectedTypes object is a description of one possible set of base units for a particular derived unit.
            // The IList allows for possible different interpretations.  For example, Volumetric Flow Rate could be defined by m^3/s (length ^ 3 / time) or L/s (volume / time).
            IList <DerivedUnitExpectedTypes> expectedTypesList = new List <DerivedUnitExpectedTypes>();

            string unitType = IFCAnyHandleUtil.GetEnumerationAttribute(unitHnd, "UnitType");

            if (string.Compare(unitType, "LINEARVELOCITYUNIT", true) == 0)
            {
                UnitType   = UnitType.UT_HVAC_Velocity;
                UnitSystem = UnitSystem.Metric;

                // Support only m / s.
                DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitName.DUT_METERS_PER_SECOND, UnitSymbolType.UST_M_PER_S);
                expectedTypes.AddExpectedType(1, UnitType.UT_Length);
                expectedTypes.AddCustomExpectedType(-1, "TIMEUNIT");
                expectedTypesList.Add(expectedTypes);
            }
            else if (string.Compare(unitType, "THERMALTRANSMITTANCEUNIT", true) == 0)
            {
                UnitType   = UnitType.UT_HVAC_CoefficientOfHeatTransfer;
                UnitSystem = UnitSystem.Metric;

                // Support W / (K * m^2) or kg / (K * s^3)
                DerivedUnitExpectedTypes expectedTypesWinvKinvM2 = new DerivedUnitExpectedTypes(UnitName.DUT_WATTS_PER_SQUARE_METER_KELVIN, UnitSymbolType.UST_WATT_PER_SQ_M_K);
                expectedTypesWinvKinvM2.AddExpectedType(1, UnitType.UT_HVAC_Power); // UT_Electrical_Wattage is similar, but UT_HVAC_Power is the one we map to.
                expectedTypesWinvKinvM2.AddExpectedType(-1, UnitType.UT_HVAC_Temperature);
                expectedTypesWinvKinvM2.AddExpectedType(-2, UnitType.UT_Length);
                expectedTypesList.Add(expectedTypesWinvKinvM2);

                DerivedUnitExpectedTypes expectedTypesWinvKinvArea = new DerivedUnitExpectedTypes(UnitName.DUT_WATTS_PER_SQUARE_METER_KELVIN, UnitSymbolType.UST_WATT_PER_SQ_M_K);
                expectedTypesWinvKinvArea.AddExpectedType(1, UnitType.UT_HVAC_Power); // UT_Electrical_Wattage is similar, but UT_HVAC_Power is the one we map to.
                expectedTypesWinvKinvArea.AddExpectedType(-1, UnitType.UT_HVAC_Temperature);
                expectedTypesWinvKinvArea.AddExpectedType(-1, UnitType.UT_Area);
                expectedTypesList.Add(expectedTypesWinvKinvArea);

                DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitName.DUT_WATTS_PER_SQUARE_METER_KELVIN, UnitSymbolType.UST_WATT_PER_SQ_M_K);
                expectedTypes.AddExpectedType(1, UnitType.UT_Mass);
                expectedTypes.AddExpectedType(-1, UnitType.UT_HVAC_Temperature);
                expectedTypes.AddCustomExpectedType(-3, "TIMEUNIT");
                expectedTypesList.Add(expectedTypes);
            }
            else if (string.Compare(unitType, "VOLUMETRICFLOWRATEUNIT", true) == 0)
            {
                UnitType   = UnitType.UT_HVAC_Airflow;
                UnitSystem = UnitSystem.Metric;

                // Support L / s or m^3 / s in the IFC file.

                // L / s
                DerivedUnitExpectedTypes expectedTypesLPerS = new DerivedUnitExpectedTypes(UnitName.DUT_LITERS_PER_SECOND, UnitSymbolType.UST_L_PER_S);
                expectedTypesLPerS.AddExpectedType(1, UnitType.UT_Volume);
                expectedTypesLPerS.AddCustomExpectedType(-1, "TIMEUNIT");
                expectedTypesList.Add(expectedTypesLPerS);

                // m^3 / s.
                DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitName.DUT_CUBIC_METERS_PER_SECOND, UnitSymbolType.UST_CU_M_PER_S);
                expectedTypes.AddExpectedType(3, UnitType.UT_Length);
                expectedTypes.AddCustomExpectedType(-1, "TIMEUNIT");
                expectedTypesList.Add(expectedTypes);
            }
            else if (string.Compare(unitType, "MASSDENSITYUNIT", true) == 0)
            {
                UnitType   = UnitType.UT_MassDensity;
                UnitSystem = UnitSystem.Metric;

                // Support kg / m^3 in the IFC file.

                // kg / m^3.
                DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitName.DUT_KILOGRAMS_PER_CUBIC_METER, UnitSymbolType.UST_KG_PER_CU_M);
                expectedTypes.AddExpectedType(1, UnitType.UT_Mass);
                expectedTypes.AddExpectedType(-3, UnitType.UT_Length);
                expectedTypesList.Add(expectedTypes);
            }
            else if (string.Compare(unitType, "USERDEFINED", true) == 0)
            {
                // Look at the sub-types to see what we support.
                string userDefinedType = IFCImportHandleUtil.GetOptionalStringAttribute(unitHnd, "UserDefinedType", null);
                if (!string.IsNullOrWhiteSpace(userDefinedType))
                {
                    if (string.Compare(userDefinedType, "Luminous Efficacy", true) == 0)
                    {
                        UnitType   = UnitType.UT_Electrical_Efficacy;
                        UnitSystem = UnitSystem.Metric;

                        // Support only lm / W.
                        DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitName.DUT_LUMENS_PER_WATT, UnitSymbolType.UST_LM_PER_W);
                        expectedTypes.AddExpectedType(-1, UnitType.UT_Mass);
                        expectedTypes.AddExpectedType(-2, UnitType.UT_Length);
                        expectedTypes.AddCustomExpectedType(3, "TIMEUNIT");
                        expectedTypes.AddExpectedType(1, UnitType.UT_Electrical_Luminous_Flux);
                        expectedTypesList.Add(expectedTypes);
                    }
                    else if (string.Compare(userDefinedType, "Friction Loss", true) == 0)
                    {
                        UnitType   = UnitType.UT_HVAC_Friction;
                        UnitSystem = UnitSystem.Metric;

                        // Support only Pa / m.
                        DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitName.DUT_PASCALS_PER_METER, UnitSymbolType.UST_PASCAL_PER_M);
                        expectedTypes.AddExpectedType(-2, UnitType.UT_Length);
                        expectedTypes.AddExpectedType(1, UnitType.UT_Mass);
                        expectedTypes.AddCustomExpectedType(-2, "TIMEUNIT");
                        expectedTypesList.Add(expectedTypes);
                    }
                }
            }

            foreach (DerivedUnitExpectedTypes derivedUnitExpectedTypes in expectedTypesList)
            {
                double scaleFactor = 1.0;
                if (derivedUnitExpectedTypes.Matches(derivedElementUnitHnds, out scaleFactor))
                {
                    // Found a match.
                    UnitName    = derivedUnitExpectedTypes.UnitName;
                    UnitSymbol  = derivedUnitExpectedTypes.UnitSymbol;
                    ScaleFactor = scaleFactor;
                    return;
                }
            }

            Importer.TheLog.LogUnhandledUnitTypeError(unitHnd, unitType);
        }
Пример #3
0
        /// <summary>
        /// Processes an IfcDerivedUnit.
        /// </summary>
        /// <param name="unitHnd">The unit handle.</param>
        void ProcessIFCDerivedUnit(IFCAnyHandle unitHnd)
        {
           List<IFCAnyHandle> elements =
               IFCAnyHandleUtil.GetAggregateInstanceAttribute<List<IFCAnyHandle>>(unitHnd, "Elements");

           IList<KeyValuePair<IFCUnit, int>> derivedElementUnitHnds = new List<KeyValuePair<IFCUnit, int>>();
           foreach (IFCAnyHandle subElement in elements)
           {
              IFCAnyHandle derivedElementUnitHnd = IFCImportHandleUtil.GetRequiredInstanceAttribute(subElement, "Unit", false);
              IFCUnit subUnit = IFCAnyHandleUtil.IsNullOrHasNoValue(derivedElementUnitHnd) ? null : IFCUnit.ProcessIFCUnit(derivedElementUnitHnd);
              if (subUnit != null)
              {
                 bool found;
                 int exponent = IFCImportHandleUtil.GetRequiredIntegerAttribute(subElement, "Exponent", out found);
                 if (found)
                    derivedElementUnitHnds.Add(new KeyValuePair<IFCUnit, int>(subUnit, exponent));
              }
           }

           // the DerivedUnitExpectedTypes object is a description of one possible set of base units for a particular derived unit.
           // The IList allows for possible different interpretations.  For example, Volumetric Flow Rate could be defined by m^3/s (length ^ 3 / time) or L/s (volume / time).
           IList<DerivedUnitExpectedTypes> expectedTypesList = new List<DerivedUnitExpectedTypes>();
           
           string unitType = IFCAnyHandleUtil.GetEnumerationAttribute(unitHnd, "UnitType");
           if (string.Compare(unitType, "LINEARVELOCITYUNIT", true) == 0)
           {
              UnitType = UnitType.UT_HVAC_Velocity;
              UnitSystem = UnitSystem.Metric;

              // Support only m / s.
              DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitName.DUT_METERS_PER_SECOND, UnitSymbolType.UST_M_PER_S);
              expectedTypes.AddExpectedType(1, UnitType.UT_Length);
              expectedTypes.AddCustomExpectedType(-1, "TIMEUNIT");
              expectedTypesList.Add(expectedTypes);
           }
           else if (string.Compare(unitType, "THERMALTRANSMITTANCEUNIT", true) == 0)
           {
              UnitType = UnitType.UT_HVAC_CoefficientOfHeatTransfer;
              UnitSystem = UnitSystem.Metric;

              // Support W / (K * m^2) or kg / (K * s^3)
              DerivedUnitExpectedTypes expectedTypesWinvKinvM2 = new DerivedUnitExpectedTypes(UnitName.DUT_WATTS_PER_SQUARE_METER_KELVIN, UnitSymbolType.UST_WATT_PER_SQ_M_K);
              expectedTypesWinvKinvM2.AddExpectedType(1, UnitType.UT_HVAC_Power); // UT_Electrical_Wattage is similar, but UT_HVAC_Power is the one we map to.
              expectedTypesWinvKinvM2.AddExpectedType(-1, UnitType.UT_HVAC_Temperature);
              expectedTypesWinvKinvM2.AddExpectedType(-2, UnitType.UT_Length);
              expectedTypesList.Add(expectedTypesWinvKinvM2);

              DerivedUnitExpectedTypes expectedTypesWinvKinvArea = new DerivedUnitExpectedTypes(UnitName.DUT_WATTS_PER_SQUARE_METER_KELVIN, UnitSymbolType.UST_WATT_PER_SQ_M_K);
              expectedTypesWinvKinvArea.AddExpectedType(1, UnitType.UT_HVAC_Power); // UT_Electrical_Wattage is similar, but UT_HVAC_Power is the one we map to.
              expectedTypesWinvKinvArea.AddExpectedType(-1, UnitType.UT_HVAC_Temperature);
              expectedTypesWinvKinvArea.AddExpectedType(-1, UnitType.UT_Area);
              expectedTypesList.Add(expectedTypesWinvKinvArea); 
              
              DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitName.DUT_WATTS_PER_SQUARE_METER_KELVIN, UnitSymbolType.UST_WATT_PER_SQ_M_K);
              expectedTypes.AddExpectedType(1, UnitType.UT_Mass);
              expectedTypes.AddExpectedType(-1, UnitType.UT_HVAC_Temperature);
              expectedTypes.AddCustomExpectedType(-3, "TIMEUNIT");
              expectedTypesList.Add(expectedTypes);
           }
           else if (string.Compare(unitType, "VOLUMETRICFLOWRATEUNIT", true) == 0)
           {
              UnitType = UnitType.UT_HVAC_Airflow;
              UnitSystem = UnitSystem.Metric;

              // Support L / s or m^3 / s in the IFC file.
         
              // L / s
              DerivedUnitExpectedTypes expectedTypesLPerS = new DerivedUnitExpectedTypes(UnitName.DUT_LITERS_PER_SECOND, UnitSymbolType.UST_L_PER_S);
              expectedTypesLPerS.AddExpectedType(1, UnitType.UT_Volume);
              expectedTypesLPerS.AddCustomExpectedType(-1, "TIMEUNIT");
              expectedTypesList.Add(expectedTypesLPerS);

              // m^3 / s.
              DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitName.DUT_CUBIC_METERS_PER_SECOND, UnitSymbolType.UST_CU_M_PER_S);
              expectedTypes.AddExpectedType(3, UnitType.UT_Length);
              expectedTypes.AddCustomExpectedType(-1, "TIMEUNIT");
              expectedTypesList.Add(expectedTypes);
           }
           else if (string.Compare(unitType, "USERDEFINED", true) == 0)
           {
              // Look at the sub-types to see what we support.
              string userDefinedType = IFCImportHandleUtil.GetOptionalStringAttribute(unitHnd, "UserDefinedType", null);
              if (!string.IsNullOrWhiteSpace(userDefinedType))
              {
                 if (string.Compare(userDefinedType, "Luminous Efficacy", true) == 0)
                 {
                    UnitType = UnitType.UT_Electrical_Efficacy;
                    UnitSystem = UnitSystem.Metric;

                    // Support only lm / W.
                    DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitName.DUT_LUMENS_PER_WATT, UnitSymbolType.UST_LM_PER_W);
                    expectedTypes.AddExpectedType(-1, UnitType.UT_Mass);
                    expectedTypes.AddExpectedType(-2, UnitType.UT_Length);
                    expectedTypes.AddCustomExpectedType(3, "TIMEUNIT");
                    expectedTypes.AddExpectedType(1, UnitType.UT_Electrical_Luminous_Flux);
                    expectedTypesList.Add(expectedTypes);
                 }
                 else if (string.Compare(userDefinedType, "Friction Loss", true) == 0)
                 {
                    UnitType = UnitType.UT_HVAC_Friction;
                    UnitSystem = UnitSystem.Metric;

                    // Support only Pa / m.
                    DerivedUnitExpectedTypes expectedTypes = new DerivedUnitExpectedTypes(UnitName.DUT_PASCALS_PER_METER, UnitSymbolType.UST_PASCAL_PER_M);
                    expectedTypes.AddExpectedType(-2, UnitType.UT_Length);
                    expectedTypes.AddExpectedType(1, UnitType.UT_Mass);
                    expectedTypes.AddCustomExpectedType(-2, "TIMEUNIT");
                    expectedTypesList.Add(expectedTypes);
                 }
              }
           }

           foreach (DerivedUnitExpectedTypes derivedUnitExpectedTypes in expectedTypesList)
           {
              double scaleFactor = 1.0;
              if (derivedUnitExpectedTypes.Matches(derivedElementUnitHnds, out scaleFactor))
              {
                 // Found a match.
                 UnitName = derivedUnitExpectedTypes.UnitName;
                 UnitSymbol = derivedUnitExpectedTypes.UnitSymbol;
                 ScaleFactor = scaleFactor;
                 return;
              }
           }

           Importer.TheLog.LogUnhandledUnitTypeError(unitHnd, unitType);
        }