I know that many data scientists have a set toolkit for manipulating data. I want to ask you to take a second to set those tools aside and look at something a little unfamiliar. The tool is Miller. Miller, abbreviated as MLR, is a command line utility for CSV parsing. It is similar to XSV. If all you need is some filtering, selecting, and sorting, then XSV may be all you need. Let's start simple. MLR cat. This allows data to be passed through as is. Formatting can be added by adding some flags. You can even add bars, but I don't normally add bars because this is something that pushes the data wider than I need it to be. I notice that MLR has many commands that are analogous to common UNIX commands. Along with MLR cat, there is MLR head, MLR tail, MLR cut, and others. MLR cut is how column selection works with MLR. If I were using dplyr, this would be just like using the select function in dplyr. Or if I were using SQL, this would be like the columns I'm selecting right after the select statement. MLR cut requires a field flag, dash F, then field names. The order that columns are printed in can be forced with the dash O flag. Fields can be dropped with the dash X flag. MLR also supports filtering. This is a big difference between XSV and MLR. Where XSV forces rejects for filtering, MLR uses logical symbols. If you are coming from standard data frame manipulation libraries, then this feature will feel familiar. When using filter, the expression is surrounded in single quotes and the fields being used in the filter start with a dollar symbol. MLR uses the put command to make new columns. This would be analogous to Panda's assign method or dplyr's mutate function. Now, let's talk about chaining, the then keyword. It is common for me to want to sort the data, then take the top rows. MLR has great support for descriptive statistics and even allows for group aggregations. In my mind, this is one of Miller's killer features. I can use Miller to calculate group counts, min max, and even various percentiles using MLR stats one. The stats one is for statistics that require only the column of interest to calculate. There is also a MLR stats two for calculations involving two or more columns. If you come across a calculation that is not provided by Miller, then you can use Miller's domain specific language to make a custom function. The author of Miller calls these out of stream variables. Miller reshape allows a clean interface to pivot data between long and wide format. I have just scratched the surface with Miller. It is a powerful and fast tool. I highly recommend any data scientist or data engineer to check it out. I was surprised by the functionality it has to offer. Thanks for listening. See you next time.


We're in the Linky booth over in Eureka Park in the Sands and I'm here with Joe DeGanzik who's going to tell us about a pretty promising new product here. Hi Joe. Hey Allison, how are you doing? We're pretending we haven't just done a podcast together. Exactly. Well, welcome to Linky. We've got a wonderful smart home hub that controls all of your various smart devices throughout your home, lights, locks, switches, you know, all the usual suspects, right? But you're doing more than anybody else in here, right? Well, we've got a product that does a lot of different, it combines a lot of features into one. So it's got the touch screen, it's got a beautiful customized user interface, it's got the control, it has the radios on board, so Zigbee, Wi-Fi, Bluetooth to connect to all the different things and it's the first third-party hardware product to have Google Assistant natively integrated. We're talking to the audio only listeners as well and this unit looks to be about four inches wide, maybe six inches wide, four inches tall, beautiful on the wall, looks really, really nice, nice industrial design. It's a, thank you so much, it's a five inch HD 720p touch screen and yeah, it's an unassuming so it blends into your decor, it's not too big. So what are the buttons we've got on screen here?  We've got a little bit of lag because of all the wireless here in CES but you can see it. Let me dim that down so I don't overpower you. So the screen is a, he's got little dials that he's just flipping through and when he goes to a dial he can just move his finger on screen and he's changing the color temperature, changing the brightness and the temperature. That's right. And that works, that's the way all of it works in terms of it's just a long press while we don't have it connected to our Nest we can add long press and I can show you the interface so you can do various functions for your thermostat as well. So it's a simple user interface, it's very approachable, the same thing goes for if you have, you set up scenes, a movie mode, a way mode, all the different types of scenes that you would set up in your home. So what is an example of what you would do with the Google Home features of Linky? Well, you can obviously talk to it about your smart home stuff like turning things on and off. Let's see if she'll actually respond. This is the most challenging wireless environment in the universe but go for it. You feeling lucky Joe? I'm feeling lucky and so a warning I'm going to set up your devices so terribly sorry. Hey Google, turn off Flamingo. And it actually worked. It actually worked. If it can work here, that means it actually does work really well. That's right, it can work anywhere. So you've got Google Assistant built in and what that means also is that it's not just the smart home stuff, I can ask it all the other questions. What's my name? What's the weather doing? You know, traffic and all. What's my name? I guess, if you forget your name I mean you could be in trouble. I think by the end of the sea, yes, I will forget my name. There you go, there you go. I noticed a plus button there, is that for adding new devices? You can add scenes, watch this. So if I want to add a scene, I just tap the scene. I can just add a junkie scene name and then it's a drag and drop interface so I can literally just drag this down. So he's dragging different devices down. That's right and then I can long press on them. I can make my adjustments to set the scene. Tap, your scene is done. Oh, okay, so that scene now is these two lights are on, they're at this temperature, each one of them at different temperatures, different brightness. That's exactly right. So how about installation of a device like this? Is it complicated? Is it hard? Nope, because we've got two versions. So this version is the wall version. It's got a special little module that goes into a standard single gang switch box and there's a back plate that this snaps onto.  So we have a desktop version. This is powered by USB. It's great for just sitting on the countertop, sitting on your desk or whatnot. Same exact interface, same system. And if you have multiple devices, multiple linky, we call it the linky home intelligence hub. So if you have multiple hubs, they will all sync with each other automatically. So it doesn't matter which one you added a scene to or a device to. You can control them from anywhere. When we finish, we will also have a smartphone app for iOS and Android. The same beautiful interface will be on your smartphone and that will enable things like geofencing. It will auto detect when you leave your house, set away mode and you'll be able to get alerts from the various devices and sensors in your smart home. What kind of granularity is possible with a smart device like this and your phone? Can it turn lights off in a room when you leave the room or is it more geofencing as far as the whole house probably? It's really the whole house. We've seen some other competing products out there that tried to do it with Bluetooth. Bluetooth is not 100% perfect yet to do that kind of granularity. That's more motion sensing than geofencing, right? It's technically geofencing. Bluetooth 5 has different ranges so it will detect down to a couple feet away. But in my experience as a smart home guy, it doesn't work so well. So now we're in Eureka Park as I mentioned which is often pie in the sky but you guys are actually getting close to shipping something like this, is that right? That's right. This will be available. We're going to do a crowdfunding campaign and it will go to retail a little bit later this year. Wow, that sounds like fun. I think I might need to test one of these, Joe. I think you should. If I just knew a guy, I could make that happen. You just knew someone who worked for the company. There you go. All right. So if people want to find out more about Linky, get involved, maybe get into that crowdfunding campaign. Where would they go? They can get updates and get more information at linky.com. That's L-Y-N-K-Y.com. Very good. Thank you for so much, Joe. This is awesome. It is really a beautiful device. Thank you so much, Allison.


