Fiery horse with the speed of light, a cloud of dust and a hardy high old silver. The Lone Ranger. With his faithful Indian companion, Tonto, the masked rider of the planes led the fight for law and order in the early west in the United States. The stories of his strength and courage, his daring and resourcefulness have come down to us through the generations and nowhere in the pages of history can one find a greater champion of justice. Return with us now to those thrilling days of yesteryear. From out of the past come the thundering hoofbeats of the great horse Silver. The Lone Ranger rides again. The langeman's steel and breed Gomez kept to the back trails as they headed south for the border. They were travel-stained and weary, their mounts were jaded, but they kept on doggedly mile after mile. When night comes we will be at the Rio Grande and the other side is Dos Brazos. We shall be safe there, senor. Safe? It's better to be safe than sorry. They're not finished yet, Brit. No, you'll start over again in Mexico. They have much money with you. You will find many chance to make more across the river. They won't be able to make more than I did in Tomahawk basins. It's better for you to forget Tomahawk Basin. Now that derelict talk to the lor, you are wonderful mother. I'm going back. Carloco, senor. They'll put you in jail as soon as they see you. They won't see me until I'm ready. You are alone now. Do not forget that. All our men are in jail. A hundred of them. If I had them all together again, I'd play the game different. I'd drive the lor out of the basin and take what I wanted by force. Till your men are in jail. There have been jail breaks before. Oh, so that is what you plan. There are other things to consider. Your men will do no good if they do not have rifles and ammunition. We can get them south of the border. And horses, senor. There's plenty of horses in the basin. There's plenty of my own horses there. It's better for you to stay in those blazers. Not a chance. What about the lor range? We've been lucky to get away from him. He'll be waiting for us when we go back. That's the main reason I'm gone. I want to even the score with that ombre. All the men have tried that. Hold up a minute. Oh, boy, won't I? Reid, are you with me or against me? The way you're talking, I think... Oh, no, I am with you, senor Steele. I only ask you to consider. I have. The lor range won't stay in the basin long. The jailbreak can wait until we show you some places. And when it does show up, we'll be ready for them. See, that would make a great difference to have men behind you. A hundred.  Come on, hit up there.  A month passed. The Tomahawk cattle still roamed the range. The Tomahawk ranch was silent and deserted. Leadville had settled down into peace and security. When all men and uproar broke out in the crowded jail, the townspeople only smiled. Steele's outlaw crew was behind bars. The basin was safe for honest men and women. Oh, boy! Oh, there! Howdy, Jim. Howdy, chef. You're sure the picture of ambition? Well, there's not much else to do but lie around these days. Haven't any trouble with the prisoners? Not much. You heard anything from the Lone Ranger? There was a pilgrim rode through the other day. Said he was somewhere around Tombstone. That's a long way. Yeah. I guess we won't be seeing him anymore. Can't expect a man like the Lone Ranger to waste his time in Leadville. Too bad he didn't catch Steele while he was at it. Ran him out of the country. That's almost as good. Yeah, I guess so. I'll be seeing you, chef. So long, Jim. Get up, boy. Then came a week of rain. And in spite of the dam and the hills, the level of river that floats at the basin rose foot by foot. There was no alarm. If the river overflowed its banks, the cattle could be driven to higher ground until the flood subsided. And one night, as the sheriff was standing at the bar in the crowded cafe, a new sound was added to the noise of the wind and the rain. A muffled explosion drifted down from the hills and then afterwards, the roaring of the flood waters. Man, that sounds to me like the dam's roar. There's a flood on the way down to the basin and there's still a lot of cattle near the river bank. I'm calling every man who can ride a horse to follow me and help the ranchers get their herds out of danger. Come on, then. In ten minutes, every able-bodied man in town was in the saddle and riding to the aid of the ranchers. Half an hour later, Benjamin Steele and Greed Gomez reigned up in front of the jail. It must be sold around, senor. You couldn't have picked up better night. This door will be locked. You can bring it in. The keys to the cells are always hanging on the wall above the sheriff's desk. Would you wade into it now? That's good. Come on, late to last. See, senor. It's a boss and Greed. We've come to let you out. How'd you manage it? We blow up the dam. There is a great flood. Everybody in town right out to help drive the cattle to higher ground. Here, breed with the others out. Oh, see, senor. I gotta hand it to you, boy. Here's a gun. I don't think we'll have any trouble getting out of town. This cattle horse is waiting to go. Where are we going? Back to the ranch? Not just yet. Only against an ammunition we brought from the south or up in the hills. That's where we're heading tonight. Tomorrow night, we'll move back to the ranch. Sheriff will be waiting for us with a posse. Yeah, he won't. We'll figure that you boys will get as far away from the basin as you can. Are you sure to find out different soon? As soon as I've got it. This is going to be a fight to resty. And we're going to win. We're going to run this county if we have to kill every rancher and cowhand in it. Are you coming to breed? They're all phenom. Let's go, boys. The rain's like them just before dawn. The sun rose in a cloudless sky. When the men rode back to town and saw the open doors of the jail, they realized a storm of a different sort was about to break. They had help from outside. That's sure. Can steel have come back here? I don't know. He has. He has. We're in for trouble. He's wanted for murder, and he won't stop at anything. Well, as soon as the boys have something to eat and get fresh horses, we're going out after him. You having a chance to pick up the trail? They must have broke out when it was still raining. There won't be any tracks. We'll take a look at the Tomahawk Ranch first. Then we'll ride up into the hills. Well, you'd better get back before dark. You can't leave the town or the ranches around here unprotected again. We'll be back. Let's hope we find them first. There's about 100 men in the gang. I know. There's more of us, but our places are scattered all over the basin. If they take us one by one, we're sunk. We've got to think of some plan. I wish the lone ranger was here. He'd come if we sent for him. There's nothing more he'd like than to put steel in jail. How about it, Jim? Would you go after him? Whenever you give me the word. Wait until tomorrow. We aren't sure yet. Maybe they just cleared out. Don't sound like steel. Wait until tomorrow. If we find any trace of them, it's up to you to bring the lone ranger Prado. Steel in his gang rode down from the hills that night, and three cowboys were unlucky enough to cross their trail. The outlaws asked no questions and were shocked to kill. In the morning, the cowboys were found, and Jim Kerry prepared to ride for the lone ranger. Tell them everything, Jim. Tell them how they're back at the ranch and they're fixing it up like a fort. Tell them what happened to Larry Oliver and Pete Smith and Johnny Day. You're not going to try and smoke them out? No, it costs us over a hundred lives. I can't take the responsibility, not when there's a chance of catching them in the open sometime. You're right. I don't have to tell you, Jim. You're taking on a mighty, dangerous job. I'll get away all right. One man's got more chance than six. And I couldn't spare any more than that. I know. Good luck, Jim. So long.  Well, let's hope he gets through. Two weeks later, the lone ranger and taller were heading east. At sunset, they stopped to cook their evening meal. They did not make camp for the night. A full moon and a cool breeze persuaded them to continue on their way. The trail led along a ridge. To the right was a valley long held sacred by the Indians. The lone ranger and taller could see their campfires and hear the throbbing of distant drums. Maybe better we ride to north. Bye, Kimosabi. Those Indians are friendly. Those aren't war drums. Well, that's right, too. Why should you be worried? Then make big dance to Moon God. This valley of Moon God. White man watch dance and die. If you aren't close enough to see it, the trail doesn't go down into the valley at all. You can see plenty far. Not that far. Better you not look that way. All right, Kimosabi. Now keep my eyes straight ahead until we get past the valley. Uh, it bad medicine for white man to watch dance. Moon God not like it. Kill him. Oh, I thought you meant the Indians would kill him.  Well, that's right. Then find out then kill him. Then not find out.  I didn't know you were superstitious. Can't you just tell story that all? I see. Well, I... Is that a silver? Is that a boy? Is that yelling part of the ceremony? No. Dance to Moon God. Dance a piece. Those are war cries. You may not like a tunnel, but we've got a ride closer and find out what's going on. Maybe so. There's a man riding towards us. His horse is tired. They're gaining on him. We'll ride alongside and he can get on silver. You've got the reins of his horse. Keep riding on silver. Get him on scouts. Don't you know me, bass man? I'm Jim Carrey. Jim Carrey from Tallahawk Basin, Kimosabi. Who's injured you're after my scouts? Swing free of your stirrups. You're changing over to silver. Shall I rain up? You don't have to. Just get your legs free. That's it. Hell, he's got the reins of his horse. He's got the reins of his horse. He's got the reins of his horse. That's it. I'll lean over and grab my shoulder. I'll help you over. We've got the reins of the sorrel tunnel. Oh, silver! Even with his double burden, silver had too much speed for the Indian ponies and soon left them far behind. When they were out of danger, the lone ranger, Tonto and Carrey, made camp and Jim told his story. So that's why I headed west to find you. If I hadn't found you when I did, I wouldn't have got any farther. You plenty lucky get away from the engine. I didn't know what they were up to. I just rode up to their campfire, hoping I could get some information about you and the lone ranger. You can forget about the Indians now. We've got to think about getting back to Tomahawk Basin. It's been two weeks since you left there. Yeah. You know, telling what's happened since then. Hello. Ah. Fort Union's a hundred miles north of here. That's right. You better ride there and tell the Colonel everything that Jim has told us. If he can spare some men, lead them to the basin. Ah. You ride on? Jim's horse is tired. We'll let him rest tonight, but we'll start out the first thing in the morning. The lone ranger and Jim Carrey made the trip to Tomahawk in eight days. Uncertain as to where Steele and his gang might be, they avoided the hills to the west and ended the basin from the south. Except for the cattle, it seemed deserted. A number of ranch houses had been burnt to the ground. There was no sign of life around there that remained intact, not even around Steele's place. On the masked man in the ranch erode toward Leadbill, at last they reached the outskirts of the town. The same here as every place else, Jim. Not a sign of life. And what's happened? We'll have to find out. Those cooks have wiped out all the ranchers and cowhands, and there ought to be some sign of them anyway. We'll have to be watching out for that sign. But they couldn't have. We had more men than Steele did. Well, a lot of fighting going on, Jim. That's sure. Look at the windows in that house. Yeah, every last one of them broke. Zeke Mason lived there. If Steele felt strong enough to attack the town, then... Yeah, it looks bad. We're very silver, steady boy. What's he acting up for? He must have a reason. See, there's some horses out in front of the cafe. Yes, Jim. And saddled. That means there must be somebody inside. Let's get a move on. Steady boys, steady. Zover doesn't want to go on, Jim. There's something wrong up ahead. Well, we've got to let him. Wait. Door of the cafe's opening. There's some men coming out. Hello there! I've brought that own ranger! A thousand dollars to the man who brought him in. Steal him! Steal his gang! Right, Jim? Get up, Red! Let's capture the town! Come on, Silver! The curtain falls on the first act of our Lone Ranger story. Before the next exciting scenes, please permit us to pause for just a few moments. Now to continue our story. As a Lone Ranger and Jim Casey wheeled their horses and raced out of town, the rest of Benjamin Steele's outlaw army poured from the cafe and sent a hail of bullets after them. The masked man on the rancher made their escape. The last Steele called a halt. Enough! They're out of range. It was a Lone Ranger. There is no doubt about that. You don't have to tell me. That was Jim Kerry with him. He brought him from the west. Does this change your plans? I should it. What do we want with the town? Yeah, it's true. It will be hard to defend. I guess too. All I say is, what's the use of it? We got most of the supplies that were here out to the ranch already. Rusty. Here? Get those wagons around in front. Get them loaded with the gold and the rest of their stuff we can use. Key no, boy. Make it fast! As soon as they're all in for age, you can carry out the rest of my orders. Yes, sir. We set fire to the town. The sun had already set when the Lone Ranger and Jim Kerry rained up on the high ridges that overlooked the basin. They started to make camp, but suddenly a bright glare lightened the gathering dust below them. It's fire! Yes. They're setting fire, the town on fire. They've decided not to stay there. The ranch will make a better stronghold. This is the end of Leadville. There was never much to look at, but it was our town and... oh, golly. I understand how you feel, Jim. If only there was something we could do about it, you and me. What's happened to everybody? My daughter and Abby and Ted Bailey in all my hands. Have they been killed? Have those crooks murdered every honest man and woman in the basin? No, that can't be Jim. Then where are they? Quiet. I can't be quiet. Listen, Jim. Somebody's riding this way. Right out to this point. It's the sheriff. You're right. Sheriff! Who is it? Jim Kerry! Oh, oh boy. Oh, oh boy. Howdy, Jim. So you got through and found the Lone Ranger. I was worried about you. Quick, Sheriff. Tell us what's happened. They've set fire to the town. It's my fault. All my fault. I waited too long. What do you mean? You know, I was afraid to attack the Tomahawk Ranch when I had all of our men together. Then I couldn't hold them together. One after another, the ranchers took their crews back to their own spreads. That's just what Steele wanted. He went after them one by one, burned them out, drove off their cattle. Well, Abby and Ted, are they all right? Yeah. Where? Back in the hills. We didn't try to defend the town. There were too many women and children there. We didn't have as many men as when we started out and Steele was getting reinforcements every day. He's still getting them. He was in Texas. What did you do, Sheriff? I ordered everybody to load what they could in the wagons. And one night when there wasn't any moon, we started for the hills. He gave up without a fight? Oh, no. The town had been raided two or three times. Now it's all finished. We might just as well keep on moving. Give up the basin and head west. What do you say to that mess, man? You aren't giving up the basin for long, Sheriff. There's help on the way. Help? Troops from Fort Union. How many? As many as a colonel can spare. It may take them a few days, but they'll get here. You are sure. The colonel has orders from Washington about Benjamin Steele. A few days, huh? Are you safe for that long? It's hard to tell. Steele's men haven't come into the hills yet. We still have arms and ammunition, but we could be attacked all right. I've been hoping they'd think we cleared out for good. Thank you, sir, the camp. We'll have a look around. Well, I'm turning everything over to you. Whatever you say goes. Men and women from the basin were camped in a high valley. Sheer walls of rock protected them to the north and south, and ridges swelled to the east and west. It was on the crest of the eastern ridge that the lone ranger conferred with the sheriff and carried the following morning. You picked a good spot, sheriff, but you can't expect to hide. Those outlaws working for Steele know the hills better than you do. I guess you're right. The valley can be defended, though. Whatever you say goes. We've got to get to work. Guards must be posted on this ridge and the one to the west. There's no cover up here. You'll have to build earthworks. Call the men together and we'll get started right away. It was late that afternoon that Rusty pulled his Mustang to a sliding stop, slid from the saddle, and ran up the steps to the Tomahawk ranch house. Boris! I found him! That's fine. I had a hunch he was still there. Yeah, but where? You know the valley high up. I'll draw you a map. Yeah, it is pencil and paper. The lone ranger's there with him. I guess he's getting them organized to stand off and attack. We'll have to move fast. What's that you're working? Sunset peak. The valley's a half a mile to the north. I know. You're right to the top of the ridge and there it is. That's right. We'll line up there a minute at the top and stand us off. They haven't got as many as we thought they had. And I got an idea right back here, boss. Well... We go after them just to dawn, just as it's getting late. Yeah. First, we send about 20 or 30 men at the west slope. They can get around there when it's dark. But that's just a fake. See, to draw them to the west ridge. We hold most of the boys to blow the east ridge. And when we hear the shooting on the other side, I'll bet we can ride straight to the top. After that, it's simple. We'll try it. It's plenty of time to get ready. Pass the word to the men. Easy, boy. For all the minute they're post-sheriff. Yeah. They didn't like it much. Rolling out of their blankets so early. You can send half of them back to Edison as soon as the sun's up. If Steele tries to get us to date, we'll be in the next few minutes. What do you think? We have to be ready for anything. Just a few more minutes before it starts getting light. Yes. I'm going to ride along the ridge and see if I can... Listen. From over west, they're coming up the west slope. The question is, how many? Must be all of them. I don't see or hear nothing down below here. It's still too dark to see. Had we better send the men on this ridge over there? No, Sheriff. We're enough there to hold it. We can't afford to leave this side unprotected. But there's no sense in trying to... Yes, there is. Listen to that. Most of the gang are attacking here. Open fire, man! Rusty's plan to surprise the defending ranchers failed, and the first attacks were beaten off on both slopes. But they rallied for a second charge, and the second wave almost reached the top before it was driven back. At that moment, the ranchers were surprised to see the great horse Silver jump the earthworks and charge down the slope. The lone ranger urged him on without laws, and he decided of him. Fire in the air, boys! What's it mean, sir? What's he up to? Keep firing, men, in the air! He's going to make it, Jim. Well, I double savvy. He can't be running away, and if he's trying to capture all of them, it's just plain local. They're so anxious to find cover they don't even know he's riding with them. He's ahead of all of them now. They're sure to recognize Silver, isn't he? No, you see? He's cutting to the trees just as they open fire on him. But what for? Why did he do it? Steel isn't with his men, Jim. The lone ranger's gone after him. How did he send a horse today, boys? His horse and the corral. He must be here. Who's there? Your covered steel. So it's you, eh? You've been got beaten right away. My men aren't beaten, but you're going to have a part in a fight.  You're coming back with me to the hills. No, I'm not. Don't forget that I know a lot about you, mister.  That might not be true in your case. I'm going to gamble on it. And it sure don't hold for me.  Well, you talk too much. Well, you had to be tied up sooner or later. And just as well be now. Hold your fire, men. Here comes the lone ranger up the hill. Why don't the outlaw's fire it? Don't you see? He's got steel. Hey! Stand back, men. He'll be jumping over the earthward. Easy, boys. Easy. Sit over there. The holiest of you, Sheriff. He's him down to the ground. We got him? Yeah. Now then. What are you going to do with it? That depends on you. All of your men are down at the bottom of this slope.  What if I refuse? And I'll turn you over to someone else. All right. Let the Sheriff arrest me. Not the Sheriff. I'll turn you over to the men whose homes you've burned. No, you can't do that. I'm waiting. You don't have long to make up your mind. All right. All right. I'll tell them. Breed. Rusty. Tell the boys to throw down their guns and surrender. What is that?  March up the hill with your hands above your head. What about it, Breed? Are we going to do what he says? Yeah, why should we? He's our boss, ain't he? Is it for him to say that we go to jail? Then perhaps we hang? No.  No. He will come to us. Let them kill him. We will do the same for them. We almost reached the top last time. See? Open fire, man. Into your shadows. Return. It didn't work. They're coming after us again. For the linehold? We've had to send some of the wounded, man, down in the valley. We're strung out pretty thin, Mass Man. They can mass our force when we see where they attack. Hey, what's that? The cavalry. They're coming up to Western Ridge. The army, boys! Open fire on the outlaws. We don't have to hold out much longer. There's the flag coming over the top of the line. The wave of blue with the colonel, Tonto, and the color bearer riding in front swept down into the valley and on up the defender's position. The colonel and the Long Ranger spoke together for a moment. The bugle sounded once again. The cavalry swept over the earthworks. The outlaws' charge drove halfway up the slope. The sight of the well-ordered ranks let only one thought in their minds escape. It was too late for that. It was a sharp, brief encounter. The colonel's commands rang out before the gang realized what was happening. They found themselves completely surrounded by a swiftly closing ream of blue and steel. To a man, the outlaws surrendered. Their hands were tied behind their backs and they were herded down into the valley. There the colonel and the Long Ranger conferred. There's no jail in Leadville, colonel. The town's been burned to the ground. We'll take the prisoners back to the fort. That would settle everything. I don't have to tell you the steel must be sent to Washington. He's wanted for treason as well as murder. I know. That's all I believe, but I'd like to thank the Army for all the ranches in the basin. You've given them back their homes and their freedom. Seems to me the situation was well in hand when we arrived. We couldn't have held out much longer. Colonel told us when he reached the fort.  It was only a job that had to be done and done fast. But I'll tell the boys what you said. Thank you, everyone, unforeseen colonel. I shall. Are you going to be leaving us, Mass Man? I'll have to, Jim. Steel won't escape. You can be sure of that. There are still two more traders at large. You've got to start after them. The best of luck. Thank you, Colonel. Is that a big fella? Let's go, tunnel. Adios. Or you have just heard is a copyrighted feature of the Lone Ranger Incorporated.


