Automatic flow addition to Chilled water pipes

Revit has a default flow parameter to the terminal units where if the flow is added to the units it gets transferred to the pipes. Sometimes it is not possible or may produce wrong values due to some reasons:-

  1. If the connector flow settings in the families such as flow configuration, Loss method, etc are incorrect.

  2. If the connector flow setting in the pipe fitting is incorrect.

  3. Incorrect pipe accessories used.

  4. The cumulative flow in the pipes may not be accurate and to resolve this fittings have to be disconnected and connected again.

The script does the following:-
The video shows the automatic addition of flow from mechanical units to the pipes and pipe fittings. As shown there are 16 mechanical units connected in the network and each is assigned a flow of 0.5 L/s. The integrated flow is automatically added to the following pipes upstream and the sum flow in the end pipe is 8 L/s (16*0.5). The pipe and pipe fittings are set with the respective flows and there is nothing to be changed or edited to the families or fittings used in the project.

import clr
import math

clr.AddReference('DSCoreNodes')
from DSCore import *

clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *


import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

import sys
sys.path.append(r'C:\Program Files (x86)\IronPython 2.7\Lib')

# Import RevitAPI
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

# Import ToDSType(bool) extension method
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)

from collections import defaultdict
#The inputs to this node will be stored as a list in the IN variables.

clr.AddReference('DSCoreNodes')
from DSCore import *


# Enable Python support and load DesignScript library

import clr
import math

clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

clr.AddReference('DSCoreNodes')
from DSCore import *





import clr
import sys
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB.Electrical import*

clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.AddReference('DSCoreNodes')
from DSCore.List import Flatten



import sys
pyt_path = r'C:\Program Files (x86)\IronPython 2.7\Lib'
sys.path.append(pyt_path)

#for Using  C# List 
import System
from System.Collections.Generic import*

clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument

clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)

import collections

uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application
uidoc = uiapp.ActiveUIDocument

#The inputs to this node will be stored as a list in the IN variables.
if isinstance(IN[0],list):
	connector = UnwrapElement(IN[0])
	toggle = 0
else:
	connector = [UnwrapElement(IN[0])]
	toggle = 1
	
bool = IN[1]

def nextElements(elem):
	listout = []
	if elem.GetType() == Connector:
		conn = elem
		for c in conn.AllRefs:
			if c.Owner.Id.Equals(elem.Owner.Id):
				continue
			elif isinstance(c.Owner,MEPSystem):
				continue
			else:
				newelem = c.Owner
			listout.append(newelem)
		return listout
	try:
		connectors = elem.ConnectorManager.Connectors
	except:
		connectors = elem.MEPModel.ConnectorManager.Connectors
	for conn in connectors:
		for c in conn.AllRefs:			
			if c.Owner.Id.Equals(elem.Id):
				continue
			elif isinstance(c.Owner,MEPSystem):
				continue
			elif c.Owner.Id.Equals(ownerId):
				continue
			else:
				newelem = c.Owner
			listout.append(newelem)
	return listout
	
def nextElementsWithOwner(elem):
	listout = []
	if elem.GetType() == Connector:
		conn = elem
		for c in conn.AllRefs:
			if c.Owner.Id.Equals(elem.Owner.Id):
				continue
			elif isinstance(c.Owner,MEPSystem):
				continue
			else:
				newelem = c.Owner
			listout.append(newelem)
		return listout
	try:
		connectors = elem.ConnectorManager.Connectors
	except:
		connectors = elem.MEPModel.ConnectorManager.Connectors
	for conn in connectors:
		for c in conn.AllRefs:			
			if c.Owner.Id.Equals(elem.Id):
				continue
			elif isinstance(c.Owner,MEPSystem):
				continue
			else:
				newelem = c.Owner
			listout.append(newelem)
	return listout	
	
def collector(elem):
	cont = 0
	elements = nextElements(elem)
	for x in elements:
		if x.Id in lookup:
			cont += 1
		else:
			item = doc.GetElement(x.Id)

			lookup[x.Id] = item
			collector(x)
	if cont == len(elements):
		return elem
		
def collectorWithOwner(elem):
	cont = 0
	elements = nextElementsWithOwner(elem)
	for x in elements:
		if x.Id in lookup:
			cont += 1
		else:
			item = doc.GetElement(x.Id)

			lookup[x.Id] = item
			collectorWithOwner(x)
	if cont == len(elements):
		return elem
		
listout = []		
if bool:
	for x in connector:
		lookup = collections.OrderedDict()
		collectorWithOwner(x)
		listout.append(lookup.Values)
else:
	for x in connector:
		lookup = collections.OrderedDict()
		if x.GetType() == Connector:
			ownerId = x.Owner.Id
		else:
			ownerId = x.Id
		collector(x)
		listout.append(lookup.Values)

#Assign your output to the OUT variable.
if toggle:
	OUT = values = lookup.Values
else:
	OUT = values = listout
	