Okay, so let's start. Thanks for coming to my session. Before beginning the presentation, let me get a show of hands of how many of you have used design patterns ever in your life in programming languages? And how many of you have used design patterns in a functional programming language? Any difference you felt using a design pattern in a functional programming language and using a language like Java or C++, what kind of difference you felt? So any thoughts on how you can get that beautiful structure? Any theory, any theoretical underpinnings that make composition much more beautiful when using a functional programming language? Yeah, so it's basically we have some underpinning of mathematics, right? Category theory and things like that kicking and you have a mathematical definition of function composition. Okay, this is going to be a discussion about design patterns, but I promise that it's not, it's going to be very different from the Gang of Four design patterns that we have learned to use and loved in Java. The discussion that I will start doesn't have any serious mathematics or advanced category theory, but it's about developing an insight that lets you identify code structures that you may think can be improved with a beautiful transformation of an algebraic pattern. The basic underpinning will be algebra and we will see how to encode functional design patterns using the concepts from algebra. In the earlier days of Java coding, we used to feel proud when we could locate a piece of code which could be transformed into an abstract factory pattern and we felt proud when the factory beam could be injected using spring dependency injection. The result was that we ended up maintaining not only Java code but also XML and that too untyped and unsafe. This was dependency injection pattern in the earlier days in full glory. In this session we will discuss patterns that don't look like acceptable artifacts. They are very much part of the language itself. They have some mathematical foundations in the sense that they have an algebra that actually composes and composes organic abstractions. We will see plenty of examples of how these patterns can make your code beautiful and algebraic. So here is the plan today. We start with the formal definition of a design pattern and establish a formalism in the pattern which we are going to use for this discussion. And as you will see that this formalism is based on algebra. In fact, many of the functional patterns which we will discuss are plain encodings of the algebra itself. And we will look at some Scala code. Not necessarily imperative. They are also functional code but for which we will still try to reduce code duplication and using patterns we will try to raise the level of abstraction of the code which we are going to see. The code we will see is mostly Scala code. But the principles which we will discuss apply equally well to any statically type functional programming language. For example, Haskell. We start with the definition of a design pattern. This is the classical definition of a design pattern solution to a problem in context. And anyone can identify this gentleman in the picture is Christopher Alexander. Christopher Alexander is the person who was responsible for first using the term design pattern in the context of architecture. Not software architecture. Architecture as in buildings and bridges. And Alexander was the main catalyst because of whom? Design pattern, the term design pattern has become mainstream in software as well. So we have a solution. We have a problem and we have a context. The problem is given to us. We don't have any choice. We are given a problem for which we need to find the solution. And the solution itself which we are going to implement usually has two components. The first part is the generic component which is invariant across the context of the application. This is the part. This is the part of the design pattern which we came to be. The reusable part across all contexts. This will be the algebra itself as we will see. And the other part of the solution is context dependent which we need to implement separately for every context of the problem. Now I will claim here that this aspect of reusability that we talk about in design patterns has a parallel in the world of mathematics as well. And let's keep this in mind while we traverse through the aisles of a similar structure from the world of mathematics. Algebra. This is the definition of an algebraic struct from Wikipedia. The point to note here is that the definition of an algebraic structure is completely generic. The definition doesn't specify any concrete type. We are not talking about an algebraic structure for integers or for any other data type. Algebraic structure is defined generically. And every algebraic structure can be refined by adding more and more constraints on the set of components. For example, this mentions about operations. We can constrain some of the operations to refine our existing algebra. As for example, we can define the algebra of sets like this. We have a set A. We are given a set A and we define a binary operation on the set which we can express as Phi AB or A Phi B. Once again there's nothing concrete about this algebra. We are talking about a set, set of elements of type A. We haven't yet qualified A. The moment we qualify A with a specific type, it becomes an instance of the algebra. For example, this is one specific instance of the algebra where it deals with the set of integers. When dealing with set of integers we can define addition as a binary of operation. And as you know, that addition of integers is associative, which is an additional constraint, additional refinement that we are tacking on on top of the existing algebra. It was not there as part of our original definition of set A. That's an additional constraint which we are imposing on the algebra. Addition of integers also has an identity operation. You add 0 to anything and the number remains the same. So let's enhance our original algebra with some of these constraints. We bring in this associativity constraint here. So on top of our original algebra we say that the operation that we define, the binary operation which we define has to be associative. Anyone has any idea what this algebra can be called in generic terms? What is this algebra of? This is the algebra of semi-groups. We define a semi-group as having a set and an associative binary operation. We just change the original algebra by imposing an additional constraint. We can further refine this algebra. We add the identity operation and this algebra becomes the algebra of monoids. Now the question is how do we encode this algebra in our code? It's as simple as writing the three lines of code. We have a class monoid. This is Haskell. We have a class monoid. Note that once again this is not specialized for any concrete type. We say monoid A. It's for any generic type A and we define the two operations, memt and map n. Memt encodes the identity operation and map n encodes the binary operation. But still it doesn't have the laws which we set, the constraints, associativity and identity. We can encode them in terms of some laws. In Scala typically a monoid is defined like this. We have the semi-group and we define the algebra of semi-group to get the algebra of monoid. Note it's parametric in the type. Here we have the algebra of monoid which is the basic interface. It's reusable, polymorphic and usually it comes as part of the standard library. In Scala the Scala standard library which comes default it doesn't have any monoid, but you can use some of the standard libraries like Scala Z or CACS which gives you the definition of these algebra. And we have the instances of these algebra as implementations. The first one is the instance of monoid for integers where we define where we can define the operation of addition of integers. And the second one can be a monoid instance for any of your application data types. For example in an application you can have a data type called money which encodes a money, an instance of money. So you can have domain specific instances, but both of them, both of these instances inherit the generic contract from the basic algebra of monoids. So as we go down from the algebra to the implementations, we are going down from generic to specific. Specific implementations which we saw, they use the generic protocol or interface and this reusability is enforced by parametricity. We didn't have any type, specific types as part of the algebra, but we had them as part of the implementation because we are implementing the semantics of the specific data type in order to define the identity and the combine operations. And this genericity implies reusability. The more generic we are, more reusable the abstraction is. The moment we go down the hierarchy we lose on the genericity and we get the specific data type for the application. This is the summary. We have the pattern. The top part gives you the pattern which is the reusable part, generic and reusable. And the bottom part gives you the context specific implementation. So as part of the solution, as we define in the formalism of the design pattern, the top part is the completely reusable part which can be reused across all contexts, across all implementations of a monoid. So how do we define functional patterns? Functional patterns are defined by means of a generic reusable algebra. It has to be parametric on types. The moment you add in a specific type as part of your algebra definition, you lose on genericity. And there is a clear separation between the pattern and its instances. The pattern is the algebra part and the instances are the implementations. And as we will see, these patterns are composable through composition, function composition. Why do we need to use design patterns or functional patterns? One of the premises of the original design patterns, even in the Ganga for book was that it gives you a standard vocabulary. The moment you say factory to a person, she understands what exactly do we mean. It's meant to create some instances. Similarly with functional patterns, we have the standard vocabulary. The moment you say monoid or monoid or applicative to a person who understands the terms, he or she realizes that what to expect out of the algebra, what contract it gives you. So it establishes a standard vocabulary amongst the users. There's a rich ecosystem support through standard libraries. What we will see is that the standard libraries, besides offering you the definition of the algebra, it also offers you a suite of functions. And those functions are implemented totally with respect to the algebra without any concrete type specific implementation. So that makes those functions reusable across all data types of your application for which you honor the contract. For example, you can have 10 monoid instances in your application as part of your application. So if you have a function in the library which takes a monoid, you can use any of those instances of data types from your application and make use of the function. Also with functional patterns, you get a number of privies. For example, say you have a data type for which you have a monoid instance. If you use the data type as part of the value of a map, then that map becomes a monoid. So map kv, if you have an instance of monoid for v, then map kv becomes a monoid. This is the multiplicative power which I was talking about. These functions are from standard libraries and the contracts and these functions only depend on the algebra. So that you get a multiplicative combinatorial explosion in fact. You can combine your application specific data type with these functions. Now let's look at some concrete code and these are actual code base from real life examples, real life applications. And we will see how we can apply some of the functional patterns in order to raise the abstraction level of these code bases. Now this is a definition of a class called money, which is a frequently used data structure in many financial applications. This money abstraction is defined in terms of a map, which is a map from currency to big decimal. For example, say I can say that one unit of money I have in bank, it consists of 10 US dollars and 1000 Indian rupees. So that can be modeled using this map based data structure. And here we have some code that manipulates some money. Perfectly okay, there is nothing wrong with this code, with this piece of code. But we will look more into this add function. Yeah, we will look at this add function. What exactly are we doing here? If we focus on the how part of how we are adding the money instances, we are basically manipulating two maps. We are fusing two maps. We are adding the, we take one map, add the keys from the other and in case we have, in case the keys are equal, in that case we need to combine some of them, combine them using some additional something like that. But the important part is that it's a concrete implementation of fusing two maps. If we were able to abstract away the fusion part of it, fusion part of two maps into some generic structures, then we could get rid of some boilerplate code here. How can we define a generic function which will fuse two maps, which will add two maps? We will see it in course of this presentation. But for the time being there is a red herring, don't do this. This will lead to an explosion of boilerplates and code duplication across your code structure. Now here's another class. The important class is the payment class, which is the payment made for a particular account. For so and so account we are getting a payment of some amount of money on a specific key. Now look at the last function, new balances. Again this involves fusion of two maps because our payment structure is also, payment structure consists of a map and this, this is in fact a map from an account to money. Previously we saw money itself is based on a map and this is one more map and if we have to add these two maps then we would have to duplicate that code base once again here and do some, some other jugglery in order to combine these two maps. So this is in a way somewhat similar to the problem we saw earlier. Now the idea is that whenever you spot similarities of structure or behavior, squint hard, there may be another abstraction hidden within the concrete implementations. Yeah actually it depends it depends if it's a, if it's a small application it may not make sense to go for, go for higher order abstractions. But if you have a, typically if you have large domain models or large abstractions these are the code bases which I picked from some large applications. So we had hundreds of classes and it was a big application. So one thing which you need to keep in mind is that whenever you are going for abstracting something, judge the cost of it as well. If the cost of an abstraction exceeds the value, in that case don't go for it. If it's a small application then it doesn't make sense to go for big abstractions or make the code unnecessarily complex. But if you see that the result of code duplication or the result of having boiler plates is becoming too much, it becomes a maintenance burden also. In that case go for the higher order abstractions. In fact this logic in new balances is quite complicated and I intentionally highlighted it for the purpose of making the slide concise. Now here are two other functions. One of them is valuation and the other is max payment. What we are doing here is look at the contracts of these two functions. Both of them take a list of payments and return a money. So similar contract is there. Any commonality of behaviors that we can extract, is there any commonality of behavior we can extract from these functions? Both do basically the same thing. Iterate over the collection and compute an aggregate. The aggregate is different. In one case we are adding and in the other case we are finding the maximum. So once again there is a chance that if we squint hard we may find some design pattern from within it and we will try to extract and generalize. For the time being we will avoid doing these things. So we are back to this money adding business. One of the things which this code base does and the first impression that we will have looking at this code base is how the money are being added. Now since we are talking about functional programming and functional abstractions we need to focus first on the what part of the function. What does the function try to do? The function tries to add two money objects and even if we ignore the how part of it when we add two money objects that that addition process has to be associated. A plus B plus C will always always needs to be A plus B and then plus C. And even in our code base we have an identity operation defined here. So this gives us an idea of what pattern we can extract out of it. It's a monoid for money. So this gives us an idea that if we implement a monoid for money then the details of this logic will go as part of the abstraction and we can make our code much more sussing and smaller. So any question till now? First of all I don't think I said that patterns are applicable for statically type programming languages. I mentioned that some of the patterns that we will discuss today makes more sense when we have a statically type programming language. For example the monoids and monoids I have seen them defined also in dynamically type programming languages. But I always felt that these patterns make more sense under the concepts of static typing. Any other question? Now we try to extract the similarity of behaviors and structure out of these code bases. So I have flagged these two behaviors here. If we squint hard we will see that both of them are doing basically the same thing. They are iterating on a collection and finally doing an aggregation.  The first one is doing an addition and the second one is doing a max operation. So this gives us an indication that we can plug in two instances of monoid for money. For one we define the combined operation as the add and the other one and for the other one we define max as the combined operation. And if we do this then we can extract some of the commonality from this part of the code base. Let's see how. Similarly in this case if we have a monoid instance for money which we thought will be a good idea then this map itself will be a monoid. So both the balances will be monoid. So this is how we compose multiple design patterns. We are composing the very fact that money has a monoid instance. It gives us this thing for free that any map which has money as the value is also a monoid. So in that case we can get away with this complicated logic and model this as a combined operation on the two monos. So once again the basic pattern that we are using is monoid for money. So looking back we had similar problems but under different context we could reuse the same algebra of the monoid. Though we need to define distinct concrete instances of the algebra because we need different modes of aggregation for money. For one case we needed to add and for the other case we need to combine. Let's look at this in more detail. There are some more patterns inside these couple of lines of behavior. Now if we look at both of them as I mentioned that both of them are basically alterations over a list of payments. But if we squint hard you will see that both of them are basically fold. Both the operations are doing fold with different aggregation function. So this is one more pattern which we are which we can find out that both of them are fold. Both of them doesn't aggregate on a binary function which we can define in terms of monoid and they start with a list of payment. From there it extracts a list of money. How? By using this function called credit amount. This function extracts the money part out of the payment. So ultimately the fold is done over a collection of money not a collection of payment. Now if we extract, suppose we are able to extract this behavior out of these functions and have a common function for them. Now we have enough generic patterns inside it to extract it as a common behavior. We have the fold one. Fold is a generic operation. We can give it a monoid on which to aggregate. That's also a generic operation. And we can, the very fact that we are extracting money out of this payment is itself a map operation. So we have a map, we have a fold and we have a monoid. So now we need to combine these two. Now where should this behavior go? This generic behavior that I am talking about what is the data structure under which we should club this behavior. Here we have it in terms of list. Here it's taking list. But these behaviors are they doing anything related to list? List is a much more powerful data structure. We are not talking head of the list or tail of the list. All we need is a much lesser powerful data structure than list. And in software engineering one of the guiding principles which we follow usually is use the least powerful abstraction which applies for your use case. So we don't need list here. So the pattern that we will talk about is foldable. All we need from this collection is the usability to fold over using an aggregation data structure. Now what we have achieved here is abstracting our structure as well as the operation. We are using a foldable. Foldable is a much more generic structure than list. The moment we move over to a generic data structure the usability of our function increases. Foldable is a generic data structure compared to list. Array is also a foldable. Map is also a foldable. So the moment you plug your behavior as part of a lesser powerful data structure the range of usability increases. So here we have foldable and we have a function within it called fold map which is exactly what we plan to do. It takes a monoid and first it does a map and then it does a fold. If we apply this function in our context in the context which we saw we can define a helper function. MapReduce, that's exactly what we were doing.  Just a question. MapReduce also we have seen in the context of big data and Hadoop and things like that. Do we have any small difference between this mapReduce and the one we use in Hadoop? Combiner, you are talking about combiner. Yeah, combiner is not there but combiner is also optional. Combiner you don't have to have. The important point is that in case of Hadoop mapReduce the operations need to be commutative. Here we don't have this restriction. The operations are not commutative. So we have been able to abstract structure and operation. By using foldable as opposed to list we have made the structure more generic. So this logic no longer applies to list only. It applies to everything that is foldable. And by delegating the logic to combine the two elements to the monoend which is a generic algebra we have been able to abstract over the operation as well. So by defining these 4-5 lines of code we have been able to abstract over the structure as well as the operation. And if you look at the code base now with these changes we have this. All that multiplicative reusability that we were talking about. The standard library gives us the monoid for map implemented using the generic protocol and we can reuse that to our domain specific type provided we honor the constraints of the library. So assuming that mapReduce is a helper method as part of our library and fold map and foldable come from the standard library we have the standard application of mapReduce under both of these contexts. We just need to pass the different aggregation function and different map function if we wish. And the different aggregation function comes from the different instances of the monoid. In one case we are using the order monoid and in the other case we are using the add monoid. I will give the slides up or if you can come forward. Algebraed. Actually Algebraed what it does is it defines some of the data structures as monoids. For example those data structures are typically used in the context of big data and streaming applications like bloom filter, count mean sketch and the basic property which they exploited is that they came to the realization that all of them are monoids because they can be merged together. A count mean sketch can be merged with another count mean sketch. There is a definite algorithm for that. So because of that they defined and they released in their library. I have used that also. They have defined all of them as monoids exactly that. Monoid is a pattern which appears in various context and in various use cases. So in case you are developing a large application there is very little chance that there is not a single instance of monoid in your application. Monoids are almost everywhere. And just to summarize this discussion regarding this map reduce method which we defined the most important part which makes it reusable is parametricity. I have been emphasizing the importance of parametricity since the beginning of this session and there is a saying that the way you abstract unless it is parametric there is no value in that abstraction. If you make your abstraction depend on concrete data types in that case that that is not a good abstraction that loses reusability and in our case this map reduce function is completely parametric on types. It does not depend on any concrete types. It is reusable under multiple implementation context. Any question? This one? No, you need to have separate instances of monoid for A as well as for B. No, the basic algebra the basic definition of monoid is that it is for one specific data type, one data type. There are other algebras for multiple data types but this is for a single data type and the other thing to note is that monoid is parameterized in a specific data type. There are other algebras which are defined as on higher kinds to be honest I have used all kinds of algebras in my application and till date I have not faced any issue with this. Actually the point which we need to keep in mind is that not all parts of application need to be blazing fast. If you feel so my idea is designed for optimized abstractions and if you feel that some part of your application is becoming a bottleneck for performance because of additional abstractions then de-abstract only that part of the application. Because once you have an abstraction you can always de-abstract it but if you have a whole application without any abstraction then it is not a problem. So abstractions have to be designed and have to be thought of early enough in the life cycle of the application development. So I move on to the next topic I don't have much time I will rush through it. That's one more use case handling domain validation this is also from a real life code base the entire code base is littered with these kinds of things and you have some exceptions those exceptions at the end of it it will show the exception. So these kinds of codes first of all they are not pure or they are not referentially transparent and it adds a lot to the boiler plates and code duplication stuff. Another example configuration management we see typically every application needs to read from some configuration and this is an example of a code base where one is trying to read stuff from a configuration file once again littered with try-catch things. Try-catch things are never referentially transparent and in functional programming we usually don't advise to use try-catch blocks. So these are typical anti-patterns we think even when people code using a functional programming language it has repetitions and the other thing we saw in that is that the entire code base is based on imperative statements and not referentially transparent expressions which add value to your code base. Hence you can't compose and because you can't compose you have separate statements being invoked in sequence. It's also littered with exception handling code try-catch which violates referential transparency and it's very difficult to modularize such code bases. So the first approach the first approach is abstract your exceptions with an algebra we need to handle exceptions but not throw it upstream. So here we have defined the function which is encapsulating the exception part because this is often required when you are interfacing with a language which has support for exceptions especially java suppose you are writing in a functional programming language but you need to interface with java and you don't have any control over the code base in java there. So typically java code throws exceptions but in functional code it's always recommended that you try to localize those impact in small places. So here what is being done is that the exception is caught here and what is being returned from the function algebra of disjunction which is the either, either data type the either data type encapsulates on the left the exception and on the right the value. So the first step is abstract your exceptions. Now here we have an algebraic data type for the config part the config part we need to encapsulate right we need to abstract because once we are done reading the configuration we need to return an algebraic data type so that's what is being done here even with this algebra this algebra of either note we are returning either and either is a monad we can write beautiful configuration handling code like this it's a monadic comprehension we are reading reading various stuff from the application using our function read stream and at the end of it we are returning the algebraic data type which we define this is fine this what's fine now one thing we need to notice here is that since we are defining the thing in a functional programming language we have lots of repetitions here the config everywhere we need to in all of those invocations we need to pass the config as a parameter and in functional programming it's one of the things which we try to do is avoid repetitions so is there any way we can avoid repetitions here and avoid passing this config parameter everywhere all across the place we usually try to avoid such repetitions and our friend is algebraic composition this is the function which we had for reading the config thing and this error or is actually a type name for either now what we would like to do is we would like to compose on the return type we don't want to pass config everywhere so we need to take config out of the function signature as a correct parameter previously we were having config as part of the parameter in from config now we make the parameter a bit make the parameter correct this is the thing which we get now our function it's a config it was reading config but now it's doing it as part of the parameter and we want to have a better abstraction for reading this stuff in we are doing we are reading in the config parameter we are reading in the config data type so we can abstract this reading part in the form of a this is what we can do one common way to abstract this config abstract the reading part is by using a reader monad reader monad reader monad and since we already have an either monad there we need to fuse the two using a monad transformer so that's exactly what reader t does here I am running out of time so this is the final shape of our function we have this reader t which is the transformer which fuses the two monads the either and the reader and now our function becomes much cleaner it doesn't have we don't have to repeat the config parameter everywhere and here is the definition of the read string which also gets changed because we need to return a reader and claisely is nothing but a reader so quickly summarizing functional patterns are made useful by reuse of already existing algebra we could successfully able to reuse the reader algebra the monad either etc algebraic composition we used composition to form larger patterns out of smaller ones the map reduce was an example where we were able to compose multiple patterns the abstractions remain composable and modular so by looking into some of the aspects of an existing code base very likely that you will discover many such patterns and you should be able to raise your program to a different level of abstraction but once again before doing any refactoring with abstraction we were of the cost of it as martin mentioned in his keynote today morning there are costs to everything so be sure that that you can justify the cost which you are incurring for abstracting your program question yeah mining means the idea was to take some existing code base and find out some mine some patterns out of it explore and mine some patterns out of it and all of these code bases are real world code bases which are running in applications many of these were written by me also so it's as you learn it comes to your realization that these code bases can be improved so I picked many code bases as well exactly yeah that's actually the sign of progress if tomorrow you can find some mistakes in the code base which you wrote yesterday and that's the sign of progress yeah I think the first step will be to pick up the basics of functional programming and I feel that these kinds of refactoring and these kinds of programs make more sense in a statically type programming language pick one of them possibly haskell because in haskell yeah these patterns become much more explicit because haskell has better type inference than scala so the code becomes less noisy so yeah learn haskell learn haskell interact with people who know these things because there's no substitute for practicing in hands-on hands-on kind of stuff sorry I'll have to interject we need to set up the next speaker I'm sure they will be around so we can catch up