So, what we will do is in the last class we saw a demo of the one-dimensional Euler equation right and we are looking at various behavior. There are certain things about the demo that I just want to recollect here, one we already know that there are three different propagation speed right. So, in the demo I took a constant time step everywhere, it did not look like right I took the delta x by delta t by delta x I kept it a constant which basically means that I was taking delta t to be a constant in the demo I took delta t equals constant. So, in a sense when I say delta t equals constant I mean delta t equals constant I should say delta t is in a sense homogenous that is delta t is a constant this may not make sense to you delta t is a constant across grids right or over grids. The other thing that we saw was that these waves were propagating we saw that the compression waves not necessarily corresponding to not necessarily corresponding to u plus a or propagating at u plus a but compression waves possibly corresponding to u plus a propagating at higher speeds one way and very fraction waves coming in the opposite direction right which were taking more time because they are propagating something like u minus a.  So, just to recollect what we did in the demo we had a simple pipe and we had a pressure here p0 and initially because the flow in the pipe which is of some length l and you have k ambient on this side I will indicate t0 here because we have the boundary condition but I am really interested in the pressure coming to equilibrium in this case in the demo. So, if you recollect the demo you had a compression wave that propagated left to right of course if you have a discontinuity you know that you have to take the left conditions and right conditions and right to figure out the speed there is a specific way by which we can do it but we will just say that it corresponds to u plus a right and there was a contact surface that was essentially traveling at the speed of u and when this p0 was communicated from this end to this end because it is a compression wave bordering on a shock it was traveling quite fast it propagated through this and then the p ambient condition which we are enforcing here caused a expansion fan to travel upstream you understand what I am saying. So, there is an expansion fan traveling upstream which is propagating at u minus a and as u gets larger and larger u minus a is going to get smaller and smaller so it is going to take more and more time to propagate upstream. Now it is clear that when you get convergence if you are looking for a steady state solution these static pressure here and the static pressure there have to come to term in the sense they have to come to some kind of an equilibrium in this the reason why I took a constant area duct is that they have to be the same the p0, p in fact will be a constant throughout that is the solution. So, you are going to see this reflection back and forth constantly right and if the back part is going to take more and more time as time progresses convergence will take more time. So, one of the observations that I have taken delta t constant and convergence can be slow convergence can be slow.  So, anytime these propagation speeds are small we are going to have difficulty right and I entered the conversation in the last class by just mentioning the idea of stiff differential equation right I mean you have to use the word stiff which is a structures kind of a term so you apply you imagine that if you have a stiff beam you have apply an extremely large force and you get a small deflection very stiff right. So, there are the equilibrium involving very large entities and very small entities that is the idea right. So, it is very stiff and those problems like that can sometimes be very difficult very often can be very difficult to solve and in this case I am pointing out only a very simple scenario sometimes what happens is as in the case of u approximately 0 you could even get spurious answers you could even converge to answers that are not the right answer right based on what is the algorithm that you choose. Okay, so there is an issue of slow convergence there are two things that I want to take from this demo take forward from this demo one is how to speed up convergence right the last time we talked about speeding up convergence was when we are talking about SOR okay that was the last time we talked about speeding up convergence the other we will look at now we will look at some mechanism we have actually looked at what do you call it okay this fast and slow we will talk about it we have actually looked at other schemes where we try to speed up convergence the other thing that I want to look at is getting actually a time accurate solution so far we have been talking about steady state solutions is it possible that I can actually calculate the transient okay right given that we kept this delta t constant so we were sort of evolving and I did Runge-Kutta method which is a higher order scheme in time right. So we will see we will say we will try to say something about getting time accurate schemes something about what I mean by slow convergence so it is not enough see you can do you can do the math you can look at algorithms you can say oh this is a order n squared algorithm meaning that if you have something like a matrix which is of size n right that the time that it is going to take to compute is going to be n squared possibility right you have all of these order of magnitude calculations you have you can be given any number of guarantees by the algorithm by the programming language by the machine that you have people can make all sorts of claims but finally what counts to use what I would call the wall clock time I sit down it is 9 o'clock I start running my program when do I get my answer back you understand we can stand here waving hands caught off me about floating point number of floating point operation operations gigaflops megaflops all of this kind so it does not help those numbers do not help what really matters is there is a clock you have a question you start your program running when will you get your answer back okay and if it is going to take a long time if it is going to take a day that may be considered slow if it is going to be taken a minute that would be considered very fast right it depends on what your application is depends on the size of your problem for a given problem right obviously something that takes few days is slower than something that takes a day wall clock time am I making sense okay so in that context when we did approximate factorization we are looking at an acceleration scheme if you are looking at something that takes less effort and you get the answer back quickly we are actually looking at when we did approximate factorization for implicit scheme you are trying to look at ways by which we could make our program run faster from the point of view of wall clock time when I say faster I only mean from the point of view of wall clock time so you have looked at two SOR and some approximate factorization schemes and so on. So we will look at another we will look at another class of schemes we will look at one now and little later I will introduce other ideas to talk about how to accelerate convergence and so on okay so we will try to do this first I will set this up and then I will just say something about unsteady flows fine. Since I have talked about approximate factorization we will recollect that basically we had some term if you recollect we had some term going to 0 we said what is the big deal what happens to the coefficient we are going to use the same idea here what did we say we have very disparate wave numbers we have very disparate the wave speeds I am sorry we have very disparate wave speeds so if you have dou q dou t plus dou e dou x equals 0 one dimensional flow you have propagation speeds that correspond to u u plus a u minus a where a is the acoustic speed okay if we are looking only for the steady state right only for the steady state solution seeking steady state solution you are seeking only steady state solution what is going to happen dou q dou t will go to 0 okay when I say I am seeking steady state solution that is I am proposing to use a time marching scheme I am proposing to use a time marching scheme to march these equations in time to steady state that is the objective. And if I were to march these equations to steady state dou q dou t would go to 0 okay and that is the opportunity for us minute we see dou q dou t will go to 0 that gives us the opportunity so I say using literature the notation used in literature out there why not multiply by a pre-multiply that term by a matrix gamma okay pre-multiply that I say pre-multiply this term right by matrix gamma because I know that this quantity is going to go to 0 right so how does it matter I just pre-multiply it by gamma fine. So as a consequence this equation having done this so I propose now to solve this instead the original Euler equation if I pre-multiply this by gamma inverse what do I get I get dou q dou t plus gamma inverse dou E dou x equals 0 this tells me that you have dou q dou t plus gamma inverse A dou q dou x equals 0 fine and what we want to do is we want to choose the gamma so that these Eigen values are nice we want to choose the gamma so that the Eigen values of that matrix are nice is that fine okay I want to choose a gamma so that the Eigen values of this matrix are nice and keep life easy but the Eigen vectors are the same Eigen vectors are the same as that way fine is that okay so what I am saying is so what would be nice Eigen values they are all say the same order 1 okay so the nice Eigen values would be the Eigen values that we have right now are u 0 0 0 u plus A 0 this is the matrix this is the diagonal matrix that we get what I propose is that we build something that is I will put a 1 there which is they are all the same magnitude am I making sense I propose that we take something like this fine and having the same Eigen vectors so what I am saying is that x inverse A x equals lambda what we normally write is A x equals x lambda right that is what you normally write or what is the other possibility that I have suggested now x inverse gamma inverse A x equals lambda 1 okay or gamma inverse A x equals x lambda is that fine okay what do I get now maybe I can substitute from the A x here so I get gamma inverse A x x x lambda equals x lambda 1 yeah maybe I can multiply through by lambda 1 inverse gamma inverse x lambda lambda 1 inverse what is this product equals x so in our case right now this looks like mod lambda this looks like that you can just check this out which is mod u 0 0 0 mod u plus A 0 0 0 mod u minus A is it possible for us to find gamma from here how do we find gamma from here excuse me so this may not be the this may not be the greatest this may not be the greatest way to find gamma there are different ways by which you can do it I just wanted to give you a clue so you can work this through it is actually possible for us to solve for gamma now and once you have solved for gamma you come back you can solve that equation am I making sense and the propagation speeds will be propagation speeds will be almost equal okay so this is something that you can try out so it is very easy that you the this is as I said this is a very naive method this has been tried now for almost 25 years people have been fiddling around trying to figure out various values of gammas that will give you right extremely good convergence this process by which in any stiff equation whether it is a linear system as in algebraic equations right or differential equations any stiff equations where you have very disparate Eigen values and you do something typically you pre-multiply by some matrix or pre-multiply by some operator right this process where you do that so that the Eigen values become nice it is called pre-conditioning this it is a it is a it is a big idea and so numerical analysis we use it quite a bit it is called pre-conditioning right it comes from in matrix algebra I do not know if you are aware of this the ratio of the largest Eigen value to the smallest Eigen value is called condition number just to give you an idea as to where it comes from in matrix algebra condition number is let us say rho A divided by rho A inverse given that A is invertible okay so it gives you the ratio of rho A times rho A inverse anyway I do not rho A times rho A inverse A inverse will have rho A times rho A inverse right I am going to make it a real time I have to be careful okay fine given that A is given that A is invertible okay largest Eigen value to largest Eigen value divided by smallest Eigen value okay is that fine and if the Eigen values are very disparate this ratio will be very large it is called the condition number fine and we will see we will keep on coming back to this this is a big headache we will keep on coming back to this a lot of the acceleration schemes that the other set that I am going to look at will deal with the same idea okay will deal with the same idea in this case because we are multiplying the unsteady term it is called preconditioning the unsteady term okay so in this case we are preconditioning the unsteady okay is that fine right now what I will do is as I said there is there is another class of acceleration schemes that we are going to talk about I will get to that later since I am right now talking about fiddling around with the unsteady term and simultaneously I said look I am going to tell you how to do time accurate calculation we went through the effort of taking a constant delta t everywhere I want to say something about the consequences of this okay is that fine okay so how do we calculate how do we get time accurate computations what are the issues involved I am not going to spend a lot of time like as I mentioned a lot of these topics that I am just going to give you enough that you have a flavor for what the topic is about right I am not going to spend a lot you can there can be a whole course on unsteady aerodynamics and then consequently a computation of unsteady flows okay so but what we do here is if you have this equation we have already seen there are two issues that are involved so it is not enough that I use rangekuta method right to integrate in time it is not enough that I just use rangekuta method to integrate in time sure that gives me a higher order accuracy right the truncation error is much smaller the order of the truncation error is smaller convergence is better all of that is nice but if you still have dissipation and dispersion you still have dissipation and dispersion what you may be what the accuracy with which you may be calculating something that thing may not may itself not be that accurate the other sources of errors that you had to be careful right so when you say unsteady computing unsteady flows I want you to realize first that what I am giving you this is a disclaimer basically I am saying I am only giving you a tiny introduction meaning that there are a lot of serious issues involved that with which you have to struggle if you want to get into doing actual unsteady flow it is not just that oh I have a high resolution scheme I am going to take I am going to resolve time scales I am going to resolve length scales I am going to take right rangekuta in time and I am going to take a 4 point centered or 4 point upwinded or whatever in space and I am going to get great answers right so you have to there is an issue here right that you have to worry about dispersion and dissipation there are other issues that you have to worry about that you have to pay attention to okay given that let me just go ahead in this naive fashion saying that yes I use rangekuta in time that is one possibility one way to do it in use rangekuta in time right but then we have all this machinery that we have just developed right now right whether I look at approximate factorization whether I look at you know the whole host of other schemes that I will talk about or preconditioning the unsteady term there is other machinery that we have done that time that we have put into developing time marching schemes to get steady state solutions am I making sense we have spent effort so far developing schemes so that we can get steady state solutions to time marching schemes fine you see I am going to I am obviously you can see the by the way and sort of going around here I am going to do something the little fishy right so I am trying to set you up for doing something fishy the other observation that we made when we solved heat equation or if you want to solve the plus equation is if you have nabla squared phi equals 0 right you could either solve this using sweeping in space or you could actually add a term and look for a steady state solution marching in time okay so you could either sweep in space or march in time so since we did this and you could add any term unsteady term here the question is why do not I add an unsteady term to this why do not I just add an unsteady term to this you say why would you want to do it well if I want to choose if I what was the time step that I took in the demo yesterday what was the largest time step that I took in the demo yesterday do you remember 5 microseconds 5 microseconds you know what I am saying that is it I want to take larger time steps I want to take something in milliseconds here right I want the spatial resolution but I want to take time steps in milliseconds not in microseconds so then I would have to go to an implicit scheme so if I went to an implicit scheme I would have to struggle and solve a system of equations if I solve this using an implicit scheme right right have if I did approximate factorization then I have lost the accuracy so if I want to say if I want to use so if I want to use for example backward space right so if I wanted to use backward time so I could use let me see how does it go 3 3 Q P Q plus 1 minus 4 Q P Q P is in space Q is in time plus Q P Q minus 1 divided by 2 delta T right I could go to a higher order accuracy this way am I making sense and do an implicit scheme plus dou e by dou x at Q plus 1 equals 0 right I have discreet I have shown only this being discretized am I making sense and I can do the same thing chain rule I can have a flux Jacobian here I can write a delta form and so on the only difference is that now I have higher order accuracy and in order to retain this higher order accuracy but still take that large time step I will actually have to solve the system of equations okay actually I have to solve the system of equation am I making sense in this case because it is one dimensional flow fortunately I still get a tridiagonal system it is not that bad but the minute you go to 2 dimensions or 3 dimensions it becomes expensive one thing in the demo I took 1001 grid points right so if you look at it as a block matrix that is a 1000 by 1000 999 by 999 by 1000 by 1000 into block it is a 1000 by 1000 matrix or if you want to look at it component wise that is a 3000 by 3000 matrix and I am only solving one dimensional flow am I making sense it is an expensive process it is an expensive process so we have already said oh marching and marching is the same as sweeping so we say why do not why do not I add an extra time why do not I add an unsteady term right so the confusion comes the sort of physical look on everybody's face comes saying wait a minute there is already a time so I add one more time I create a pseudo time okay so I add a dou q dou tau plus that so all I have to do is I have to discretize this dou q dou tau in fact as I said this need not even be q it just has to be something that depends on q so I will just say q bar is that fine okay now if you are willing to squint a little and ignore the fact that this is time and treat this tau this pseudo time okay so terms that you will see is pseudo time or you sort of admit that there are two times or they are called dual times right you are this is called either dual time stepping or pseudo time stepping if you are going to go out and look to see what are if you are going to go out and search right these are two possible search terms that you would use either pseudo time stepping or dual time step now what I propose is I have this equation as I said we keep squinting at this and treat that as though it is not time I am going to march I am going to use a time marching scheme and tau and I am going to converge and go to convergence and tau and when I go to reach convergence in tau dou q dou tau will be 0 and I will solve the resulting system of equation that is the plan okay is that fine so I would have I am going to march I am going to do time marching in tau I will use a higher order accuracy representation for dou q dou t for the real real time derivative this will evolve I will evolve in the pseudo time and when it reaches a steady state in pseudo time this will go away and I do effectively ended up solving the equation that I want that I set out to solve is that okay and because I have a new coordinate so what is the price that I paid I have a new coordinate originally one spatial dimension so we call it 1d but actually it is two dimensional because I have x and t now it has become three dimensional that is the price that I paid what is the advantage that I get I am thinking time marching oh I have done this before I can do this I can handle this okay so as a consequence when I when I discretize this I get a q bar p q plus 1 and then I get an r plus 1 am I making sense maybe I will write this out separately why do not I write it out here separately so that you will get shall I first do it with the wave equation will you be more comfortable if I do it with the wave equation first I think okay maybe why do not I do it with the wave equation first then you can maybe I should have started that off okay dou u dou t plus a dou u dou x equals 0 right we will do it with the wave equation first and then apply it there if you want so I am going to add a dou u dou tau I am going to add a dou u dou tau so if I were to discretize this remember now I will have three right subscripts and so total of three subscripts and superscripts so this becomes up q plus 1 r plus 1 minus up q plus 1 r divided by delta tau it is a time derivative in tau plus we have choices I will make a particular choice in later on I will point out to you that I made the choice up q plus 1 so we have to decide this is that q plus 1 this is the time that we are going to do so that is r the choices I will make a choice r there are three of them minus 4 upq plus upq minus 1 divided by 2 delta t plus a how come they do not have a third subscript they do not have a third subscript they do not have a third subscript right I mean I asked how come they do not have that because they do not have a third subscript there is no pseudo time these are already these are in real time okay let me write it out and maybe I will explain that so a up plus 1q we will do central differences minus up minus 1q divided by 2 delta x so what we are doing is what we are doing is I will write it here q minus 1q q plus 1 we are here and we want to go to q plus 1 you understand the tau is a coordinate tau is a coordinate that occurs between this and this everything is known below that q is known q plus 1 is q minus 1 is known q minus 2 is known they are all known when you converge when r q r becomes q r plus 1 when this converges when this goes to 0 you would have the q or the u will become u q plus 1 you understand this is something that is happening in this gap okay this is something that is happening in this gap is that fine these are known these quantities are known okay so we are set we can now this is this is sort of like this looks like very suspiciously like a explicit method right it looks like you everything at r is known so you just take all of this this equals 0 you take all of this to the right hand side upq plus 1 r plus 1 equals upq plus 1 r plus delta tau times the equation that you are actually trying to solve am I making sense plus minus minus delta times delta tau times the residue right delta tau times the residue or these are all known these are all constants for all practice for this iteration in R these are all these are all constants the only one that changes is this is that fine you keep on you keep on so what would be a good first guess for you what would be a first guess for what would be a first guess for this 0 what would be a first guess for that use some explicit scheme use some standard explicit scheme you understand or upq would be a good guess this is a cheaper guess right you could choose I will be honest this is what we did right with the suggestion that everybody made is what we did the very first time that we did this upq would be a good guess then we got a little bolder and said hey I can actually take whatever explicit thing that I was doing earlier and use that as the first time step right it is an improvement so you could use you can use even with all this satisfying the stability condition and all of that stuff it is it is still a little better you could use that as the initial guess calculate the R update the U you keep repeating this process till it converges okay I am not going to do it here but you can actually do the stability analysis for this just like we did for FTCS okay there is a stability condition we are using an explicit scheme here in R we are doing forward time in R you get R plus 1 explicitly it comes of all the terms in R it is an explicit scheme it turns out there is an associated stability condition fine okay are there any questions so how do you decide on delta tau and delta t that will actually come out of the stability condition there is a stability condition on delta tau and delta t see there are 2 there are 2 issues when you say how do you calculate it is like saying how do I decide on delta t in my computation the delta t in your computation will depend on other parameters what is the accuracy you are looking for how much you know there are it depends on other parameters but there is a stability condition there are constraints right so question you should ask is what is the constraints are there any constraints on delta tau there are constraints on delta tau if you ask the question are there optimal values for delta tau so that you get to a steady state yes there are optimal values for delta tau right so you have to figure out how to pick that every time you introduce a parameter it is not obvious that just like SOR we introduce an omega so you can ask the question what how do I pick omega well yeah that is an issue if you get a good omega it will converge fast right it is just a parameter that we introduce it is not part of the problem so one way to look at it as look at it as a problem it is a difficulty saying that why should I do this why do I do this it is just a headache I have one more parameter determine the other way to look at it is an opportunity you look around figure out if you can get a delta tau or a delta tau by delta t that ratio if you get it right you will get very rapid converges okay so our experience with this just as the initial transients the initial first few time steps the number of delta tau time steps that you take is large is it the order of 1000 500,000 of that order but after that it is like down to 4 of 5 okay convergence is very rapid after that only the initial we have always found that initially it takes some time for the and after that subsequent time steps it is of the order of 4 of 5 okay to convergence so but you take some you have to implement it try it out see what happens fine what is the other possibility I said I made a decision what is the other possibility maybe this I do using maybe this I do using the full equation okay what is the other possibility so I have q pq plus 1 r r plus 1 minus q let us q bar is it not delta tau plus 3 q pq plus 1 so you could instead of choosing r you could choose r plus 1 then it sort of looks implicit like there is some so it is implicit okay minus 4 q pq r oops no r plus q pq minus 1 divided by 2 delta t what do we do for what do we do for e now e which happens to be a function of q is also a function of q bar and if I represent e at r plus 1 e at r plus 1 is e at r plus dou e dou q bar delta q bar right anyway I have used forward time here I am not using such an accurate scheme there so I am doing the same thing there okay we have done this the only difference is that I am doing it with respect to q bar so this is dou e dou q bar so I should most probably call this a bar right I am trying to write it in the delta form now that is basically what I am trying to do okay so this gives me delta q plus dot dot dot delta q bar by delta tau plus here I want a delta q bar what am I going to do I will add and subtract a 3 q pq plus 1 r I will add and subtract that so I will get a 3 by 2 3 delta q bar you have to be a bit careful with that maybe I will do that a little let me let me just leave that I will get that this is q remember this is not q bar 3 q well I can add and subtract it does not matter 3 delta q plus 3 q pq plus 1 r minus 4 q pq plus q p minus 1 divided by 2 delta t divided by 2 delta t a bar dou q dou by dou x a bar delta q bar equals what is on the right hand side I take this e r to the right hand side dou e r dou x minus is that fine everyone okay and as we did before we will use we can relate we can relate delta q to delta q bar right so delta q we can write this we can substitute delta q you can write that delta q as some p bar times delta q bar right where p bar would be dou q dou q bar is that fine all I have done is I am just using I am just using chain rule I just want to say I have some q bar for instance this could be rho u t right these variables could be rho u t this could be rho this is this is our standard conservative variable rho u rho u rho e t right we may figure we may find and actually it is a fact we may find that using rho u t or rho u p or something may be better for the pseudo time okay so for various reasons I will point out one possible reason for various reasons so we may we choose to have this pick this variable that is going to go to 0 the dependent variable we choose to pick it right and if we pick it then of course I have a delta q I have a delta q which I have to convert to a delta q bar I have no choice so I do it through chain rule I just basically perform a change of variables only for that single term so my delta form my delta form then turns out to be I plus delta tau by delta t there is that I specifically write it right because we had a question about that multiplying p bar 3 by 2 delta tau by delta t multiplying p bar plus dou by dou x a bar acting on delta q bar equals minus delta x into r of q bar and what is r of q bar residue dou e dou x plus however you discretize this plus that term 3 q p q plus 1 r minus 4 q p q plus q p q minus 1 you are making sense in fact r as far as I am concerned I do not write it this way I write it as dou e dou x plus dou q dou t that is the residue so I look at this equation it looks like a familiar equation I have it in delta form the residue decides when my when my when I am done when my solver is done and when the residue is 0 I am solving this equation with dou q dou t represented second order accurate or if you want to do something fancy now maybe you can step in and do it you understand what I am saying is that fine okay. So now the little twist that we throw in little twist that we throw in is we say wait a minute we just looked at a acceleration scheme pre-conditioning the unsteady term so you can pre-condition the pseudo of unsteady term so you see basically take this and you can multiply that by a gamma or a gamma bar if you want since we are saying q bar fine right this is as I said this is a sampling but this gets you very quickly to where we are so the kinds of things that the kinds of things that one can do kinds of things that one can do you can add a pseudo term the pseudo terms going to go to 0 when you have when you are you can pre-multiply it by some gamma if you pre-multiply it by some gamma there will be a gamma that shows up there that is basically what happens if you pre-multiply this by gamma what will happen is this will become gamma that is the only thing that will change the change is a small change this is a change is seemingly a small change the idea is that you have if you have a code that you develop can I make a small change to the code to make it run faster right to make my convergence better so we can pre-multiply this pseudo dual time stepping unsteady term by the gamma pre-conditioned that term so that this converges faster to what looks like a steady state in tau but is in fact a transient and when you have done that what you would have done is you would have gone from q to q plus 1 taken one step am I making sense then you shift whole machinery shift restart again fine right as I said here please remember so I am only talking in terms of oh I addressed only one issue how can I take a very large time step I wish I could do implicit schemes without all that effort well it is implicit scheme there is a certain amount of effort but the effort is what we have been doing so far so hopefully it is not that difficult we are just using the ideas that we had in our time arching scheme so far so which means that you can now try doing approximate factorization here you can do whatever you want in tau here because when this ?q ? goes to 0 r will be 0 and you would have solved your unsteady equation exactly have more accurate right does that make sense so you can pre-condition you can do approximate factorization all the games that we are playing earlier you can do the same things here everything that we have done so far you can do the same things here knowing that you are going to solve the full unsteady equations ultimately right but you do all of that stuff you would have taken one time step that is the point to remember you do not lose sight of that you do all of that stuff you would have taken one time step then you have to repeat the process only question is this less expensive or more expensive than solving the full system of equations okay fine and of course if you are going to solve the full system of equations there is whole bunch of machinery to allow you to help you solve systems of equations very efficiently so the competition is there the comparison right the competition of ideas is there because there are there are it is not as though people have not tried to solve large systems of linear equations right when there are algorithms there do not get do not let me you do not allow me to give you the impression that oh this is it and the other one is difficult to know there are other there are other possibilities I am just basically saying we have developed certain schemes certain skills using to get steady state solutions using time marching schemes they can also be used to solve for the unsteady problem fine okay in the next class what we will do is we will look at some other acceleration schemes right we will look at another class of schemes to increase the improve the performance of your solvers fine thank you.


