ooking for an efficient way to perform glazing of complex shapes.
I've only followed the Energy modelling workshops so far so i may have missed some essential components or workflows to achieve my needs. But i've made an attached definition with all my current attempts to get a proper HBzone with the numerous windows faces i will always have to deal with in this project.
I first thought that i was not using the HBObjWGZ correctly, then after some readings it was maybe an upgrading issue, then effectively i had my Therm 7.5 that needed to be reinstaled, but then ... I must be missing an essential HB tricks or workflow i guess ...
So I divided my attempt in two series :
- The Serie 1 : is a simplier version of the project step i'm working on but i'd be glad to achieve it first !
- The Serie 2 : is the real final direction of the project, which consist in sorting/dispatch faces to windowon one side and to an other material on the other, according to the winter sun and a pourcentage param.
Despite it is more complicated than the Serie one, it seems seems to create the same diversity of issues.
Until now, with the 5 different combinations of Serie 1, and the 3 of Serie 2, with and without using the different Glazing/window components, here are the logs i got from both HBZone component or OpenStudio component:
From OpenStudio - "1. The simulation has not run correctly because of this severe error: ** Severe ** BuildingSurface:Detailed="00073E23257843B6A948", invalid Construction Name="ETFE" - has Window materials.">> Has to deal with the way i'm trying to assign too early a customized EPConstruction material ? Done it wrong ? I tried to reload it in the library but doesn't change anything...
From OpenStudio - "1. The simulation has not run correctly because of this severe error: ** Severe ** BuildingSurface:Detailed="000579CD749E46DFA5EA", invalid Construction Name="EXTERIOR WINDOW" - has Window materials.">> Is it an issue in the way i define my surfs both as "WINDOW" (5) for srfType and Outdoors on the same component ?
From Create HBZone -"1. Solution exception:'EPZone' object has no attribute 'shdCntrlZoneInstructs'"
>> Happens when i try to introduce my ETFE EpMaterial after creating my first HBZone, with a Set EP Zone Construction, so this material seems to be not working either before and after trying to create an HB Zone
From Create HBZone- "1. Solution exception: 73df51a3b2144b1e858b has been moved, scaled or rotated."If you need to move or rotate a Honeybee object you should use Honeybee move, rotate or mirror components. You can find them under 12|WIP tab.
>> >> wich seems to exist in some on other thread Here and was a coding bug supposed to be fixed.
And last but not least ...
From OpenStudio - "1. The simulation has not run correctly because of this severe error: ** Severe ** checkSubSurfAzTiltNorm: Outward facing angle of subsurface differs more than 90.0 degrees from base surface.2. The simulation has failed because of this fatal error: ** Fatal ** GetSurfaceData: Errors discovered, program terminates" .
I'm attaching the file with each attempt in this post. The definitions are disabled and the log already copied separatly so there is no need to compute each of them to see what's wrong.
If someone from the beginner to one of the Kings of HoneyBee has any relevant answer/solution to this attempt with complex geometry Issue it will be really nice for me so i could to move forward !!
Thanks in advance guys and have a great day !
…
The PC actually stops working because after a few seconds the simulation starts the fan inside the PC all of a sudden stops and for the next 5-10 mins I cannot do anything, even alt+ctrl+canc. After I wait for that time i get the followig error:
the ReadMe says:
{0;0;0}0. Grid-based Radiance simulation1. The component is checking ad, as, ar and aa values. This is just to make sure that the results are accurate enough.2. -ar is set to 300.3. Good to go!4. Current working directory is set to: C:\Users\Luigi\Desktop\Prova__\Prova_1\gridBasedSimulation\5. Found a trans material... Resetting st parameter from 0.85 to 0.011276004966. WMIC PROCESS get Commandline7. WMIC PROCESS get Commandline8. WMIC PROCESS get Commandline9. WMIC PROCESS get Commandline10. WMIC PROCESS get Commandline11. WMIC PROCESS get Commandline12. WMIC PROCESS get Commandline13. WMIC PROCESS get Commandline14. WMIC PROCESS get Commandline15. WMIC PROCESS get Commandline16. WMIC PROCESS get Commandline17. WMIC PROCESS get Commandline18. WMIC PROCESS get Commandline19. WMIC PROCESS get Commandline20. WMIC PROCESS get Commandline21. WMIC PROCESS get Commandline22. WMIC PROCESS get Commandline23. WMIC PROCESS get Commandline24. WMIC PROCESS get Commandline25. WMIC PROCESS get Commandline26. WMIC PROCESS get Commandline27. WMIC PROCESS get Commandline28. WMIC PROCESS get Commandline29. WMIC PROCESS get Commandline30. WMIC PROCESS get Commandline31. WMIC PROCESS get Commandline32. WMIC PROCESS get Commandline33. WMIC PROCESS get Commandline34. WMIC PROCESS get Commandline35. WMIC PROCESS get Commandline36. WMIC PROCESS get Commandline37. WMIC PROCESS get Commandline38. WMIC PROCESS get Commandline39. WMIC PROCESS get Commandline40. WMIC PROCESS get Commandline41. WMIC PROCESS get Commandline42. WMIC PROCESS get Commandline43. WMIC PROCESS get Commandline44. WMIC PROCESS get Commandline45. WMIC PROCESS get Commandline46. WMIC PROCESS get Commandline47. WMIC PROCESS get Commandline48. WMIC PROCESS get Commandline49. WMIC PROCESS get Commandline50. WMIC PROCESS get Commandline51. WMIC PROCESS get Commandline52. WMIC PROCESS get Commandline53. WMIC PROCESS get Commandline54. WMIC PROCESS get Commandline55. WMIC PROCESS get Commandline56. WMIC PROCESS get Commandline57. WMIC PROCESS get Commandline58. WMIC PROCESS get Commandline59. WMIC PROCESS get Commandline60. WMIC PROCESS get Commandline61. WMIC PROCESS get Commandline62. WMIC PROCESS get Commandline63. WMIC PROCESS get Commandline64. WMIC PROCESS get Commandline65. WMIC PROCESS get Commandline66. WMIC PROCESS get Commandline67. WMIC PROCESS get Commandline68. WMIC PROCESS get Commandline69. WMIC PROCESS get Commandline70. WMIC PROCESS get Commandline71. WMIC PROCESS get Commandline72. WMIC PROCESS get Commandline73. WMIC PROCESS get Commandline74. WMIC PROCESS get Commandline75. WMIC PROCESS get Commandline76. WMIC PROCESS get Commandline77. WMIC PROCESS get Commandline78. WMIC PROCESS get Commandline79. WMIC PROCESS get Commandline80. WMIC PROCESS get Commandline81. WMIC PROCESS get Commandline82. WMIC PROCESS get Commandline83. WMIC PROCESS get Commandline84. WMIC PROCESS get Commandline85. WMIC PROCESS get Commandline86. WMIC PROCESS get Commandline87. WMIC PROCESS get Commandline88. WMIC PROCESS get Commandline89. WMIC PROCESS get Commandline90. WMIC PROCESS get Commandline91. WMIC PROCESS get Commandline92. WMIC PROCESS get Commandline93. WMIC PROCESS get Commandline94. WMIC PROCESS get Commandline95. WMIC PROCESS get Commandline96. WMIC PROCESS get Commandline97. WMIC PROCESS get Commandline98. WMIC PROCESS get Commandline99. WMIC PROCESS get Commandline100. WMIC PROCESS get Commandline101. WMIC PROCESS get Commandline102. WMIC PROCESS get Commandline103. WMIC PROCESS get Commandline104. WMIC PROCESS get Commandline105. WMIC PROCESS get Commandline106. WMIC PROCESS get Commandline107. WMIC PROCESS get Commandline108. WMIC PROCESS get Commandline109. WMIC PROCESS get Commandline110. WMIC PROCESS get Commandline111. WMIC PROCESS get Commandline112. WMIC PROCESS get Commandline113. WMIC PROCESS get Commandline114. WMIC PROCESS get Commandline115. WMIC PROCESS get Commandline116. WMIC PROCESS get Commandline117. WMIC PROCESS get Commandline118. WMIC PROCESS get Commandline119. WMIC PROCESS get Commandline120. WMIC PROCESS get Commandline121. WMIC PROCESS get Commandline122. WMIC PROCESS get Commandline123. WMIC PROCESS get Commandline124. WMIC PROCESS get Commandline125. WMIC PROCESS get Commandline126. WMIC PROCESS get Commandline127. WMIC PROCESS get Commandline128. WMIC PROCESS get Commandline129. WMIC PROCESS get Commandline130. WMIC PROCESS get Commandline131. WMIC PROCESS get Commandline132. WMIC PROCESS get Commandline133. WMIC PROCESS get Commandline134. WMIC PROCESS get Commandline135. WMIC PROCESS get Commandline136. WMIC PROCESS get Commandline137. WMIC PROCESS get Commandline138. WMIC PROCESS get Commandline139. WMIC PROCESS get Commandline140. WMIC PROCESS get Commandline141. WMIC PROCESS get Commandline142. WMIC PROCESS get Commandline143. WMIC PROCESS get Commandline144. WMIC PROCESS get Commandline145. WMIC PROCESS get Commandline146. WMIC PROCESS get Commandline147. WMIC PROCESS get Commandline148. WMIC PROCESS get Commandline149. WMIC PROCESS get Commandline150. WMIC PROCESS get Commandline151. WMIC PROCESS get Commandline152. WMIC PROCESS get Commandline153. WMIC PROCESS get Commandline154. WMIC PROCESS get Commandline155. WMIC PROCESS get Commandline156. WMIC PROCESS get Commandline157. WMIC PROCESS get Commandline158. WMIC PROCESS get Commandline159. WMIC PROCESS get Commandline160. WMIC PROCESS get Commandline161. WMIC PROCESS get Commandline162. WMIC PROCESS get Commandline163. WMIC PROCESS get Commandline164. WMIC PROCESS get Commandline165. WMIC PROCESS get Commandline166. WMIC PROCESS get Commandline167. WMIC PROCESS get Commandline168. WMIC PROCESS get Commandline169. WMIC PROCESS get Commandline170. WMIC PROCESS get Commandline171. WMIC PROCESS get Commandline172. WMIC PROCESS get Commandline173. WMIC PROCESS get Commandline174. WMIC PROCESS get Commandline175. WMIC PROCESS get Commandline176. WMIC PROCESS get Commandline177. WMIC PROCESS get Commandline178. WMIC PROCESS get Commandline179. WMIC PROCESS get Commandline180. WMIC PROCESS get Commandline181. WMIC PROCESS get Commandline182. WMIC PROCESS get Commandline183. WMIC PROCESS get Commandline184. WMIC PROCESS get Commandline185. WMIC PROCESS get Commandline186. WMIC PROCESS get Commandline187. WMIC PROCESS get Commandline188. WMIC PROCESS get Commandline189. WMIC PROCESS get Commandline190. WMIC PROCESS get Commandline191. WMIC PROCESS get Commandline192. WMIC PROCESS get Commandline193. WMIC PROCESS get Commandline194. WMIC PROCESS get Commandline195. WMIC PROCESS get Commandline196. WMIC PROCESS get Commandline197. WMIC PROCESS get Commandline198. Runtime error (IndexOutOfRangeException): index out of range: 0199. Traceback: line 320, in script
The thing is that if I raise the -aa parameter from 0.05 to 0.1 all works fine..
Is this only related to my PC then?? What should I do to solve this issue?
Thanks again for your help
Luigi…
stributes structural supports for a uniformly loaded domain using e.g. the internal energy of the loaded domain as fitness. Here the uniformly loaded domain is represented by the trimmed surface. My genomes are the support positions (green crosses), which are restricted to a set of predefined grid points. I’m currently using an (i,j)-coordinate indexing for these grid points (illustrated in the viewport just below) as opposed to a sequential , “one-dimensional” numbering (illustrated in the viewport further down).
(i,j)-indexing systemAltenative, sequential indexing system
The support positions are computed by two gene pools; one governing the i-index, Gene List {i}, and one governing the j-index, Gene List {j}, of each support. The value of slider 0 in Gene List {i} is paired with the value of slider 0 in Gene List {j} etc. and the amount of sliders corresponds to the amount of supports. The screen shot below depicts the slider constellation corresponding to the support distribution depicted above. Unfortunately the j-index represented in the sliders needs remapping as the number of j-indices vary for each i-index (horizontal row of grid points). With the current setup I have 12^6 x 9^6 = 1,6 x 10^12 different genomes. If I were to use the sequential, “one-dimensional” numbering, I would only use one gene pool with sliders ranging from 0 to 76 meaning that remapping could be avoided and thereby having only 76^6 = 1,9 x 10^11 different genomes.
So, my current genome setup causes a bunch of issues related to the Evolutionary Solver: Remapping Changing one of the j-index sliders, will not necessarily change the related support position but it will still facilitate another genome to be calculated by the solver. (This problem could be eliminated by using the sequential, “one-dimensional” numbering)
Switching slider values around If the values of e.g. slider 0 were to be switched around with the values of slider 5, this again would yield a new genome but an identical solution. (This problem cannot be eliminated by using the sequential, “one-dimensional” numbering)
Coincident support positions Two or more supports may be located in the same position. (This problem cannot be eliminated by using the sequential, “one-dimensional” numbering)
I find it impossible to imagine the fictive “fitness landscape” of this problem and not only because of the multidimensional genome characteristic but just as much because of these listed, intertwined peculiarities. I’ve tried running the Simulated Annealing Solver as well, but my experience is that the Evolutionary Solver yields better results. To my awareness, the solver uses some kind of topographical proximity searcher. This is why, I think that the solving process itself benefits more from analysing the (i,j)-index system, in which neighbouring grid points hold more uniform topographical information than the sequential, “one-dimensional” numbering, which might have big ID-numbering gaps between neighbours. Have I understood this correctly?
Cheers…
ahams's question about how shades are accounted for in the simulation/thermal map and Theodore's thought that just accounting for shades in the E+ run was sufficient. I think that it may be clearest to explain what is going on with this infographic:
As the graphic shows, the thermal maps are made from 4 key types of inputs. The radiant temperature map is formed through a consideration of both the temperature of the surfaces surrounding the occupants and the direct solar radiation that might fall onto the occupants through un-shaded windows. The first surface temperature effect is easily computable from your Energy simulation results and the HBZone geometry. However, the second is calculated by seeing how sun vectors pass through the windows of the zones and uses the SolarCal method of the CBE team (http://escholarship.org/uc/item/89m1h2dg) to compute an MRT delta resulting from solar radiation. This delta is then added to the initial values computed through surface temperature view factor. When you do not connect up your shading brep geometry, internal furniture breps, or outdoor context geometry that might block sun to the additionalShading input, the thermal map will assume that sun can pass unobstructed through the window or through indoor furniture to fall onto occupants. It is important to stress that the EnergyPlus simulation does not count for blind geometry or internal furniture as actual geometry. Just as numerical abstractions of surface area and material properties. So we need you to plug in the actual geometry of these things when we compute the MRT delta resulting from sun falling directly onto people.
Next, to clear up the definition of window transmissivity. The important thing to clarify here is that, whether it refers to the tranmittance of glass or to the amount of sun coming through a fine screen of blinds, the value is multiplied by the radiation falling on the occupant and thus has a direct correlation to the MRT Delta from sun falling on occupants. So, if you set transmissivity to zero, the sun falling on the occupants will not be considered in the calculation and, if you set the transmissivity to 1, the assumption is that there is no window (or the window glass is 100% clear). So, Abraham, your definition of it as a coefficient is appropriate.
Normally, I would just recommend that you leave this value at the default 0.7, which corresponds to the transmittance of the default glass material in Honeybee. However, there are 4 cases in which you might consider changing it:
1) You are not using the default Honeybee glazing material, in which case, you should change the transmissivity to be equal to this new value.
2) You have a lot of really small blind/shade geometries and you do not want the view factor component to take several minutes to trace sun vectors through the detailed shade geometry and so you are ok with using just a simple abstraction instead of plugging shade breps into the additionaShading. In this case, you might try to estimate the average percentage of radiation coming through the blind geometry (maybe with some simple Ladybug radiation studies or with your intuition about the amount of sun blocked by the shades). You will then multiply this by the tranmissivity of your glass and this will be the value that you input to the component.
3) Your blinds for your Honeybee simulation are dynamic, in which case, plugging shade breps into additionalShading is not going to work because the component will assume that those shades are always there. In this case, you should be plugging a list of 8760 values into the transmissivity that correspond to when the shades are pulled. When the blinds are completely up, the value should be the tranmittance of your window and, when they are down, the value should be the window tranmittance multiplied by the fraction of light coming through the shades.
4) You have shades/blinds but they are transparent or are not completely opaque. The additionalShading_ input assumes that all shade geometry is opaque and so you cannot use it to account for such shades. Accordingly, you will need to account for it through the tranmissivity.
In the future, I may try to pull more information about blinds and glass properties off of the HBzones inside the view factor component but, for now and for the next few months, the above describes how it works.
Theodore, for curved geometry, I think that your safest bet is going to be planarizing the Rhino geometry before you turn it into a HBZone (so you just divide the curved surface into a few vertical planar panes of glass that approximate the curve well enough). This is essentially what the runSimulation component does for you automatically (it meshes the geometry as you see here: https://www.youtube.com/watch?v=nMQ2Pau4q6c&index=12&list=PLruLh1AdY-SgW4uDtNSMLeiUmA8YXEHT_). If I were to figure out a way to incorporate shades in this automatic meshing workflow, your EnergyPlus simulation would take a very long time to run and I am not even sure if the result will be that accurate with the way E+ abstracts shades. So I don't think that it's really worth it over just planarizing the geometry yourself.
Lastly, I won't be able to figure out the problem with your current run Theodore, unless I get the GH file from you. Make sure that you are using all up-to-date components.
-Chris…
I tell you what I had to do and how I did it.
I have the following situation. A urban context with a square plot 40m x 40m surrounded by buildings.
If I extrude the plot I get 4 surfaces and I need to calculate the minimum daily quantity of direct sunlight hours each test point receives in the period from 22nd of April to 22nd of August. For example for the test point at index 21 of surface with index 1 (I am just creating these numbers in my mind) the minimum is on 27th of April and the test point receive 8 hours (this is also invented for the sake of the example) of direct sunlight. All the other days it receives more. So the values I have to found are these minimums for all the test points. Now how to calculate these minimum quantities is a different issue of the topic of this post and actually I manage it.
Continuing with the explanation of what I had to... so I have only the initial plot that generate 4 surfaces, then I want to test smaller plots generated by an offset of 4 m of the original one, and the relative 4 surfaces for each smaller plot.
So in this case I think I cannot use your suggestion because the object don't exist yet.
I managed creating a loop with Anemone, the loop generate an offset starting from the original at 0 until 4 (then I multiply it by 4 to obtain the offset at 0, 4, 8, 12 and 16. Then I did like you also suggest I record every time the result with the DataRecorder and I create for each result a different branch with the index coming from the loop (0, 1, 2, 3 and 4) with the Flatten component.
In this image you can see all the surfaces saved in the same way as described above and in white the test points that receive minmum or equal than 2.5 hours per day of direct sunlight in the period from from 22nd of April to 22nd of August and in dark gray the test points that receive less.
The main point of this discussion is just the fact that instead use this tricky way I used, or the one you suggest, to analyze separately (because they shade each other) 20 geometries (in this case 20 they could be many more) it would be good if it would be possible just to input all the geometries at the same time and they would not shade each other so to get directly all the results with one run and in a more simple way.
Francesco
…
sinergetici associati alla compresenza simultanea di differenti strumenti di analisi e digital design all'interno di un processo di progettazione in svolgimento. I partecipanti utilizzeranno Grasshopper (modellatore parametrico per Rhino): l'uso di questo editor grafico di algoritmi si integra alla perfezione con gli strumenti di modellazione di Rhinoceros 3D espandendo le possibilità di corstruire modelli parametrici altamente complessi. Per generare una complessità simile saranno utilizzati collegamenti live ai diversi programmi elencati di seguito: . Autodesk Ecotect Analysis via GECO . FEA software GSA via SSI Durante questi intensi 3 giorni, i partecipanti impareranno il workflow dei plug-ins con l'aiuto di esempi esplorando una panoramica dei differenti software, le possibilità di testare le performances di un progetto o l'uso di strumenti addizionali non legati ad un singolo sistema (es. accentuazione, formazione, reazione parametrica) [english text] The focus of the workshop is to integrate and correlate the synergistic effect associated with simultaneous presence of different digital design- and analysis tools in an ongoing design process. The main attention is set on easy to handle interface , which should be used at a early stage of conceptual design to respond to external and internal influences in a intelligent and sustainable way. Participants will use the software Grasshopper as a parametric modeling plug-in for Rhino. The usage of this graphical algorithm editor tightly integrated with Rhino's 3-D modeling tools open up the possibility to construct highly parametrical complex models. To generate this complexity we will use live linkages to several programs listed below: . Autodesk Ecotect Analysis via GECO . FEA software GSA via SSI In this 3 intense days, the participants should learn the workflow of the plug-ins with the help of examples and get an overview of the different software's, there possibilities for evaluating the performance of a design or the usage of additional tools to be not chained to a single system . (e.g. parametrical accentuation, parametrical formation, parametrical reaction) [.] Dettagli : Istruttori: Thomas Grabner & Ursula Frick from [uto]. lingua del corso: inglese (saranno disponibili tutor di supporto ma è richiesta una conoscenza di base della lingua unglese).
Quote d'iscrizione (min 12 max 20 posti): educational* : € 280.00 + iva professional: € 450.00 + iva * studenti, docenti, ricercatori, dottorandi e laureati fino a un anno dalla data di laurea OFFERTA EARLY BIRD SPECIAL: le prime 5 domande di iscrizione pervenute entro il 31 Dicembre 2011 avranno diritto ad una quota di iscrizione scontata del 20% Quote d'iscrizione E.B. SPECIAL: E.B. SPECIAL educational* : € 224.00+ iva E.B. SPECIAL professional: € 360.00+ iva. ulteriori info, dettagli e iscrizioni: http://www.co-de-it.com/wordpress/nexus-advanced-grasshopper-workshop-with-uto.html…
I live on my computer and I even sleep with it, so learning all this is probably within my reach but I'm a complete beginner as of now.
I'm downloading the 32 bit version of rhino 5 since the 64 bit doesn't seem to work with your downloads Jon.
I haven't grasped everything you have made yet Jon I can't even begin to understand what your IFC stuff is actually capable of, but just to be clear I'm not interested in solely being able to tell that something is colliding as there are already software that can do that beautifully. What I want to do is bypass that step altogether by never having collision-checking back and forth go on, even collisions which aren't physical collisions, but rather just violations by code. The simplest way to do this would be to simply make the geometry of the beams 2 feet wider than they are in real life, so that way you could put a light right next to the 'over-sized' beam and it would still be within the rules. But that would be extremely primitive and I'm sure there's a way to do it mathematically.
Just to clarify, I'm the fire sprinkler designer in the architectural circus. The sprinkler designer (me) doesn't really get the luxury of telling the other trades that they're colliding with my stuff and they should move. Rather, I get their drawings, find out I'm colliding with them, and move around them. So it would be of great use to me to have this be automatic - that is, to automatically space my sprinklers the neccesary distance away from all obstructions. There are different spacing rules for different obstructions - walls, beams, open web steel, unit heaters, hvac ducts depending on how wide the ducts are, lights, fans, high rack storage, basically anything that would obstruct the water spray from a sprinkler needs to be taken into account and spaced away from.
It's therefore a very attractive idea to be able to just draw a rectangle (representing the walls of a simple room) for instance, have the sprinklers automatically spaced as far apart as possible within the rectangle according to the rulebooks (to minimize the amount of sprinklers needed which minimizes the material cost of the job).
Then add obstructions inside the rectangle, such as a beam, and have the sprinklers relocate themselves or add new sprinklers to accommodate for the new obstruction.. Keep adding obstructions until you have the realistic 3d model of the room, with the sprinklers spaced accordingly, and you have an up-to-code sprinkler system.
There is one example where sprinklers actually need to be spaced really close to, rather than away from, an object.. and that is the ceiling (sprinklers must be within 12 in of ceiling typically).
If the HVAC guy decides to reroute his ducts right through my sprinklers, then I could draw 3D HVAC ducts (I usually get 2D drawings coming in) going right through the room and the sprinklers would relocate and auto-space away from the ducts, without actually having to tell the HVAC guy he is colliding with me because all that will do is require me to do a redesign anyway.
And presto, the HVAC guy loves me because I didn't complain to him at all and seemingly did all this work by moving around him when all I really did was use the computer to do it, the job gets done much faster and I don't have to worry that I'm going to lose my job in court because I made a silly human error when I was patching my system manually because some HVAC guy made me redesign 12 times in different places.
From what I have been reading from you guys, doing this is possible although (I realize) ambitious. The end result would be vastly increased productivity, less error making, cheaper design cost, etc. Using programs like Rhino, architects are getting more and more funny-shaped buildings and making it difficult for guys like me to make sprinkler systems within the rules, and I see it as an inevitability that computers will be making almost all of the typical design decisions in the future when it comes to life safety systems, I'm just trying to see if it's possible to start implementing this extra aid today.
…
ng is deciding how and where to store your data. If you're writing textual code using any one of a huge number of programming languages there are a lot of different options, each with its own benefits and drawbacks. Sometimes you just need to store a single data point. At other times you may need a list of exactly one hundred data points. At other times still circumstances may demand a list of a variable number of data points.
In programming jargon, lists and arrays are typically used to store an ordered collection of data points, where each item is directly accessible. Bags and hash sets are examples of unordered data storage. These storage mechanisms do not have a concept of which data comes first and which next, but they are much better at searching the data set for specific values. Stacks and queues are ordered data structures where only the youngest or oldest data points are accessible respectively. These are popular structures for code designed to create and execute schedules. Linked lists are chains of consecutive data points, where each point knows only about its direct neighbours. As a result, it's a lot of work to find the one-millionth point in a linked list, but it's incredibly efficient to insert or remove points from the middle of the chain. Dictionaries store data in the form of key-value pairs, allowing one to index complicated data points using simple lookup codes.
The above is a just a small sampling of popular data storage mechanisms, there are many, many others. From multidimensional arrays to SQL databases. From readonly collections to concurrent k-dTrees. It takes a fair amount of knowledge and practice to be able to navigate this bewildering sea of options and pick the best suited storage mechanism for any particular problem. We did not wish to confront our users with this plethora of programmatic principles, and instead decided to offer only a single data storage mechanism.*
Data storage in Grasshopper
In order to see what mechanism would be optimal for Grasshopper, it is necessary to first list the different possible ways in which components may wish to access and store data, and also how families of data points flow through a Grasshopper network, often acquiring more complexity over time.
A lot of components operate on individual values and also output individual values as results. This is the simplest category, let's call it 1:1 (pronounced as "one to one", indicating a mapping from single inputs to single outputs). Two examples of 1:1 components are Subtraction and Construct Point. Subtraction takes two arguments on the left (A and B), and outputs the difference (A-B) to the right. Even when the component is called upon to calculate the difference between two collections of 12 million values each, at any one time it only cares about three values; A, B and the difference between the two. Similarly, Construct Point takes three separate numbers as input arguments and combines them to form a single xyz point.
Another common category of components create lists of data from single input values. We'll refer to these components as 1:N. Range and Divide Curve are oft used examples in this category. Range takes a single numeric domain and a single integer, but it outputs a list of numbers that divide the domain into the specified number of steps. Similarly, Divide Curve requires a single curve and a division count, but it outputs several lists of data, where the length of each list is a function of the division count.
The opposite behaviour also occurs. Common N:1 components are Polyline and Loft, both of which consume a list of points and curves respectively, yet output only a single curve or surface.
Lastly (in the list category), N:N components are also available. A fair number of components operate on lists of data and also output lists of data. Sort and Reverse List are examples of N:N components you will almost certainly encounter when using Grasshopper. It is true that N:N components mostly fall into the data management category, in the sense that they are mostly employed to change the way data is stored, rather than to create entirely new data, but they are common and important nonetheless.
A rare few components are even more complex than 1:N, N:1, or N:N, in that they are not content to operate on or output single lists of data points. The Divide Surface and Square Grid components want to output not just lists of points, but several lists of points, each of which represents a single row or column in a grid. We can refer to these components as 1:N' or N':1 or N:N' or ... depending on how the inputs and outputs are defined.
The above listing of data mapping categories encapsulate all components that ship with Grasshopper, though they do not necessarily minister to all imaginable mappings. However in the spirit of getting on with the software it was decided that a data structure that could handle individual values, lists of values, and lists of lists of values would solve at least 99% of the then existing problems and was thus considered to be a 'good thing'.
Data storage as the outcome of a process
If the problems of 1:N' mappings only occurred in those few components to do with grids, it would probably not warrant support for lists-of-lists in the core data structure. However, 1:N' or N:N' mappings can be the result of the concatenation of two or more 1:N components. Consider the following case: A collection of three polysurfaces (a box, a capped cylinder, and a triangular prism) is imported from Rhino into Grasshopper. The shapes are all exploded into their separate faces, resulting in 6 faces for the box, 3 for the cylinder, and 5 for the prism. Across each face, a collection of isocurves is drawn, resembling a hatching. Ultimately, each isocurve is divided into equally spaced points.
This is not an unreasonably elaborate case, but it already shows how shockingly quickly layers of complexity are introduced into the data as it flows from the left to the right side of the network.
It's no good ending up with a single huge list containing all the points. The data structure we use must be detailed enough to allow us to select from it any logical subset. This means that the ultimate data structure must contain a record of all the mappings that were applied from start to finish. It must be possible to select all the points that are associated with the second polysurface, but not the first or third. It must also be possible to select all points that are associated with the first face of each polysurface, but not any subsequent faces. Or a selection which includes only the fourth point of each division and no others.
The only way such selection sets can be defined, is if the data structure contains a record of the "history" of each data point. I.e. for every point we must be able to figure out which original shape it came from (the cube, the cylinder or the prism), which of the exploded faces it is associated with, which isocurve on that face was involved and the index of the point within the curve division family.
A flexible mechanism for variable history records.
The storage constraints mentioned so far (to wit, the requirement of storing individual values, lists of values, and lists of lists of values), combined with the relational constraints (to wit, the ability to measure the relatedness of various lists within the entire collection) lead us to Data Trees. The data structure we chose is certainly not the only imaginable solution to this problem, and due to its terse notation can appear fairly obtuse to the untrained eye. However since data trees only employ non-negative integers to identify both lists and items within lists, the structure is very amenable to simple arithmetic operations, which makes the structure very pliable from an algorithmic point of view.
A data tree is an ordered collection of lists. Each list is associated with a path, which serves as the identifier of that list. This means that two lists in the same tree cannot have the same path. A path is a collection of one or more non-negative integers. Path notation employs curly brackets and semi-colons as separators. The simplest path contains only the number zero and is written as: {0}. More complicated paths containing more elements are written as: {2;4;6}. Just as a path identifies a list within the tree, an index identifies a data point within a list. An index is always a single, non-negative integer. Indices are written inside square brackets and appended to path notation, in order to fully identify a single piece of data within an entire data tree: {2,4,6}[10].
Since both path elements and indices are zero-based (we start counting at zero, not one), there is a slight disconnect between the ordinality and the cardinality of numbers within data trees. The first element equals index 0, the second element can be found at index 1, the third element maps to index 2, and so on and so forth. This means that the "Eleventh point of the seventh isocurve of the fifth face of the third polysurface" will be written as {2;4;6}[10]. The first path element corresponds with the oldest mapping that occurred within the file, and each subsequent element represents a more recent operation. In this sense the path elements can be likened to taxonomic identifiers. The species {Animalia;Mammalia;Hominidea;Homo} and {Animalia;Mammalia;Hominidea;Pan} are more closely related to each other than to {Animalia;Mammalia; Cervidea;Rangifer}** because they share more codes at the start of their classification. Similarly, the paths {2;4;4} and {2;4;6} are more closely related to each other than they are to {2;3;5}.
The messy reality of data trees.
Although you may agree with me that in theory the data tree approach is solid, you may still get frustrated at the rate at which data trees grow more complex. Often Grasshopper will choose to add additional elements to the paths in a tree where none in fact is needed, resulting in paths that all share a lot of zeroes in certain places. For example a data tree might contain the paths:
{0;0;0;0;0}
{0;0;0;0;1}
{0;0;0;0;2}
{0;0;0;0;3}
{0;0;1;0;0}
{0;0;1;0;1}
{0;0;1;0;2}
{0;0;1;0;3}
instead of the far more economical:
{0;0}
{0;1}
{0;2}
{0;3}
{1;0}
{1;1}
{1;2}
{1;3}
The reason all these zeroes are added is because we value consistency over economics. It doesn't matter whether a component actually outputs more than one list, if the component belongs to the 1:N, 1:N', or N:N' groups, it will always add an extra integer to all the paths, because some day in the future, when the inputs change, it may need that extra integer to keep its lists untangled. We feel it's bad behaviour for the topology of a data tree to be subject to the topical values in that tree. Any component which relies on a specific topology will no longer work when that topology changes, and that should happen as seldom as possible.
Conclusion
Although data trees can be difficult to work with and probably cause more confusion than any other part of Grasshopper, they seem to work well in the majority of cases and we haven't been able to come up with a better solution. That's not to say we never will, but data trees are here to stay for the foreseeable future.
* This is not something we hit on immediately. The very first versions of Grasshopper only allowed for the storage of a single data point per parameter, making operations like [Loft] or [Divide Curve] impossible. Later versions allowed for a single list per parameter, which was still insufficient for all but the most simple algorithms.
** I'm skipping a lot of taxonometric classifications here to keep it simple.…
Added by David Rutten at 2:22pm on January 20, 2015
ainbox. This pipe has to force the chain exactly under the chainwheel, and in the middle of the chainbox, and every new design has the chainbox in a different position.
Doing this in Rhino takes with all the changes, moving winches several times etc, about 2.5 days per new design, so about a week work a year. An expensive pipe.
There had to be a way to do it faster, and Grasshopper seemed to be a good way to do this. First I had to learn Grasshopper, but the main problem I ran into was constructing a line tangent to two circles not in the same plane. After maybe 12 or 13 attempts I found a solution for it that is accurate up to 0.001 degrees.
It now takes minutes to make a change, and I get all the information I need: position of the pipe, endrings and closing ring. This is through iges files transported to the big Cadmatic model the ship (commercial) is in.
In the overview picture "lier met pijp en kettingbakken" you see the anchorwinch, the chainpipe and both chainboxes. I left the sb winch away.
In the picture "aanzicht kettingwiel" you can see the chainwheel that pulls the chain. The chain shackles fall in the recesses in both sides of the wheel. The red pipe represents the outside of the chain.
In the picture "vooraanzicht kettingwiel" you can see the chainpipe, or actually the ring at the end of the pipe forcing the chain (red pipe) to come straight from the chainwheel.
When the chain wouldn't come in a straight line from the wheel, we would have a lot of wear on chain and chainwheel.
I'm able to move the top of the pipe in x and z direction, and the lower end of the pipe in x, y and z direction now.
So that was quite an excercise for a simple pipe.
But the next challenge has submitted itself allready. We now need a chainpipe consisting of 2 pieces.
The whole project is done in my own time as a study project, the hours involved do not outweigh the result.
…
ion, extract structural data, produce 2d drawings, and exchange data with other external software. Nemo also includes free tools to create parametric shapes, such as Naca profiles, hydrofoils, keels, rudders, blade propellers, and sail plans.
Born in 2018 as an academic research project at ENSTA Bretagne, Nemo grew up since, immersed in professional naval architecture practice with L2Onaval.
From 2021, Nemo is now available for purchase with commercial or educational licenses. Following license levels are provided to fit every needs depending of user activity :
Free (Designer)
Level 1 (Section + Hydrostatics + Visualization)
Level 1 + 2 (Section + Hydrostatics + Visualization + Resistance + Structure)
We can also help you make best use of our software, provide project guidance, establish specific workflow and create custom tools.
Requirements
Microsoft Windows 10 or Apple Mac OS 12 Monterey :
McNeel Rhinoceros 7 SR26
(Other Rhinoceros, Windows and Mac OS versions have not been tested but may work)
Additional info
Food4Rhino Download
Discourse Forum
Facebook Page
Linkedin Page
Nemo Website
Credits
Authors : Mathieu VENOT
Contributors : Paul POINET, Laurent DELRIEU
…