#System classification rule filter
Sys_rule = ParameterFilterRuleFactory.CreateContainsRule(ElementId(-1140325),"Hydronic Supply",True)

#C list for filters
Filters = List[FilterRule]()
Filters.Add(Sys_rule)

# Parameter Filer
param_filter =ElementParameterFilter(Filters)

# Adding elements to csharp list
elementIds = List[ElementId]()
for value in values:
	elementIds.Add(value.Id)
	
# Filtering on the existing element list
Fec_Elements = FilteredElementCollector(doc,elementIds).WherePasses(param_filter).ToElements()

#The inputs to this node will be stored as a list in the IN variables.

def Find_Connection_Between_Elements(All_Elements_Of_Category):
	p = []
	dir = []
	rep = []
	ref = []
	
	#elements = List.Flatten(elements,2)
	
	for e in All_Elements_Of_Category:
		refs = []
	
		try:
			connectors = e.MEPModel.ConnectorManager.Connectors
		except:
			connectors = e.ConnectorManager.Connectors
		for conn in connectors:
			for c in conn.AllRefs:
				connectortype = str(c.ConnectorType)
				if connectortype == "End":
					refs.append(c.Owner)
		ref.append(refs)
	
	#Assign your output to the OUT variable.
	
	return ref
def Find_Connectors(elementlist):	
	if isinstance(elementlist, list):
		elements = elementlist
		toggle = 0
	else:
		toggle = 1
		elements = elementlist
		

	listout = []

	for element in elements:
		try:
			connectors = element.MEPModel.ConnectorManager.Connectors
		except:
			try:
				connectors = element.ConnectorManager.Connectors
			except:			
				connectors = []
		listout.append([x for x in connectors])
	#Assign your output to the OUT variable.
	if toggle:
		return listout
	else:
		return connectors
		
connected = Find_Connectors(Fec_Elements)

def Unwrap(item):
	return UnwrapElement(item)
	
def ProcessList(_func, _list):
    return map(lambda x: ProcessList(_func, x) if type(x)==list else _func(x), _list)

if isinstance(connected, list):
	connectors = ProcessList(Unwrap, connected)
else:
	connectors = [Unwrap(connected)]
	
def IsConnected(connector):
	bool = False
	try:
		bool = connector.IsConnected
	except:
		pass
	return bool
booleans = ProcessList(IsConnected, connectors)
filtered_list = []
for c,b in zip(connected,booleans):
        filterted = []
        for a,d in zip(c,b):
            if d:
            	sys = a.MEPSystem.Name
            	if "CHWS" in sys:
                	filterted.append(a)
            	else:
                	continue  
        filtered_list.append(filterted)

def getConnSysType(connector):
	systype = None
	try:
		sys = connector.MEPSystem
		systype = doc.GetElement(sys.GetTypeId())
	except:
		pass
	return systype
def getAllRefs(connector):
	refs = None
	try:
		refs = [doc.GetElement(x.Owner.Id) for x in connector.AllRefs if x.Owner.Id != connector.Owner.Id and x.ConnectorType != ConnectorType.Logical]
	except:
		pass
	if type(refs)==list:
		if refs == []:
			return None
		else:
			return refs[0]
	else:
		return refs

def elementcategory(elements):
	elementlist = []
	for element in elements:
		categorylist = []
		for item in element:
			try:
				categorylist.append(item.Category.Name)
			except:
				categorylist.append(None)
		elementlist.append(categorylist)
	return elementlist			
#Assign your output to the OUT variable.
#connected_elements = Find_Connection_Between_Elements(Fec_Elements)
connected_elements  = ProcessList(getAllRefs,filtered_list)
for  elements in connected_elements:
	lg = len(elements)
	if lg ==1:
		dex = connected_elements.index(elements)
		ele = Fec_Elements[dex]
		ki = elements.insert(0,ele)
		
final = []
for connected_element in connected_elements:
	if len(connected_element)>1:
		final.append(connected_element)
	
elements_category = elementcategory(final)


for item,category in zip(final, elements_category):
	pos = elements_category.index(category)
	index_size = len(category)
	if index_size == 2:
		cont = category.count("Pipe Fittings")
		if cont ==2:
			del final[pos]
			del elements_category[pos]
			del Fec_Elements[pos]

		
		if f_e_name == "Pipe":
			continue
		else:
			type_id = f_e.GetTypeId()
			ele_type = doc.GetElement(type_id)
			ele_fam = ele_type.Family
			ele_name = ele_fam.Name
			if "Tee" in ele_name:
				fe_index = final_element.index(f_e)
				fe_insert = final_element[fe_index] = fec_element 

final = []
for connected_element in connected_elements:
	if len(connected_element)>1:
		final.append(connected_element)
		