Okay, so hi everyone, my name is Jan McGehrke and I would like to give you some insights into how we try to ensure that our apps work as intended by testing the code of our apps. Before we start, I would like to mention that the exercises, which I will introduce later, can only be worked on with Chrome, Chromium or Brave. Unfortunately Firefox has some issues with the code sandbox's testing functionality. You're going to have some time after my presentation before working on the exercises to install another browser so you do not need to do that during the presentation. I have divided this presentation into two parts. In the first part we will talk about what testing is, why it is important and what different types of testing exist. There's a small part about end-to-end tests with our own tools, but it won't be the focus of this presentation. And in the second part we'll look into the specifics of how to write unit tests, including some live coding. Okay, so every time we write code it's normal that we don't spot all the typos or edge cases that will cause bugs occurring on the end user side. And especially when changing existing code that the developer hasn't worked with before, it's near to impossible to know every possible scenario that the code has to handle. So by testing code you're reducing bugs. And in order to make refactoring easier and to prevent user-facing bugs, the code can be tested with testing tools to make sure the erroneous parts are reduced to a minimum. And by doing this a lot of time can be saved with tests. This can be done by testing bits and pieces of the code or testing the entire stack. When testing the smallest part of the code for example functions and classes, the test makes sure that for a given input or state the function or class will return an expected value or the components render expected html. Testing entire apps will ensure that the app works in the intended way while not testing any code directly. Tools that help testing apps open a browser and click or type just the user would do. Of course apps and code could be tested manually but that's a cumbersome and time-consuming task. Without a dedicated team, manual testing is quite unreliable. That's why tools can be used to automate these tasks, adding robustness to the app while reducing the burden on the quality assurance team. Writing tests does take more time than simply writing code, which is why it's often seen as a hurdle. But it offers several benefits that make adding tests worthwhile. By covering app and code with tests, the amount of user-facing bugs and the time to confirm and fix bugs is reduced. Additionally the time it takes to get back into the development flow is reduced as developers don't have to handle unexpected issues. This is especially true for apps that are going to be used by djs2 instances as what's normally being handled is critical health-related information. Testing apps can make a difference in data collection and display, so covering apps by both core developers as well as third-party developers is very important and yet an often overlooked aspect. At djs2 this has been a topic that we have not addressed properly for way too long, but roughly two years ago we started adding tests to our apps and libraries and we all see and appreciate all the benefits this adds to our daily routine. It feels a lot safer to work on apps as we know that all the functionality that we covered with tests stays intact. Additionally to just covering code with tests after the code has been written, there are several alternative approaches. One of these is called test-driven development or just TDD. This means that tests are being written before the actual code, which means that the benefit that the developer has to think about the final structure and logic before writing code, that she or he has to change eventually again when making up the structure on the go. As mentioned there are different levels of an app that can be tested. One of these is so-called is called end-to-end tests. We go through what end-to-end tests are and what tools we use at djs2 to implement these tests. End-to-end tests don't test actual code. They instead try to test the entire product from beginning to end to ensure that the application flow behaves as expected. In other words, an application is tested from one end to the other, which of course includes the user's perspective. The tool that we use at djs2 is called Cypress. We will not cover how to use Cypress during this workshop, but I want to give a quick overview over the software so you can take a look yourself if you're interested. Cypress is a command line tool with a graphical user interface for development. It opens the app inside the browser and clicks on types on elements that a user would interact with as well. While interacting with the app, the software can perform checks to test whether an interaction has caused the app to perform desired behavior. With the graphical interface, every step of the test can be expected. This includes the DOM in the developer tools as well. This is quite handy when developing tests as it's easy to see why a test is failing. The graphical user interface will show all available tests, as well as a drop-down in the upper right corner, which you can use to choose a different browser. On the image, you can see some of the tests that we use to test our UI library components, like the alert bar or button. On this screenshot, you can see the tests for the transport component being executed. We're testing one specific feature here, which is allowing the user to highlight options with key combinations, like clicking with control, command or shift. In the center, you can see the actual component that's being tested. On the right-hand side, there are developer tools, which can be used to inspect the current state of the HML at any state of the test. For this case, I'm inspecting one particular diff and see if the CSS is applied properly. This allows to write tests relatively quickly and comfortably. If one of the tests fails, Cyprus will provide details about what went wrong. It will let you know about the origin of your error, which might come from the application or the test code itself. In case an error occurs, you can see the console output and inspect the DOM at the time the error occurred. This is what makes Cyprus quite a powerful tool. This is one of many reasons why we will increase the test coverage of our apps with Cyprus and our own CLI utilities that extend the functionality of Cyprus. The test that you just saw in the previous screenshot is described in this file, a so-called feature file, which is divided into scenarios. As you can see, this is more or less normal English, which is another advantage of using these types of tests, as even non-developers are able to read what the software should be capable of. If this is interesting to you, I have included a couple of links in a readme that I will share with you later. Knowing how Cyprus works is quite crucial when working with our CLI utilities. Internally, we're using our own utility. It's relatively new, so most of our apps do not use it yet, but we're planning on adding it to more and more apps over time. We're actively working on the tool as well. In the near future, we will be releasing some new utilities to make Cyprus even record and replay network requests, so the tool can be used in conjunction with the continuous integration tools without having to set up a new leadge as to instance and database for every individual test. In this readme that I'm going to share with you after the presentation, I've included some useful links, including the links to our Cyprus utility. If you want to get into Cyprus, you can find the documentation here. It will tell you how to install the tool. It will tell you how to set up Cyprus for your project, how to enable automatic login with this tool, how to add the login credentials, and some other useful information. If you want to have an example of how we're using this at DJI's tool, there's not a link to the code of the SMS configuration app. So this is the SMS configuration app, and here you can see we have a Cyprus folder and here in the integration folder, we have different feature files. For example, for adding an SMS command of type alert. So you can see here that we have different scenarios. Here's the testing code, and if you want to try this out yourself with this app, you can just clone the code, start a new instance with our D2 cluster utility. You will have to install the dependencies, of course, with Jan. You will also have to add the Cyprus.nflotjson with your login credentials and the URL of the instance, which would be localhost with port 8080 if you use the D2 cluster command, and then you just need to run Jan, Cy, colon run, and then it will execute the test and you can play around with this yourself. Another way of testing code is to test the smallest parts of the code. This is what we will have a look at today and what the exercises later will be about. But if you have attended the workshop last year in August or if you're already familiar with Jest, you could alternatively also try to play around with the Cyprus tool or read through the documentation. Okay, so what are unit tests? As mentioned in the introduction, with unit tests, we can test the smallest units of the code like functions or classes and their methods. These are very lightweight tests, so it takes a fairly low amount of time to run these. This allows us to integrate these tests into our daily workflow like in the pre-commit hook, which ensures that code that doesn't pass tests can't be added to a code base. This is especially useful when changing existing code. If the change code will produce unwanted behavior in a part of our code that hasn't been touched, this might be caught with these tests before it ever makes it into production. Michael Lynch says in his blog post about why good developers write bad tests, that a good unit test is often small enough that a developer can conceptualize all the logic at once. A very common tool to write unit tests with is called Jest. It's developed and maintained by Facebook's developers and contains a complete package to write unit tests for JavaScript projects. It's widely used, so for functionality that's not covered by Jest itself, like testing React components, there are solutions that cover the missing parts like Enzyme, which is a React component testing library developed by Airbnb. Jest allows you to run tests in your terminal, which is way faster than using Cypress. In the screenshot, you can see that 164 tests were executed in just four seconds. When a test fails, Jest will tell you what exactly went wrong as well. In this case, the test expected only valid emails to be passed to the email validator function. The description associated with the test states, should return undefined for value, I am not a valid email address of type string. Obviously, I am not a valid email address, is not a valid email address, so this test fails for a good reason. Jest also caches its results, so if a test and all its related files have not changed, it treats the test as having passed, which is why it only took a bit more than six seconds to run 486 tests on my computer. When you are working on a platform app, then you don't have to add or configure Jest. It is included in the app platform scripts. Once you have added tests, you can simply run the yarn test. This will run all your tests and print the result on the console. If you don't change Jest's default configuration, you will have to add the .test.js or .spec.js file extension to your files. Now we are going to do some coding together. I have prepared some code. In this case, a function and a component that we are going to test. Here you can see a function that is called getLabelByType. It expects an object, which is then called instance. It expects this instance to have a property called type, and if the instance does not have the type, it is going to throw an error. If the type is top, it is going to return premium tier. If the type is mid, it is going to return top tier. Here you can see that the developers chose a different terminology than stakeholders or whoever. It is good to actually test this. It is working correctly. If the type is low, it is going to return value tier. If it is none of these three, it is just going to return the type itself. We want to make sure that this works as expected. There are different ways how to use just. One would be to use the test function provided by just. Then we can just say one plus two equals three. In this function that I am going to provide to this test function, I can say expect one plus two to be three. Let's see if this works. I can run the test by running the yarn test, which executes just the background. Actually, let me just run this file specifically. I can do that by supplying the path to the file. Now it is just going to run the test for this file. You can see one plus two equals three. I can make this test for any purpose and see what happens. I can also add the watch argument and then this is going to rerun the test every time this file changes or one of the files is going to use by this one. Here you can see that we expected value four, but it actually received three. Of course, this is wrong. I can fix the test again by just changing this to three, saving it. Then this test is going to work. You can see that the other tests in here, which don't have any test code at all, are passing, which is because there are no expectations inside these functions. I am not really a big fan of using the test function. I prefer to use describe because with this one we can choose a unit in our test like this function and then handle different cases that this unit has to handle. I am saying this. I am just adding describe then a string, which is what you can see here. Then inside this function that I am providing as well, I can use the it function. It basically stands for whatever is in the string here. Instead of reading it should return premium tier, I could also say get labeled by type should return premium tier when type is top. I am going to test that now. The expected value is top. The actual value is get labeled by type. I need to pass in an object with a type property that is expected as premium tier and type is top. Then again before I can just say expect actual to be expected. Of course I could just provide this directly. It would work as well, but this makes it quite readable. If I run this one by just saving it, you can see the test passes and if I change the contents of the type, it should not pass anymore. You can see it fails and says expected premium tier but received full. It changes back and it should pass again. Oops. Now we can do the same with top tier and this should be returned when we use type mid. Let's see if this works. It does. Let's see if I can break it if I use the wrong value here. As you can see, so the test actually makes sure that this is working. I can do exactly the same with low as well. It should be valued here and I can do the same with the custom type. If type is none of the three above, something like this, it should return to type itself. Now this should fail because I'm still using your one here, but you can see it actually returned custom type, so this is correct. Now the test passes. We successfully covered this function. Now if another developer changes this for whatever reason, like this for example, then the tests are going to tell him that he broke the tests. Either he has to update the test because this is a valid change or he has to revert his changes to make the test pass again. Here I've prepared another test for testing a React component. To test React components, you have to, if you're using Enzyme, which is the library by Airbnb that I've mentioned earlier, you have to configure this first with the app platform, you don't have to think about this. You don't really have to worry about this. Now the important part that we're going to use is mount. So here I have a component data element that expects a loading error and data prop and if loading is truly, then it's going to render some HTML with the content loading data element. If the error is truly, then we're going to render the error message itself. Otherwise, we're going to render the ID and the display name. So to make sure that this works correctly, I can use the mount function that I just imported from Enzyme. I can render this component as I would normally would do with React as well. And then loading equals true. So here we're going to test that it's going to render the loading text. And then I can, so you can see here that the, this component, this element containing the text has a class loading. So I can try to find that loading element by using the mounted component find and then load. This is going to return the element that's inside this component with the class loading. And then I can do an assertion as earlier. I can extract the text that's inside this element by using the text method and then say, this should be, let's see what exactly it should be, loading data element. So I can do this. Now, another thing that I can do with Jest is I can tell Jest to only run this test and ignore all the others by using the only. So in here, it's still running the old tests. I'm just going to change it to data element. I was going to run the test for this test file and you can see that it skipped two tests because I told it to run only this one. Alternatively, I could tell these two to skip, which is going to produce the same output here. So it's only running this first test here. Let's see if I can break this by changing something here. And you can see it says I'm expecting or the test is expecting loading data element two, which is wrong. It received loading data element. So we can fix this test again by removing that part. Now it should pass again. We can do the same thing for the error. So I'm going to give this data element an error now and this is not going to work. This is going to fail because loading is still set to true. I still have to, of course, I still have to error. What should it display? Error loading data element and then the error message. So it should pass the error. This is what it should display. This is going to fail because loading is still true and in the function you can see that loading is handled before error and it returns. So if this is true, the function will never execute this part of the code. So first I have to either set loading to false and you can see it works now or I can entirely remove this one because then if I don't provide the properties undefined, which is also falsey, and it's working again. Now I can do the same thing for the testing when the data is provided. If this works, it expects a data element with an ID and the display name and expects the data to be this data. And then we can again try to find the ID and display name inside the component. ID element is component.find.id, display name element is this component and then we can say expect the ID element text to be data element i. And then display name element should display this is my display name. So let's see what happens. This is going to fail because you can see that it says cannot read property ID of undefined. So we just provided data element with an ID property, but data element actually has to be inside of data. So I have to wrap this data element inside this data element with an object and provide data to this data element component and it still did not work. Of course this has to be display name. And you can see now that it has passes. I can remove all the skips. So now it should run all tests and you can see all of them pass and because we implemented the tests of both files we can run all tests and now this should pass all test should pass. You can see this one passed this one passed it executed seven tests into files in 4.5 seconds and most of this time is because just need some initialization to do and then running the tests itself is quite fast. So I'm going to share with you the exercises in a second. In here you will find the link to the code sandbox exercises and in the source folder there are eight files, four for regular JavaScript unit tests and four files for component tests and each of these exercises increases in difficulty. So the first one should be fairly straightforward. This is the function that we just took a look at. There is a comment that describes what you have to do. You can see the implementation is missing here. Same for the component tests. You just everything is important already that you need so you just have to go down to the tests and read the comments and implement what you what is expected here and you can see here instead of browser there's also tests and it will tell you whether the tests pass or not. The first time I load this normally just a test phase but none of these tests have any assertions so they're all going to pass. There's also the solutions but I highly encourage you to not look at these solutions and try it out yourself. If you're struggling before going to the solutions you should try to read the documentation because this is what you will spend most of your time with when writing tests until you get used to using these libraries and I think this is one of the best skills to have when writing tests is to know your way around the documentation. Are there any questions? There was a question like Pete and I think you can unmute yourself. Right Martin? I'm going to get the question is in the chat on Slack in the channel. On Slack give me a second. Is it best practice to provide a test string value multiple times in a test or reference the original variable again for example this is my discipline rather than data element dot discipline and that's a good question. Let me share my screen again. I prefer to just write this string again. In this case it doesn't really matter. You could just reference it again here but by writing out the string again it's easier to read the actual test code which could serve as documentation as well. For more complex tests or more complicated tests it's actually better to write out stuff again instead of making things in quotes dynamic or a little bit more abstract because tests should be as simple as possible to make sure that everything works as intended. You're not trying to make right elegant tests or make this really super abstract and reuse as much code as possible. These are meant to test stuff so my preference is to just write this out again and have lots of duplication in here which is normally not good in application code but in tests it's actually encouraged so yeah I prefer to put this one in here again for several reasons.