I will show you pseudo code with proper looping. I am showing you the main part of the code I am not showing you the complete pseudo code. So, the main loops which are involved I am showing you it is just that you have to use a particular programming language and convert into the as per the language syntax. So, this pseudo code what I am showing right now is when you apply x momentum equation to obtain u velocity. In this slide I am showing you steps to predict u velocity. Now, to predict u velocity this is the expression to calculate the mass fluxes in the x direction this is the expression to calculate the mass fluxes in the y direction. Note that the to calculate mass flux in case of x momentum control volume you have to do linear interpolations. This are the expression to calculate the momentum flux in the x direction and momentum flux in the y direction. This is the expression to calculate the viscous force in the x direction on vertical faces which is a normal viscous stress. This is the expression to calculate the shear viscous stress in the x direction. Note the difference in the loop running in this is of the loop. Once you have calculated this fluxes then you know there is a step there is an expression where you do a balance multiply by delta v divided by and then add that with the velocity of the previous time step. You do calculate total advection which is the rate at which x momentum is lost by the fluid in the control volume. Let me see I think it is right now east face minus west face. So, this is x momentum lost by the fluid in the control volume this is the total viscous force acting in the x direction. So, now we are doing a balance and this is the total pressure force acting in the x direction. Note that for pressure in x momentum we are not doing any interpolations and finally, to predict u velocity. Similarly, we this is the adposing animation for this. This is the steps to calculate the fluxes momentum fluxes viscous forces viscous stresses in the x direction. This is in the y direction sorry the viscous stresses will be the shear viscous stress here and this will be the normal viscous stress, but both the viscous stress will be in the y direction. Because viscous force we have to take in y direction in y momentum equation. Once you have calculated this fluxes you calculate the total term do a balance and then predict the velocity. That completes the pseudo code for velocity prediction. First we predict fluxes and then we obtain then we predict velocities. Now, here I will show you expression to do mass balance. So, once we have predicted the velocities we use those velocities and calculate mass imbalance which is represented here as divergence net mass going out of the control volume mass source. This epsilon is what we call as practically 0 which a user has to define. If the mass source has become practically 0 then whatever velocity you have predicted is the correct velocity for the next time state and you can go for computation of temperature in case of force convection heat transfer problem. If it is not then you solve for pressure correction as a function of mass imbalance as shown here. You add the pressure correction to the earlier pressure and obtained a this is a basically a pressure tuning. You get an updated value of pressure and from an updated value of pressure you get an updated value of the velocities updated value of mass fluxes. And with that updated value of mass fluxes check again the mass imbalance. If mass imbalance is close to 0 then you are converged otherwise you keep doing keep doing pressure tuning new mass imbalance. So, this continues till convergence. Note here that even if you are using a semi explicit method in for unsteady formulation there is one loop for time marching where you will generate pictures at every different time step and you can create a movie for the velocity and temperature distribution. There is an inner loop also which is that inner loop this pressure tuning and mass updation mass flow rate updation. So, I will note that continuity equation as there is no explicit equation for pressure needs to be solved iteratively. And that is the biggest difficulty in computational fluid dynamics. This is for temperature at only the grid points at the cell center and face centers. This is to calculate the mass flux enthalpy flux and conduction heat flux in the x and y direction the pseudo code. This is to balance the net enthalpy lost by the fluid in the control volume total heat gained by conduction total heat gained by volumetric heat generation. So, this is the total heat gain you multiply by dt divided by rho Cp into volume. You get a value some temperature which you add with the temperature of the previous time step and obtain the temperature of the new time step. So, this staggered grid is one of the remedy it works well in the standard coordinate system problems. But when you go to the complex geometry we have to come up with another formulation which is called as collocated grid formulation. I would like to mention that nowadays one method which is becoming very popular which is the method which was the first method in the for CFD computation. So, one method which was which is a Cartian grid method which was probably the first method with which CFD started. Now, that method is again becoming popular nowadays because there is an issue that if you are solving industrial problem which is a very complex geometry three dimensional problems. And if you and nowadays there are more complex problem like moving boundary problems. Then after each time step when you have to regenerate the mesh like for flow across a car or an aeroplane mesh generation takes lot of computational time. If it is not moving then you generate mesh only, but just imagine it is a moving boundary problem then you generate have to generate that mesh after every time step. So, when you use this body fitted curving in your grid structured or unstructured it takes lot of time in mesh generation. So, one of the oldest method in CFD Cartian grid method is nowadays becoming popular due to this reason. However, if you are using Cartian grid for let us say flow across a car or aeroplane where the surface is curved solid surface is curved. Then you generate Cartian control volume where there are certain control volume which are partially filled by solid and by liquid. So, if in at formulation stage we are somehow able to handle the this partially filled cells by properly applying the boundary conditions at the solid fluid interface. Then it is a very promising option. There is another approach which is becoming quite popular which was called as adaptive multilevel Cartian grid method. Public towards the end of today's lecture I will show you we are working on developing that method. So, maybe I will show you an animation for that. So, I would like to say that maybe you see lot of unstructured grid or a Kelvinian grid for industrial problem, but right now here you are learning a Cartian grid method, but this method is coming is gaining lot of importance nowadays. Because in the Cartian grid method when there is a partially filled cells which we mentioned even if the object is moving what will change is that the partially filled change may next time let us say it can go in completely in solid or it can go completely in fluid. So, you may have new partially filled cells. So, you have to keep a tag of the cells which are being partially filled, but your grid Cartian grid does not change with respect to time. So, you do not have to do remachine and moreover generating body fitted grid in a let us say car or aeroplane versus generating Cartian grid which is not body fitted you can the computational time requirement for mesh generation there is a lot of difference this Cartian grid generation does not take almost any time. In this slide I am showing you as we are having pressure Poisson equation for pressure correction it is like a conduction equation. So, you need boundary condition at all the boundaries. So, in here I am showing you the boundary conditions for pressure correction and the boundaries where pressure is defined like an outflow if pressure is prescribed then the pressure corrections become 0. So, for any boundary where pressure is given pressure correction is 0 in most of the solid boundary in fact all the solid boundary you know there is one boundary condition which even comes from an inviscid flow mostly boundary condition comes from viscous flow what is the boundary condition even in inviscid flow normal velocity is equals to 0. So, in a solid boundary normal velocity correction is equals to 0 and if you go back and look into the expression for velocity corrections the way we have proposed if the normal velocity correction is equals to 0 what you will get is the normal gradient of pressure correction should be 0. So, in a solid boundary is your normal gradient of pressure correction is taken as 0 as a boundary condition. So, on the left boundary, right boundary and bottom boundary which are solid boundary normal gradient of pressure correction these are the discrete form of the normal gradient of pressure correction is equals to 0 on this stationary boundary is u and v are 0. So, that is what is shown here on the top boundary is when v is 0 and even if it is a top boundary it is a solid boundary. So, there is no velocity normal velocity will be 0. So, normal gradient of pressure correction is 0 here also. So, after starting with the finite volume method moving on to formulations for both semi explicit and semi implementation the semi explicit as well as semi implicit method then discussing the implementation details of the semi explicit method with pseudo codes finally, let me discuss the solution algorithm. The solution algorithm for semi explicit method is that we start with the user input which is common to all the solution algorithm discussed in the earlier lecture that is material property, thermo physical property, geometrical parameter, maximum number of control volumes in x and y directions what is the type of boundary conditions and what are the input corresponding to a boundary condition this epsilon which are two things here which is converges criteria as far as mass balance is concerned and it is a steadiness criteria for steady state. If you want to stop your computations then grid generation we calculate all the geometrical parameters delta t if you are using a semi explicit method I had mentioned that we do not have a one equation for the time step restriction in a semi explicit method in case of new stoke equation. We have one equation for pure conduction we have one equation for delta t as a function of delta x and delta y and u velocity and v velocity of the grid point for pure advection. So, for pure conduction and pure advection we have separate equations. So, we calculate one delta t for pure conduction pure diffusion in this case second time step for pure advection. So, we get two time step and we take the minimum of the two known that these are just as a guidelines they are not sufficient or guaranteed that they will work because this new stoke equation is not pure diffusion equation it is not pure advection equation it is the combination of the two, but we do not have we cannot do stability analysis for this non-linear equations. So, that way delta t is calculated I had discussed this in detail in the chapter of computational heat convection set the initial condition for phi which will be u velocity v velocity and temperature set the boundary condition. When you go for the next computation set the value as a old value then first taking this phi as u there will be one sub routine for advection flux diffusion flux u send phi is equals to u gamma is equals to dynamic viscosity c is equals to 1 calculate fluxes in the x and y directions using velocity of the previous time level calculate the total force acting in the x direction as a source term calculate total advection total diffusion and predict u velocity similarly do for v velocity. So, for v velocity repeat this step 7 to 10. So, with that you have predicted u velocity and v velocity and then you check how much is the mass imbalance if it is close to 0 then you have got the correct velocity. Otherwise calculate pressure correction as a function of mass imbalance add that pressure correction to the previous pressure and get an updated value of pressure. So, this is the pressure tuning which is happening once you get a new pressure then the mass flux correction then there is a velocity correction from which you can calculate the mass flux correction by which the mass flux predicted mass flux is updated when you update the predicted mass flux you get a new mass imbalance here note that you have to go back to step 2 and this step 12 to 15 continues till mass balance occur and then this predicted. So, once you have obeyed the mass balance the predicted star velocity which you have obtained that become the velocity for the next time step. Then you solve the energy equation if it is a force connection problem and you check for steady state otherwise go to step 5 and continue till steady state. So, after discussing all the formulation as I say that even if you use all this formulation implementation detail solution algorithm you will develop a product. What is that product? A CFD software, but to make it to a CFD software here what I am discussing is what are the main core things as far as fluid mechanics and heat transfer is concerned. To convert into full-fledged software you need other things also which are more related with the computer science aspects, but once you have developed the core of the which are related with fluid mechanics and heat transfer as far as programming is concerned you have to test it then only your product will be accepted by the people in the market. So, that is what is called as test problems or benchmark problems. So, yesterday in the lab session you have solved this problem. We have given you the product which is the code which is the set of programs and you have solved it for 4 different cases. First isothermal flow where there is no heat transfer everywhere temperature is ambient and then convective heat transfer problem 3 different types of convective heat transfer problem. Force convection which is a approximation what is the approximation in force convection? Buoyancy induced flow is negligible as compared to the force flow and in this case there is a one way coupling between the momentum and energy equation. Energy equation is anyway dependent on the flow, but the flow is not dependent on the heat transfer whereas, in case of mixed convection both fluid flow and the buoyancy induced flow are of comparable magnitude. In this case in the momentum equation there is a source term which is a function of temperature whereas, when you go to the natural convection the buoyancy induced flow is dominant. So, you have solved various problem corresponding to this force situations after the t break I will discuss this various problems one by one and before I end I would like to say that sorry you have to appear for the quiz yesterday twice due to some problem in the our server we sincerely apologize for the inconvenience. Many of you might be feeling that you had completed first time and you had to appear second time. This is just to we had certain issues as far as grading is concerned. So, that is that was the reason you had to go through the second time also as there were many questions there were total 45 questions and you have to and the questions were randomized and you have to solve 30 questions. So, probably when you had appeared for the second time at least few of the questions were new to you even if it was a repetition I hope you would have been refreshing or reemphasizing the concepts which you had learned. I hope that the quiz the problems in the quiz will help you in better understanding of what is been taught here. We are on the topic on solution of neostopic question on staggered grid. Now, we will discuss some test problems which you have attempted in yesterday's lab session. The objective of showing this is also because there were many requests from you that we should if we can highlight the research opportunities as well as aspects in computational fluid dynamics. So, as the primary objective of this workshop is on teaching. So, we would not be able to showcase whatever CFD research we are doing for that you can refer to our research paper from our websites. However, we would highlight certain aspects as far as research in CFD is concerned through this problems. There are two aspects of research in computational fluid dynamics CFD development where you come up with a new method for a particular heat transfer or fluid flow problem or improve an existing method. And the second aspect is of research in CFD is CFD analysis that is once you have developed a code for a software you run that for some problem you set up a problem set up a domain generate grid and then each problem has certain governing parameters. Note that in research we do non-dimensional analysis. So, there will be certain non-dimensional governing parameters and you might have noticed that in the four problems which you had solved in yesterday lab sessions the problem was proposed in a generic sense where there were certain things which was explained to you that what is code validation what is benchmarking. It was also mentioned the governing parameters which are involved in the various problems discussed here which will be discussed here was shown to you the Reynolds number Grashof number Prandtl number and yesterday lab session you had solved using non-dimensional analysis. So, each problem like flow across a cylinder if you consider what are the governing parameters what are the non-dimensional governing parameter for flow across a cylinder the non-dimensional governing parameter is Reynolds number. So, one of the CFD research as far as that problem is concerned is people vary that Reynolds number and then they try to see two things that the capture let us a CFD movies for velocity distribution, pressure distribution, water city distribution amidst the heat transfer problem temperature distribution and then try to have a physical understanding of the flow physics understanding of the flow physics you will get different types of flow structures. What is the role of this flow structures on the engineering parameters this is something which is always aimed at. So, any CFD studies which you do the overall objective the bigger objective is to study the nature or characteristics of the flow structures characteristics of the flow which is reflected by the flow structures and try to correlate because what happens is that depending upon the range of governing parameter you may get certain let us a reduction in drag force or increase in lift force. Now, the reason why that reduction or that increase is happening as a part of research we try to investigate the flow structure and the objective is to connect the flow structure to the reason why increase or decrease of engineering parameter is happening. So, the first problem which you had solved in yesterday's session was an isothermal flow problem lead driven cavity flow which I had explained in my earlier slides note that the characteristic length scale taken here is the size of the square cavity note that the length and height of the cavity is same the characteristic velocity in this problem is the velocity with which lead is moving in this problem there is only one length scale and only one velocity scale. So, it is easy to decide what is the characteristic length scale and characteristic velocity scale, but there are many problems or most of the problems in real world you find there are more than one length scale like if you take flow across a cylinder in a pipe or in a plane channel there are two length scale let us say diameter of the pipe and the size of the cylinder. Now, you when you take up that problem one confusion which is there is whether you should take the diameter of the cylinder as the characteristic length scale or diameter of the pipe as the characteristic length scale. So, in that case what you do is that you try to see whether the pipe is very far away from the cylinder then the diameter of the cylinder is a good characteristic length scale, but if the diameter of the pipe is slightly more than that of the cylinder then probably you should take the diameter of the pipe as the length scale and many times what we do is that we look into the research paper on that particular problem and from there we try to take an idea or guideline that what is the length scale he has used and accordingly once we are convinced we use that as a length scale or a velocity scale. Now, whenever you do a CFD analysis so, once you have developed a code tested a code you take up a problem and then you run your code and in general there are two types of results. First it is called as a qualitative results where we create movies for let us say velocity vectors, streamlines right now here what I will be showing you is the steady state profile. So, this pictures or if you create a movie that is animation this gives us qualitative information ok. Here I will show you the variation of u velocity along the vertical center line. Let me go to the previous slide and then discuss how is the nature of the flow in this case the lid is like a conveyor belt which is moving from left to right. So, the top wall is having a velocity u naught now that we had I had taken this example when I was discussing physical interpretation of kinematic viscosity where I talk about penetration depth where I said that if the depth of this cavity is infinite then this momentum is penetrated up to certain depth at certain time step. However, with increase in time that penetration depth increases and I had mentioned that penetration depth is directly proportional to square root of kinematic viscosity. So, the momentum is diffused or penetrated to the bottom layer and the fluid moves with the maximum velocity at the top at the corner it cannot go out. So, it turns when it turns it goes downward but there is a viscous resistance from the bottom fluid which is stationary. So, there is a second turn and you get a clockwise vortex. When there is a clockwise vortex in this there is this is called as a benchmark problem because whenever we develop our code we compare our results with an accurate experiment with an accurate experimental or numerical result. So, for this there is one result which is considered very accurate which is which was published by Gia and Xin and the results which they have given in a tabular form which we can use for comparison is the variation of u velocity on vertical center line. So, this is the vertical center line passing through the cavity. So, as you move from bottom to top what will be the direction of u velocity of course on the top portion it will be in the positive x direction because it will have we having the effect of this conveyor built and what will be the velocity at penetration depth at slowly this velocity will keep reducing and as you know that there is a clockwise vortex. So, on the bottom half the direction of the velocity will be negative. So, on the top portion you have a positive velocity and on the bottom portion as there is a clockwise vortex it will be negative. So, there is change in the direction of u velocity from positive to negative as you move from top to bottom in the vertical center line. Similarly, if you look into the variation of v velocity on horizontal center line. So, on horizontal center line when you have a clockwise vortex near to the left fall the direction of v velocity will be upward positive and near to the right fall the direction of the fluid will be downward. So, there is change in the velocity as you move from left to right on the horizontal center line for v velocity as initially the v velocity is positive then it becomes 0 and then it becomes negative. So, other than this plots we generate data from our in house code which we have developed through the formulation implementation detail solution algorithm discussed here and compare our result with the published result. Right now the result is shown for 3 different grid size note that in yesterday lab session you had solved the problem on a very coarse grid size. This is just so that you should not feel that it is taking 2 time and you become impatient we have given you a grid size. So, that you get a quick result, but in that lab sheet I had written that if you want a very accurate solution you have to be patient and you have to keep running the code for a long time. Maybe you can start the code even in the night before sleeping and you can watch the result after in the morning. So, it may take as large as time as this note that the psi lab the program we had written in psi lab one of the primary objective is that this is an open source software first and second it is easy to go through the programs in psi lab it is almost like a pseudo code. The programming language in fact is very easy and in fact it is very easy whenever you run the psi lab the psi lab is very much similar to the commercial software MATLAB and it is not only easy to program actually here one good thing is that you do not have to declare variables it automatically takes the size of the variables like in photon or C you have to declare whether it is an integer or real whether it is a single precision or double precision you have to declare the size of the variable if it is a matrix. So, all those things you do not have to do in this programming language so with this psi lab you can understand the program. However, as compared to the conventional programming language like C and FORTRAN I would tell you if you develop the same program in C or FORTRAN it will take less computational time as compared to the psi lab code the reason being this psi lab the way it runs the code is that it does not creates an executable files and every time it loads all the variables and runs in each iteration so it takes more computational time. However, the objective was to get you started as far as programming is concerned and we believe that you should be able to convert the psi lab code into let us say C C plus plus or FORTRAN whichever language you want to convert to and in fact one another good thing about this psi lab is that when you are developing a program like if you want to if your result is not coming what you do is that you try to insert print statement in between the lines in the program you have to insert write statement in the C language and FORTRAN language to print some variable but here in psi lab you do not have to do that you just have to write the name of the variable in the command window because once this is run all the variable is stored in its memory so that is why it takes more computational time as compared to C program or FORTRAN program for the same method whether it is a conduction, advection, convection or navistoke. So there are certain disadvantage of whether you use a psi lab or MATLAB versus C program or FORTRAN program but we felt that right now our objective is to make you understand taking some simple CFD problems so that is why we decided that you will develop program in psi lab another good thing is that we had a problem that if we had given you code in C or FORTRAN then you need another software for plotting otherwise we have to develop the graphical user interface in our program which is more of a computer science job which we normally do not do so that way we decided this psi lab is another good thing is that it has its own inbuilt graphics so that way we decided upon this now this is the steady state result. Now what are the things which you are seeing in this figure there is a color, there is a white line and there are arrows there are three things what does the color represents? Color represents flooded contour of steam function line represents stream lines along with their values and the arrows represents which is what is called as vector plot what is this vector plot? Once you let us suppose you have obtained the steady state velocity distribution you let us suppose you have 100 points in the domain so you get 100 u velocity 100 v velocity and corresponding to those point there is some x coordinate y coordinate so you have 100 x coordinate 100 y coordinate 100 u velocities and 100 v velocity this is the numbers you have got which you have stored in a data structure matrix. Now what you do is that you take this data to a plotting software like if you are in psi lab as when you run it stores in the memory it is already there in the memory so in the program if you use a plot command it plots it otherwise if you are using a program C or FORTRAN as a programming language and if you have not developed graphical user interface then you store this data in a data structure which is required by a particular graphical software and then you take it to that software plot it and then visualize the result. So with that data when there is a velocity distribution what vector plot represent is that at different grid points if there are 100 points corresponding to those 100 points when you talk of velocity it is a vector quantity and vector we represent by some magnitude direction and sense. So what this software graphical software does is that it does some scaling okay maybe let us say the maximum value of the data maximum value of the resultant velocity it does a scaling let us suppose that will be represented by 1 centimeter and with that relative scaling depending upon the magnitude of the resultant velocity it creates a length of this vector and as each point not only we have magnitude we can calculate the orientation of the vector also. So the software does that also and then draws the at each grid point vectors that is what is shown in this vector plot many a time this vector plot if you draw you do not get a good feel of the flow structure most of the time you get an idea that okay at some location the velocity is low here you can say that the velocity is low in the bottom region velocity is high in the top region but as far as the overall idea about the vortex formations many a time you have a very fine grid and this vectors fills the region completely this arrows overlap over each other in space. So it becomes very difficult to understand so that is why in fluid dynamics a CFD one picture or one movie is not sufficient to give us the complete story about what is happening to the fluid flow. So if you want to know if you want to understand the vortex it is better to draw the stream lines for that what we do is that we post process this velocity information because you know what is the relationship between a stream function and a velocity like u is equals to del psi by del y. So what we do is that we do a numerical differentiation and we express psi 2 minus psi 1 is equals to once you know the velocity you do the numerical differentiation and you can calculate the stream function values at different normally the way we do is that we calculate if either velocity are defined at the centroid of the control volume then we calculate the stream function at the phases of the control volume phase centers of the control volume once you have so stream functions are calculated by a method which is called as post processing. So once we have got the converge let us say study state solution then we used the discrete form of the expression for stream function as a function of velocity gradient and we calculate let us see if there are 100 point we calculate the stream function values and then once we have got that data we take it to a software and we use a command what is called as contour command and then we get the stream lines. So this is the way it is drawn so from the stream lines one thing which you can see is that there is a although the stream line is not showing you the direction whether it is a clockwise vortex or is an anticlockwise vortex that you get from vector plot. So some information is given by the velocity in for vectors some other information is given by the stream line. The story about the characteristics of the flow we get different stories or different aspects of the characteristics with different types of plot this is what you can understand and appreciate through this figure. Right now I am showing you for a particular problem but this is applicable what I am discussing is quite generic in nature and this is applicable to any CFD problem when you are doing a CFD analysis note that you can use a CFD software or CFD code which you have developed you can know what are the governing parameter like in this case I can say the Rinal number is the governing parameter note that in earlier in the lab session we had told you to run the code on to Rinal number. So like a so if you want to do a research you can keep increasing the Rinal number from 100 to 400 to 1000 and you can what you will slowly see is that the size of this here you will see there is a corner vortex which is formed the size of this corner vortex will keep on increasing with the increase in the size of the Rinal number. So with the increase in the governing parameter you see that change there is a change in the flow structure now this change in the flow structure has a creates its effect on the engineering parameters like what is the engineering parameter in this problem wall shear stress near to the bottom wall top wall or let us say top like if there is a conveyor belt there is some energy which is spent in moving this conveyor belt and there is a resistance there is a viscous force which is opposing its motion. So let us say there is an engineering parameter that how much energy needs to be spent to move the conveyor belt and as you increase the Rinal number the velocity gradient near to the wall of the conveyor belt will increase so the shear resistance will increase. So that is the engineering parameter in this problem note that this engineering parameter varies from problem to problem like flow across an aeroplane it is a lift force and drag force which is there for most of the external flow problem and for most of the internal flow problem the wall shear stress whose non dimensional representation is a skin friction coefficient is an engineering parameter. Also when you have an open domain internal flow pressure drop is an important engineering parameter okay all this engineering parameter are obtained once you have obtained a convert solution of the velocities and pressure distribution by doing numerical differentiation to calculate the local values like at the wall if I want to calculate the wall shear stress analogously we had calculated the local heat flux at the boundary grid points in case of conduction problem. So to calculate local heat flux at the boundary grid point or local wall shear stress at the boundary grid point you have to do numerical differentiation because heat flux and wall shear stress are expressed by Fourier law of heat conduction and Newton law of viscosity where they are expressed in terms of gradients of temperature and velocity respectively. Now here you are having number which are discrete and although the expression is a differential expression you have here you have to do numerical differentiation. Now when you want to calculate total shear force let us say in this case or total heat gained by conduction from a particular wall when you want to calculate total value then you know that you have to do integration and as the data here is discrete you have to do numerical integration. So in a numerical method course it is a good idea that when you are teaching a topic on numerical differentiation or numerical integration you take example from fluid mechanics and heat transfer. In fact here we have two courses first course which we call as computational methods in thermal and fluid engineering where we teach all this numerical differentiation, numerical integration solution of linear algebraic equations on the first half of the course. In the second half of the course we teach complete finite difference method applied to starting from pure conduction and then moving on to steam function vorticity formulation and even near stoke equation on staggered grid. And we have a second course which we call as computational fluid flow and heat transfer computational fluid dynamics and heat transfer where we teach finite volume method. So whatever I have taught here it constitute approximately 40 to 50 percent of that course and another 50 percent consist of solution of near stoke equation on a collocated grid complex geometry formulation grid generation. So this is the figure showing the results so the using all the details which have been discussed earlier code is developed and that code is run on three different grid sizes. Here right now variation of u velocity on vertical centre line is shown you can see on the bottom half u is negative and on the top half u is positive as per our expectation. Grid line represent the results obtained on a grid size of 11 by 11, green line on a grid size of 31 by 31 and blue line on a grid size of 15 by 15. Now what the purpose of this figure is to show you that as many of you are asking question that how do we know that what is the grid sufficient grid. As each fluid dynamics problem has its own action I had answer that we do not know how much grid is enough because that enough word is a relative word. I had given an analogy that let us suppose you want to capture some phenomena which is changing with respect to time. So let us say water flowing in a river versus let us suppose an explosion now to capture if you want to create a movie you need a video camera which is a very fine very large frame rate to capture the details of the explosion how the shock is generated during explosion. Whereas, even with a normal camera you can at least pictorially get the flow of water in a river. So analogously here each fluid flow situation has its own action. So how much frame rate you need how much pixel or resolution or grid size you need for a particular problem you do not know a priori most of the time. You try to take guidance from the published literature where someone has done earlier taken the same problem although he may have done for some other governing parameter. So you can get guideline from the previous published results but you have to do this exercise to convince people that the results which you have obtained is accurate enough. Note that in a research paper code validation even if you are using a software the people who have developed the software they might have validated but when you are using you have to show that you are using the software correctly. So even if you are using a software and you are doing a CFD analysis if you want to publish your result in an international general conference there are two very important things which you have to show to convince people in your result. First is code validation which I am showing you in this slide and second is grid independence which also I am showing through this slide. So both the things I am showing through this slide. So here what is meant by grid independence is that as you refine the grid it can be seen that the difference between the results between 31 by 31 is large and the difference is negligible between 31 by 31 and 51 by 51. So you can write down that 31 by 31 is small enough to obtain the results which are accurate enough and obtain the result which is called as grid independence solution. This black circle are the results which have been taken from a research paper which is commonly used for code validation and you can see that the blue and green line are lying almost on the top of it. So this way you can convince people that you have got an accurate, your code is giving accurate results and if you are using a software you have to convince that you are using the software correctly because this software usage there is lot of things which requires understanding. As I had mentioned that for flow across a car and a rail plane if you take the size of the external size of there are two boundary for such case inner boundary which is covering the surface of car or a rail plane and outer boundary which is the far field boundary. Now if your far field boundary is too small then the effect of boundary condition from the far field will distort the result near to the solid boundary. So you also have to show domain size independent study in that case. So these are some of the things which comes because as you know theory is something which nobody believes except the person proposing the theory and CFD is of course a theoretical method. So these are all the things which we do like grid independence, code validation, domain independent study if it is a transient problem, time step independent study also to convince people that whatever results you are obtaining is accurate enough. Once you have convinced then you can start with two aspects of the study. First is the scientific aspects where you look into the pictures or create movies for the flow and try to have a qualitative description of the characteristics of the flow, quantify the structures of the flow and then you second aspect is you do a quantitative analysis where you plot results which I will show for this problem in the next slides. In this figure what I am showing you is the code validation but here it is a variation of v velocity on the horizontal center line. Now here again you can see that the result obtained by 11 by 11 grid, the difference between the result on 11 by 11 and 31 by 31 is large whereas the difference between this blue and the green which is obtained on 51 by 51 and 31 by 31 is less. So this shows that as you refined the grid there is a change in the result but the change is asymptotic in nature. What is in asymptotic? Note what is the difference between 11 by 11 and 31 by 31, 20 is the difference in the so 20 nodes you are increasing in the x direction when you change from 11 to 31. When you change from 31 to 51 again you are changing the 20 nodes but the change in the results which you see initially there is a large change and that change slowly dies down as you refine the grid. So the difference asymptotes so that is the nature of which of the grid refinement. So the change should be monotonic and it should asymptote. So that was about the qualitative analysis. There is a second aspect of the study which is called as quantitative analysis. So CFD has two types of analysis, qualitative analysis and quantitative analysis. Qualitative analysis we write which results which we use for qualitative analysis, pictures or movies of the flow field and in quantitative which results which we discuss we discuss engineering parameters. Like in this case variation of skin friction coefficient, the skin friction coefficient is non-dimensional wall shear stress. It is expressed as tau w divided by half rho u0 square u0 is the lead velocity. So variation of local skin friction coefficient along the different poles of the cavity at 52 by 52 grid is shown here. Variation of mean skin friction coefficient on different walls of the cavity. So this is the local value, this is the mean value. Next slide shows you the local value. This is the non-dimensional wall shear stress variation on the left wall. The green line represent the same parameter on the right wall. You can correlate that why this is positive and why this is negative by carefully looking into the direction of the velocity near to the respective walls. Now on different grid sizes, this corresponds to the grid size of 12 by 12 where delta x is 0.1, the domain size is 1, so 1 divided by 10 it is 0.1. This is the grid size for 1, 32 by 32, so 1 divided by 30 is this. So the grid size means delta x which is also equal to delta y for the present problem. So as you refine the grid, what you see is that there is a change in the results. So here again we expect that the change in the results should asymptote. That was for as an isothermal flow, there had shown a much more details of the result. In the other problem I will just show you the physical description of the problem and the mathematical equations. I will not discuss the results for the remaining problem. So here the problem which I had discussed earlier was isothermal flow. It is the same problem, now the difference is left wall, bottom wall and top wall the boundary condition is that they are maintained at a temperature which is less than the that of the hot wall, the top wall is hot as compared to the other walls, constant wall temperature. Now in this case note that you have a force flow, why there is a force flow which is created by due to the motion of this lead. If this lead is stationary then it becomes a natural connection problem. As this lead is moving, if it is moving with very large velocity and if the temperature difference is small then it can you can even neglect the buoyancy induced flow and it will become a force connection it becomes a problem. Whereas if the temperature difference is large buoyancy effects will be more and if there are not number is also large both effects will be cannot be neglected and then it becomes a mixed connection problem. Whereas if the wall this lead is stationary then the force flow you do not have any force flow and then you have only buoyancy induced flow then it becomes a natural connection problem. So, for this case which is a force or mixed connection it transfer problem where we are having lead which is having non-zero velocity this is the governing equation for which you have been given the lab sheet. So note that here in this case what is the diffusion coefficient 1 divided by a non-number for momentum equation and what is the diffusion coefficient for energy equation 1 divided by a non-number into Prandtl number. What is the body force term when it is a mixed connection problem? Note that here momentum equation has a temperature term so now it has become two way coupling. Velocity depends on temperature temperature anyway depends upon the velocity. In force connection case this is close to 0 so I think in your lab sheet you have to solve one case where Grashev number is 0. Grashev number is 0 means this term 0 then it becomes a force connection it transfer problem and for non-zero values of Grashev number then it becomes a mixed connection it transfer problem. And these are the expression Reynolds number is ratio of inertia force to viscous force Grashev number that of buoyancy force and viscous force. You also have a Prandtl number as a non-dimensional governing parameter. So if you want to study this problem you have let us say three tuning parameter. What are those three tuning parameter? How do we decide that how many parameters we have by looking into this non-dimensional equation and non-dimensional governing parameter? Note that there are two types of parameter governing parameter and engineering parameter. Engineering parameter is an input parameter engineering parameter is an output parameter. So Reynolds number is one non-dimensional governing parameter Grashev number is a second and Prandtl number is the third governing parameter. So if you want to do a detailed investigation you need to vary the Reynolds number, Prandtl number and Grashev number and you can do a detailed scientific as well as engineering study analyzing the qualitatively and quantitatively. Now here there is no lead, top wall is also stationary. Now this has become a natural conduction heat transfer problem and the boundary condition which has been given is top wall and bottom wall there is a constant heat flex. Left wall is at hot temperature is more as compared to the right wall. Now note that in earlier case actually I had not written here non-dimensional temperature but this is mostly defined as T minus T H divided by T minus T H divided by T C minus T H. You can define in different ways the two ways is that in one case you will get a non-dimensional value of temperature as one on the top wall hot wall and zero on the cold wall. You can define in another way also where you can get one in the cold wall and zero in the hot wall. Now here the non-dimensional in natural convection as lead velocity, lead is not moving all walls are stationary there is no characteristic velocity as far as the problem is concerned. So in this problem we have defined characteristic velocity as alpha divided by L. What is alpha? Thermal diffusivity and the length scale is the length of the plate and in this case when you do non-dimensionalization considering this as the non-dimensional velocity you end up with this non-dimensional equation and in this non-dimensional equation the non-dimensional governing parameters are two parameters one is Rayleigh number and second is Prandtl number. So with this I had come to the end of this topic.