public static ConnectorProfileType ConnectorProfileType(this MEPCurve mEPCurve) { if (mEPCurve == null) { return(Autodesk.Revit.DB.ConnectorProfileType.Invalid); } ConnectorSet connectorSet = mEPCurve?.ConnectorManager?.Connectors; if (connectorSet == null) { return(Autodesk.Revit.DB.ConnectorProfileType.Invalid); } foreach (Connector connector in connectorSet) { ConnectorProfileType result = connector.Shape; if (result != Autodesk.Revit.DB.ConnectorProfileType.Invalid) { return(result); } } return(Autodesk.Revit.DB.ConnectorProfileType.Invalid); }
/// <summary> /// Calculate the area of the duct. /// </summary> /// <param name="eShape"> /// The profile type of the duct. /// </param> /// <param name="dWidthOrDiameter"> /// The diameter of duct with round profile, or the width of the duct with other profiles, Units: (ft). /// </param> /// <param name="dHeight"> /// The height of the duct, Units: (ft). /// </param> /// <returns> /// The area of the duct, Units: (ft²). /// </returns> private double Area(ConnectorProfileType eShape, double dWidthOrDiameter, double dHeight) { double dArea = 0.0; if (eShape == ConnectorProfileType.Round) { dArea = Math.PI * dWidthOrDiameter * dWidthOrDiameter / 4.0; } else if (eShape == ConnectorProfileType.Rectangular) { dArea = dWidthOrDiameter * dHeight; } else if (eShape == ConnectorProfileType.Oval) { double dA; double dB; if (dWidthOrDiameter - dHeight > 0.0) { dA = dWidthOrDiameter; dB = dHeight; } else { dA = dHeight; dB = dWidthOrDiameter; } dArea = (Math.PI * dB * dB / 4.0) + dB * (dA - dB); } return(dArea); }
/// <summary> /// Return dimension for this connector: /// diameter if round, else height. /// </summary> static double GetConnectorDim(Connector c) { ConnectorProfileType shape = c.Shape; return(ConnectorProfileType.Round == shape ? 2 * c.Radius : c.Height); }
const double twoInches = 1.0 / 6.0; // two twelfths of a foot is a sixth /// <summary> /// Return dimension for this duct: /// diameter if round, else height. /// </summary> static double GetDuctDim(Duct d) { ConnectorProfileType shape = d.DuctType.Shape; return(ConnectorProfileType.Round == shape ? d.Diameter : d.Height); }
/// <summary> /// Return dimension for this duct: /// diameter if round, else height. /// </summary> static double GetDuctDim( Duct d, ConnectorProfileType shape) { return(ConnectorProfileType.Round == shape ? d.Diameter : d.Height); }
/// <summary> /// Calculate the duct pressure drop with the input data. /// </summary> /// <param name="data"> /// The input for the pressure drop calculation. The output are also returned through the data to the caller. /// </param> public void Calculate(DuctPressureDropData data) { ConnectorProfileType eShape = data.Shape; SystemCalculationLevel eLevel = data.Level; double dWidthOrDiameter = data.WidthOrDiameter; double dHeight = data.Height; double dHydraulicDiameter = 0.0; double dEquivalentDiameter = 0.0; double dVelocity = 0.0; double dVelocityPressure = 0.0; double dReynoldsNumber = 0.0; double dPressureDrop = 0.0; double dFriction = 0.0; double dCoefficient = 0.0; dHydraulicDiameter = HydraulicDiameter(eShape, dWidthOrDiameter, dHeight); dEquivalentDiameter = EquivalentDiameter(eShape, dWidthOrDiameter, dHeight); if (eLevel != SystemCalculationLevel.None) { double dDensity = data.Density; double dViscosity = data.Viscosity; dVelocity = Velocity(eShape, dWidthOrDiameter, dHeight, data.Flow); dVelocityPressure = VelocityPressure(dVelocity, dDensity); dReynoldsNumber = ReynoldsNumber(dHydraulicDiameter, dVelocity, dViscosity); if (eLevel == SystemCalculationLevel.All) { double dLength = data.Length; double dFrictionFactor = AltshulTsalFrictionFactor(dHydraulicDiameter, data.Roughness, dReynoldsNumber); dPressureDrop = PressureDrop(dHydraulicDiameter, dFrictionFactor, dDensity, dVelocity, dLength); if (!AlmostZero(dLength)) { dFriction = dPressureDrop / dLength; // Friction is the pressure drop at the unit length. } if (!AlmostZero(dVelocityPressure)) { dCoefficient = dPressureDrop / dVelocityPressure; } } } data.HydraulicDiameter = dHydraulicDiameter; data.EquivalentDiameter = dEquivalentDiameter; data.Velocity = dVelocity; data.VelocityPressure = dVelocityPressure; data.ReynoldsNumber = dReynoldsNumber; data.Friction = dFriction; data.PressureDrop = dPressureDrop; data.Coefficient = dCoefficient; }
/// <summary> /// Calculate the velocity of the duct. /// </summary> /// <param name="eShape"> /// The profile type of the duct. /// </param> /// <param name="dWidthOrDiameter"> /// The diameter of duct with round profile, or the width of the duct with other profiles, Units: (ft). /// </param> /// <param name="dHeight"> /// The height of the duct, Units: (ft). /// </param> /// <param name="dFlow"> /// The flow of the duct, Units:(ft³/s). /// </param> /// <returns> /// The velocity of the duct, Units:(ft/s). /// </returns> private double Velocity(ConnectorProfileType eShape, double dWidthOrDiameter, double dHeight, double dFlow) { double dVelocity = 0.0; double dArea = Area(eShape, dWidthOrDiameter, dHeight); if (!AlmostZero(dArea)) { dVelocity = System.Math.Abs(dFlow) / dArea; } return(dVelocity); }
/// <summary> /// Return shape of first end connector on given duct. /// </summary> static ConnectorProfileType GetShape(Duct duct) { ConnectorProfileType ductShape = ConnectorProfileType.Invalid; foreach (Connector c in duct.ConnectorManager.Connectors) { if (c.ConnectorType == ConnectorType.End) { ductShape = c.Shape; break; } } return(ductShape); }
/// <summary> /// Calculate the hydraulic diameter of the duct. /// </summary> /// <param name="eShape"> /// The profile type of the duct. /// </param> /// <param name="dWidthOrDiameter"> /// The diameter of duct with round profile, or the width of the duct with other profiles, Units: (ft). /// </param> /// <param name="dHeight"> /// The height of the duct, Units: (ft). /// </param> /// <returns> /// The hydraulic diameter of the duct, Units: (ft). /// </returns> private double HydraulicDiameter(ConnectorProfileType eShape, double dWidthOrDiameter, double dHeight) { double dHydraulicDiameter = dWidthOrDiameter; if (eShape == ConnectorProfileType.Oval) { double dA; double dB; if (dWidthOrDiameter - dHeight > 0.0) { dA = dWidthOrDiameter; dB = dHeight; } else { dA = dHeight; dB = dWidthOrDiameter; } double dArea = (Math.PI * dB * dB / 4.0) + dB * (dA - dB); double dP = Math.PI * dB + 2.0 * (dA - dB); if (!AlmostZero(dP)) { dHydraulicDiameter = 4.0 * dArea / dP; } else { dHydraulicDiameter = 0.0; } } else if (eShape == ConnectorProfileType.Rectangular) { double dPerimeter = dWidthOrDiameter + dHeight; if (AlmostZero(dPerimeter)) { dHydraulicDiameter = 0.0; } else { dHydraulicDiameter = 2.0 * dWidthOrDiameter * dHeight / dPerimeter; } } return(dHydraulicDiameter); }
/// <summary> /// Calculate the equivalent diameter of the duct. /// </summary> /// <param name="eShape"> /// The profile type of the duct. /// </param> /// <param name="dWidthOrDiameter"> /// The diameter of duct with round profile, or the width of the duct with other profiles, Units: (ft). /// </param> /// <param name="dHeight"> /// The height of the duct, Units: (ft). /// </param> /// <returns> /// The equivalent diameter of the duct, Units: (ft). /// </returns> double EquivalentDiameter(ConnectorProfileType eShape, double dWidthOrDiameter, double dHeight) { double dEqDiameter = dWidthOrDiameter; if (AlmostZero(dWidthOrDiameter + dHeight)) { return(dEqDiameter); } if (dWidthOrDiameter + dHeight < 0.0) { return(0.0); } if (eShape == ConnectorProfileType.Oval) { if (!AlmostEqual(dWidthOrDiameter, dHeight)) { double dA; double dB; if (dWidthOrDiameter - dHeight > 0.0) { dA = dWidthOrDiameter; dB = dHeight; } else { dA = dHeight; dB = dWidthOrDiameter; } double dArea = (Math.PI * dB * dB / 4.0) + dB * (dA - dB); double dP = Math.PI * dB + 2.0 * (dA - dB); dEqDiameter = 1.55 * Math.Pow(dArea, 0.625) / Math.Pow(dP, 0.250); } } else if (eShape == ConnectorProfileType.Rectangular) { dEqDiameter = 1.3 * Math.Pow(dWidthOrDiameter * dHeight, 0.625) / Math.Pow(dWidthOrDiameter + dHeight, 0.250); } return(dEqDiameter); }
/// <summary> /// Return shape of all duct connectors. /// </summary> static ConnectorProfileType[] GetProfileTypes( Duct duct) { ConnectorSet connectors = duct.ConnectorManager.Connectors; int n = connectors.Size; ConnectorProfileType[] profileTypes = new ConnectorProfileType[n]; int i = 0; foreach (Connector c in connectors) { profileTypes[i++] = c.Shape; } return(profileTypes); }
const double twoInches = 1.0 / 6.0; // two twelfths of a foot is a sixth /// <summary> /// Return shape of this duct, retrieved /// from its first or first two connectors. /// </summary> static ConnectorProfileType GetDuctShape(Duct d) { // According to Jared, DuctType.Shape is unreliable: //ConnectorProfileType shape = d.DuctType.Shape; Debug.Assert(null != d.ConnectorManager, "expected a valid connector manager on a duct"); ConnectorSet cons = d.ConnectorManager.Connectors; Debug.Assert(null != cons, "expected valid connectors on a duct"); Debug.Assert(2 <= cons.Size, "expected at least two connectors on a duct"); ConnectorProfileType shape = ConnectorProfileType.Invalid; foreach (Connector c in cons) { #if DEBUG if (ConnectorProfileType.Invalid != shape) { Debug.Assert(shape == c.Shape, "expected same shape on first two duct connectors"); break; } #endif // DEBUG shape = c.Shape; Debug.Assert(ConnectorProfileType.Invalid != shape, "expected valid shape on first two duct connectors"); #if !DEBUG break; #endif // DEBUG } return(shape); }
/// <summary> /// Resize ducts to ensure that branch ducts are no /// larger than the main duct they are tapping into. /// </summary> void DuctResize(Document doc) { FilteredElementCollector ductCollector = new FilteredElementCollector(doc) .OfClass(typeof(Duct)); using (Transaction transaction = new Transaction(doc)) { if (transaction.Start("Resize Ducts for Taps") == TransactionStatus.Started) { int i = 0; foreach (Duct d in ductCollector) { ConnectorProfileType shape = GetDuctShape(d); ConnectorSet dctCnnctrs = d.ConnectorManager.Connectors; int nDCs = dctCnnctrs.Size; if (nDCs < 3) { // do nothing } else { double ductDim = GetDuctDim(d, shape); double largestConnector = 0.0; foreach (Connector c in dctCnnctrs) { if (c.ConnectorType.ToString().Equals("End")) { // Do nothing because I am not // interested in the "End" Connectors } else { ConnectorSet taps = c.AllRefs; double maxTapDim = 0.0; foreach (Connector cd in taps) { double tapDim = GetConnectorDim(cd); if (maxTapDim < tapDim) { maxTapDim = tapDim; } } if (largestConnector < maxTapDim) { largestConnector = maxTapDim; } } } if (largestConnector > ductDim) { double updatedHeight = largestConnector + twoInches; // Use duct shape vaiable here instead of // checking parameter for null? Parameter ductHeight = d.get_Parameter(bipHeight) ?? d.get_Parameter(bipDiameter); double oldHeight = ductHeight.AsDouble(); if (!Util.IsEqual(oldHeight, updatedHeight)) { ductHeight.Set(updatedHeight); ++i; } } } } // Ask the end user whether the // changes are to be committed or not TaskDialog taskDialog = new TaskDialog( "Resize Ducts"); TaskDialogCommonButtons buttons; if (0 < i) { int n = ductCollector.GetElementCount(); taskDialog.MainContent = i + " out of " + n.ToString() + " ducts will be re-sized." + "\n\nClick [OK] to Commit or [Cancel] " + "to Roll back the transaction."; buttons = TaskDialogCommonButtons.Ok | TaskDialogCommonButtons.Cancel; } else { taskDialog.MainContent = "None of the ducts need to be re-sized."; buttons = TaskDialogCommonButtons.Ok; } taskDialog.CommonButtons = buttons; if (TaskDialogResult.Ok == taskDialog.Show() && 0 < i) { // For many various reasons, a transaction may not be committed // if the changes made during the transaction do not result a valid model. // If committing a transaction fails or is canceled by the end user, // the resulting status would be RolledBack instead of Committed. if (TransactionStatus.Committed != transaction.Commit()) { TaskDialog.Show("Failure", "Transaction could not be committed"); } } // No need to roll back, just do not call Commit //else //{ // transaction.RollBack(); //} } } }
/// <summary> /// Calculate the equivalent diameter of the duct. /// </summary> /// <param name="eShape"> /// The profile type of the duct. /// </param> /// <param name="dWidthOrDiameter"> /// The diameter of duct with round profile, or the width of the duct with other profiles, Units: (ft). /// </param> /// <param name="dHeight"> /// The height of the duct, Units: (ft). /// </param> /// <returns> /// The equivalent diameter of the duct, Units: (ft). /// </returns> double EquivalentDiameter( ConnectorProfileType eShape, double dWidthOrDiameter, double dHeight ) { double dEqDiameter = dWidthOrDiameter; if( AlmostZero( dWidthOrDiameter + dHeight ) ) return dEqDiameter; if( dWidthOrDiameter + dHeight < 0.0 ) return 0.0; if( eShape == ConnectorProfileType.Oval ) { if( !AlmostEqual( dWidthOrDiameter, dHeight ) ) { double dA; double dB; if( dWidthOrDiameter - dHeight > 0.0 ) { dA = dWidthOrDiameter; dB = dHeight; } else { dA = dHeight; dB = dWidthOrDiameter; } double dArea = ( Math.PI * dB * dB / 4.0 ) + dB * ( dA - dB ); double dP = Math.PI * dB + 2.0 * ( dA - dB ); dEqDiameter = 1.55 * Math.Pow( dArea, 0.625 ) / Math.Pow( dP, 0.250 ); } } else if( eShape == ConnectorProfileType.Rectangular ) dEqDiameter = 1.3 * Math.Pow( dWidthOrDiameter * dHeight, 0.625 ) / Math.Pow( dWidthOrDiameter + dHeight, 0.250 ); return dEqDiameter; }
/// <summary> /// Calculate the velocity of the duct. /// </summary> /// <param name="eShape"> /// The profile type of the duct. /// </param> /// <param name="dWidthOrDiameter"> /// The diameter of duct with round profile, or the width of the duct with other profiles, Units: (ft). /// </param> /// <param name="dHeight"> /// The height of the duct, Units: (ft). /// </param> /// <param name="dFlow"> /// The flow of the duct, Units:(ft³/s). /// </param> /// <returns> /// The velocity of the duct, Units:(ft/s). /// </returns> private double Velocity( ConnectorProfileType eShape, double dWidthOrDiameter, double dHeight, double dFlow ) { double dVelocity = 0.0; double dArea = Area( eShape, dWidthOrDiameter, dHeight ); if( !AlmostZero( dArea ) ) dVelocity = System.Math.Abs( dFlow ) / dArea; return dVelocity; }
/// <summary> /// Calculate the hydraulic diameter of the duct. /// </summary> /// <param name="eShape"> /// The profile type of the duct. /// </param> /// <param name="dWidthOrDiameter"> /// The diameter of duct with round profile, or the width of the duct with other profiles, Units: (ft). /// </param> /// <param name="dHeight"> /// The height of the duct, Units: (ft). /// </param> /// <returns> /// The hydraulic diameter of the duct, Units: (ft). /// </returns> private double HydraulicDiameter( ConnectorProfileType eShape, double dWidthOrDiameter, double dHeight ) { double dHydraulicDiameter = dWidthOrDiameter; if( eShape == ConnectorProfileType.Oval ) { double dA; double dB; if( dWidthOrDiameter - dHeight > 0.0 ) { dA = dWidthOrDiameter; dB = dHeight; } else { dA = dHeight; dB = dWidthOrDiameter; } double dArea = ( Math.PI * dB * dB / 4.0 ) + dB * ( dA - dB ); double dP = Math.PI * dB + 2.0 * ( dA - dB ); if( !AlmostZero( dP ) ) dHydraulicDiameter = 4.0 * dArea / dP; else dHydraulicDiameter = 0.0; } else if( eShape == ConnectorProfileType.Rectangular ) { double dPerimeter = dWidthOrDiameter + dHeight; if( AlmostZero( dPerimeter ) ) dHydraulicDiameter = 0.0; else dHydraulicDiameter = 2.0 * dWidthOrDiameter * dHeight / dPerimeter; } return dHydraulicDiameter; }
/// <summary> /// Resize ducts to ensure that branch ducts are no /// larger than the main duct they are tapping into. /// </summary> public void DuctResize(Document doc) { BuiltInParameter crvCharLength = BuiltInParameter.RBS_CURVE_DIAMETER_PARAM; Parameter ductHeight; double updatedHeight = 0; double twoInches = UnitUtils.Convert(2.0, DisplayUnitType.DUT_DECIMAL_INCHES, DisplayUnitType.DUT_DECIMAL_FEET); FilteredElementCollector ductCollector = new FilteredElementCollector(doc) .OfClass(typeof(Duct)); using (Transaction transaction = new Transaction(doc)) { if (transaction.Start("Resize Ducts for Taps") == TransactionStatus.Started) { int i = 0; foreach (Duct d in ductCollector) { double largestConnector = 0.0; double previous = 0.0; double cnnctrDim = 0.0; ConnectorSet dctCnnctrs = d.ConnectorManager.Connectors; int nDCs = dctCnnctrs.Size; if (nDCs < 3) { // do nothing } else { foreach (Connector c in dctCnnctrs) { if (c.ConnectorType.ToString().Equals("End")) { //Do nothing because I am not interested in the "End" Connectors } else { ConnectorSet taps = c.AllRefs; foreach (Connector cd in taps) { ConnectorProfileType cShape = cd.Shape; string shapeType = cShape.ToString(); if (shapeType.Equals("Round")) { cnnctrDim = cd.Radius * 2.0; } if (shapeType.Equals("Rectangular") || shapeType.Equals("Oval")) { cnnctrDim = cd.Height; } } if (cnnctrDim >= previous) { largestConnector = cnnctrDim; previous = largestConnector; } else { largestConnector = previous; } } } try { if (largestConnector >= d.Height) { updatedHeight = largestConnector + twoInches; i++; } else { updatedHeight = d.Height; } } catch { if (largestConnector >= d.Diameter) { updatedHeight = largestConnector + twoInches; i++; } else { updatedHeight = d.Diameter; } } try { crvCharLength = BuiltInParameter.RBS_CURVE_HEIGHT_PARAM; ductHeight = d.get_Parameter(crvCharLength); ductHeight.Set(updatedHeight); } catch (NullReferenceException) { crvCharLength = BuiltInParameter.RBS_CURVE_DIAMETER_PARAM; ductHeight = d.get_Parameter(crvCharLength); ductHeight.Set(updatedHeight); } } } // Ask the end user whether the // changes are to be committed or not TaskDialog taskDialog = new TaskDialog("Revit"); if (i > 0) { int n = (ductCollector as ICollection <Element>).Count; taskDialog.MainContent = i + " out of " + n.ToString() + " ducts will be re-sized" + "\n\nClick [OK] to Commit or [Cancel] " + "to Roll back the transaction."; } else { taskDialog.MainContent = "None of the ducts need to be re-sized" + "\n\nClick [OK] to Commit or [Cancel] " + "to Roll back the transaction."; } TaskDialogCommonButtons buttons = TaskDialogCommonButtons.Ok | TaskDialogCommonButtons.Cancel; taskDialog.CommonButtons = buttons; if (TaskDialogResult.Ok == taskDialog.Show()) { // For many various reasons, a transaction may not be committed // if the changes made during the transaction do not result a valid model. // If committing a transaction fails or is canceled by the end user, // the resulting status would be RolledBack instead of Committed. if (TransactionStatus.Committed != transaction.Commit()) { TaskDialog.Show("Failure", "Transaction could not be committed"); } } else { transaction.RollBack(); } } } }
/// <summary> /// Calculate the area of the duct. /// </summary> /// <param name="eShape"> /// The profile type of the duct. /// </param> /// <param name="dWidthOrDiameter"> /// The diameter of duct with round profile, or the width of the duct with other profiles, Units: (ft). /// </param> /// <param name="dHeight"> /// The height of the duct, Units: (ft). /// </param> /// <returns> /// The area of the duct, Units: (ft²). /// </returns> private double Area( ConnectorProfileType eShape, double dWidthOrDiameter, double dHeight ) { double dArea = 0.0; if( eShape == ConnectorProfileType.Round ) dArea = Math.PI * dWidthOrDiameter * dWidthOrDiameter / 4.0; else if( eShape == ConnectorProfileType.Rectangular ) dArea = dWidthOrDiameter * dHeight; else if( eShape == ConnectorProfileType.Oval ) { double dA; double dB; if( dWidthOrDiameter - dHeight > 0.0 ) { dA = dWidthOrDiameter; dB = dHeight; } else { dA = dHeight; dB = dWidthOrDiameter; } dArea = ( Math.PI * dB * dB / 4.0 ) + dB * ( dA - dB ); } return dArea; }