def setvalues(list1):
	elements = []
	elementids = []
	idvalues = []
	
	for l1 in list1:
		list2=[]
		list3 = []
		list4 = []
		for el in l1:
			element = UnwrapElement(el)
			elementid = element.Id
			elementvalue = elementid.IntegerValue
			list2.append(element)
			list3.append(elementid)
			list4.append(elementvalue)
		elements.append(list2)
		elementids.append(list3)
		idvalues.append(list4)
	m=1
	length = len(elements)
	
	while m <length:
		rest = []
		for el,ids,val in zip(elements,elementids,idvalues):
			boolean = []
			empty = []	
			indexes = []
			index_values =[]
			size = len(el)
			if size == 3:
				for j,k,l in zip(el,ids,val):
					param= j.LookupParameter("flow")
					param_value = param.AsDouble()
					if param_value==0:
						boolean.append(True)
						index = val.index(l)
						index_value = el[index].LookupParameter("flow").AsDouble()
						indexes.append(index)
						index_values.append(index_value)
					else:
						boolean.append(False)
						index = val.index(l)
						index_value = el[index].LookupParameter("flow").AsDouble()
						indexes.append(index)
						index_values.append(index_value)			
				count = boolean.count(False)
				if count ==2:
					values = []
					for b,id,v,v1 in zip(boolean,indexes,index_values,el):
						if b==False:
							values.append(v)
							value = sum(values)
						else:
							n = id
					p_value = el[n].LookupParameter("flow").Set(value)
					rest.append(el)			
				elif count ==1 or count==0:
					rest.append(el)
					continue
			elif size==2:
				for j,k,l in zip(el,ids,val):
					param= j.LookupParameter("flow")
					param_value = param.AsDouble()
					if param_value==0:
						boolean.append(True)
						index = val.index(l)
						index_value = el[index].LookupParameter("flow").AsDouble()
						indexes.append(index)
						index_values.append(index_value)
					else:
						boolean.append(False)
						index = val.index(l)
						index_value = el[index].LookupParameter("flow").AsDouble()
						indexes.append(index)
						index_values.append(index_value)			
				count = boolean.count(False)
				if count ==1:
					values = []
					for b,id,v,v1 in zip(boolean,indexes,index_values,el):
						if b==False:
							values.append(v)
							value = sum(values)
						else:
							n = id
					p_value = el[n].LookupParameter("flow").Set(value)
					rest.append(el)			
				elif count ==0:
					rest.append(el)
					continue
			elif size==4:
				for idx,j in enumerate(el):
					param= j.LookupParameter("flow")
					param_value = param.AsDouble()
					if param_value==0:
						boolean.append(True)
						index = idx
						index_value = el[index].LookupParameter("flow").AsDouble()
						indexes.append(index)
						index_values.append(index_value)
					else:
						boolean.append(False)
						index = idx
						index_value = el[index].LookupParameter("flow").AsDouble()
						indexes.append(index)
						index_values.append(index_value)			
				count = boolean.count(False)
				if count ==1:
					values = []
					for b,id,v,v1 in zip(boolean,indexes,index_values,el):
						if b==False:
							values.append(v)
							value = v
						else:
							n = id
							p_value = el[n].LookupParameter("flow").Set(value)
					rest.append(el)			
				elif count ==0:
					rest.append(el)
					continue
			elif size==1:
				continue			
		m = m+1						
	return elements
		

TransactionManager.Instance.EnsureInTransaction(doc)
setelements = setvalues(final)
cat_list = [BuiltInCategory.OST_PipeFitting, BuiltInCategory.OST_PipeAccessory]
typed_list = List[BuiltInCategory](cat_listdef elementcategory(elements):
	elementlist = []
	for element in elements:
		categorylist = []
		for item in element:
			try:
				categorylist.append(item.Category.Name)
			except:
				categorylist.append(None)
		elementlist.append(categorylist)
	return elementlist)
filter = ElementMulticategoryFilter(typed_list)
#Catfilter = ElementCategoryFilter(ElementId(-2008049))
catlist = List[ElementId]()
for Fec_Element in Fec_Elements:
	catlist.Add(Fec_Element.Id)
Cat_Filtered= FilteredElementCollector(doc,catlist).WherePasses(filter).ToElements()
Cat_Filtered_connectors = Find_Connectors(Cat_Filtered)
Cat_Filtered_connected = ProcessList(getAllRefs,Cat_Filtered_connectors)

	
#for f,c in zip(Cat_Filtered,Cat_Filtered_connected):
TransactionManager.Instance.TransactionTaskDone()			


for l1,l2 in zip(Fec_Elements,connected_elements):
    for l3 in l2:
        if l1.Id == l3.Id:
            l2.remove(l3) 
for  elements in connected_elements:
	lg = len(elements)
	if lg ==1:
		dex = connected_elements.index(elements)
		ele = Fec_Elements[dex]
		ki = elements.insert(0,ele)

OUT = Fec_Elements,final

3 Likes

Hi Chandu
I have seen your post and i am very happy with your output , could you please attach the Dynamo script and/or a video.
I am facing a similar issue and it will be great to see your solution.

Regards

@CHANDU
tag