Hello everyone.
Welcome back to the CFD using Openfoam beginner to intermediate course.
This is our class six.
In this class we will be seeing introduction to Transient solvers decomposing methods which will be
useful in running cases in parallel.
If you are interested in running parallel processing, then we will also see how to run parallel processing
for snappy hex mesh.
So the entire meshing process through snappy hex mesh can be done in parallel.
So we will see how to do that.
Okay.
Now introduction to transient solvers.
So transient solvers it uses time dependent simulation.
So we will be getting a sort of animation where every time step is converged solution.
So we will get a feel of the flow progressing over time.
The key features are the model here is unsteady or transient flows such as vortex shedding behind a
cylinder.
Example solvers in Openfoam are pimple foam, eco foam, piezo foam, inter foam.
So applications are like uh, in most cases.
The examples are aerodynamics, combustion, or multiphase phenomena like mixing processes.
The advantage of using a transient solver is to capture time dependent phenomena.
Analyze dynamic behavior.
So in solver settings, apart from what we have done till now, we will also define our time step which
is delta t.
And we will be seeing how to set the convergence criteria which defines solution accuracy.
We will also set maximum Cuda number, serial number and so on.
So we will be seeing a multiple tutorial cases.
So the first one will be backward facing step 2D case.
In openfoam terms it's called pitch daily.
Uh we will be seeing k epsilon turbulence model.
And the solver which we will be using is pimple four.
So as you can see this is the part of control dict file which we will control the entire simulation
parameters.
So the start frame uh start from is set to latest time.
So basically when we don't have any time steps before running the simulation, zero is the latest time.
So it will start at latest time.
But if you want to start at start time every time, then you can start, uh, you can set the start
from to start time instead of latest time.
Too many times in a sentence stop.
It will be n time and you can set the end time.
That is the uh, time flow time in seconds where your simulation will end.
In this case, your simulation will end at 0.3 seconds.
So it's like you're starting a simulation, you're starting a flow.
And after, if you stop the simulation or stop recording the simulation after 0.3 seconds, whatever
video you would have got, that is exactly what we are trying to simulate here.
Then we have the delta T, which is the time step.
In this case it is one over one E minus four.
So that is very small.
And we will see why we said that okay.
In the control deck we are sorry in the right control we are setting it to adjustable and the right
interval is 0.01 which means our delta is 0.0001, but for every 0.01 seconds, we will be saving a
time step file which will cater us to the animation finally.
So we will get a frame of reference for every 0.01 seconds.
So the purge rate is mostly useful only for steady state case.
What it means is if I said purge rate to five, then only the latest five time steps will be stored.
Everything else will be deleted to save some storage space.
Uh, the right format should be Ascii.
You don't have to touch any of these if you just come.
Uh.
Below you will find runtime modifiable.
You can set it to S, because if you see that the simulation is running and you feel like 0.3 is not
enough, then you can, uh, set the end time to 0.5 while the simulation is running.
If you want to do that, then you have to set the runtime modifiable to S.
And in the adjust time step, if you keep s, then what it means is you are doing adaptive time stepping.
So in case of adaptive time stepping you also have to define your maximum current number.
Only then it will uh do it.
So generally maximum current number has to be one.
That is the realistic case.
Uh, it is also popularly known as CFL current Frederic uh Levy number.
But in open form terms it's maximum current number.
We can monitor current number while the simulation is running for every time step.
So by default this tutorial comes with a max of five.
So let's stick on to the tutorial.
But when you are actually setting up a case, make sure that mostly it is one or depends on the physics.
So the next image is from turbulence properties file.
The simulation type is going to be Arias and the Arias model is going to be epsilon k epsilon.
The turbulence is turned on and the print coefficients also turned on.
What this does is in the command prompt or the console window, you will be able to see the coefficients
of turbulence parameters like k, epsilon and duty while the simulation is running.
So after running the simulation, we will be getting, uh, multiple files from 0.010.020.03, so on
to 0.3 seconds.
We will be visualizing those things, those, uh, frames of animation in Paraview after running this
case.
So this is what we are trying to, uh, visualize.
So the left one is 0.01 seconds and the right one is 0.3 seconds.
This is how it starts.
And it ends here.
So this is just a backward facing step.
Now we will jump into our command prompt and try to simulate this case.
I am in class six folder.
Here we have the first pitch daily tutorial.
Here we have zero constant and system.
So as you might already know, uh, pitch daily comes with a block mesh.
So I will run block mesh okay.
And we will find out.
What is this, uh, solver?
As we already saw, this is a simple form case.
Sorry, this is a simple form case, so I will write it to simple form.
And let's wait for the simulation to end.
Meanwhile, I'll just pause somewhere.
Like if you scroll your mouse over here, it will snap to specific time and it will keep on running.
It won't stop, but you can just scroll and it will just stop there.
You can see it is progressing, the Delta T is progressing and it is not same as what we had defined
because we have set the maximum current number and we also have the delta t, so it can alter the delta
T to, uh, adapt to the maximum number.
That's what adjustable time step is.
It's mostly adaptive time stepping.
Also you can monitor at what time the simulation is happening.
Like this is 0.018 and so on.
And we can see the parameters residual parameters for UX UI.
And we also have for epsilon k pressure continuity everything.
So this goes on.
And finally when it reaches 0.3 this simulation will end.
So when you are doing this uh you can actually go to that location and see it.
So I will tell you what that latest time is all about.
Now, if I want to stop this simulation, I can just do control C and it will just end there.
Now I will do explorer dot x.
So this location is open and you can see we have all the time steps coming here from 0.01.
And it is slowly progressing.
We have up to 0.14.
So since we have given latest time now see the last time which it ran was 0.141795.
So when I run the pimple form again it will just start from 0.14.
See, it is starting from 0.14 because that is the latest available time step.
So it is starting to write from 0.15.
That is the advantage of having the start time as the latest time instead of starting.
Okay, now the simulation is over as you can see, it took so much time to finish this though I have
got all the, uh, running time in the video, so it took a lot of time and you can see how many actual
seconds it took here.
Okay.
You can also monitor that.
And you can see it ended at 0.3 okay.
And maximum delta T was around 0.0002.
So that was much greater than what we defined like 0.0001 was what we defined.
And you can see a maximum current number is just five here.
So that's why it got adopted okay.
Now we have all the, uh files here.
I'll open the paraview.
Okay, now it has loaded.
I'll click on apply and I'll change it to velocity.
Okay.
Now as you can see we are at 0.01 flow time.
It is always advisable to first go to the last frame and click on this thing which is rescale to visible
data range, and then go back to your first time step.
Mostly that would be better if you are running a transient cases, but if you think the physics is like
the initially, it will be high in velocity and finally it will be lower in velocity.
Then you have to do the rescale to visible data range in the first time step.
So in this case the final time step has some less velocity than the first time step.
So first time step has to be rescaled so that it can adapt till the last time step.
So you will understand when you are actually working on multiple cases and you will get it.
So I will click on play.
So this is how the flow is progressing.
So you can see the time is changing here I'll click play again and it will start from 0.00 0.01 seconds.
Now as you can see the minimum is 0.01.
But if you want to include the zeroth time timestep as well, you can check on this button and click
apply.
Now you would also have the zeroth timestep, but mostly it wouldn't make sense at all because it is
just initial condition.
Click on run and it will be done.
So it is not generally advised to take the zeroth time step because it is just initial values.
It won't, uh, give you any proper insight.
Okay, now we got the velocity.
Similarly, you can also monitor pressure and go to the first time step, rescale it and click on pressure.
And you can see it is getting like an animation.
Now I can do this same thing for k nu t epsilon.
Okay so you get the point.
Now if I want to do uh velocity streamlines as an animation then I can still do it.
I just plot streamlines, just like how, uh, just the way I would do normally.
I'll hide the line.
Okay.
Maybe reduce the number of lines here.
Okay, now I can do the same thing, like start play and it is running.
Now it is a bit slow and loading because it is, uh, loading all the time steps and plotting the stream
lines.
So it is doing multiple things at the same time.
So it is a bit glitchy.
So what you can do is go to file, click on Save Animation and probably I will save it as stream lines.
Hit okay and probably I will take yeah.
Just for this case I would take just one frame per second.
Okay.
But if you want a realistic scale, then you have to choose ten frame per seconds for, uh, for you
to get a slowed down animation of ten times.
But if you do 100 frames per second, then you would get the exact realistic thing, because our lowest
time step is 0.01 and our delta T is, uh, I mean delta t in terms of saving animation.
Every frame here as we saved it is 0.01 seconds.
So when you want everything for one second, you just have to multiply it by 100.
But that would be too fast because the animation would end in 0.3 seconds.
So I'll change it to one and click on okay.
So you don't have to worry about this error.
It is uh because of the resolution okay.
It doesn't matter.
now.
We got the file, saved the animation file, and I can open the stream lines and it would be decent
enough and fine.
As you can see, it is saving one frame per one second.
You can get some good insight from this, but if you really want, uh, a fast forwarded kind of thing,
like a realistic animation kind of thing, maybe a ten times slow but animation kind of thing.
Then you can choose ten frames per second in this case.
Okay, I'll just save it.
Now I will run this.
Now you can see it is much better and looking like an animation.
Since it is a streamline, we can't infer much as well.
I will go here and save this as, uh, velocity file.
But instead of ten I am even going to use 20, so it is just half scaled down.
Go here.
Run the velocity file.
So this ran very fast as you can see.
So this is what a real animation would look like at the end.
If we had much higher time steps of flow time then we would have a longer animation.
But this was just for demonstration.
So this is okay.
Now, you understood how to set up a transient case and run this.
So this is the first part of the video.
Uh, from the second part we would continue.
Okay.
Now we are going to see decomposing methods.
So decomposing is a method where you will split the mesh into separate sections or regions, and give
your processors each part of the mesh and ask it to solve for you.
So this is done through a process called message passing interface, also popularly known as MPI.
Openfoam comes with the MPI installation.
Generally, people have to write MPI codes to parallel process their simulations.
But since Openfoam comes with the installation of MPI, we can use it.
So it also depends on the number.
Of course, your system has.
So cores are the number of physical processors your CPU comes with.
Okay.
So your CPU will have certain number of physical cores and logical course Openfoam can access only physical
cores.
Commercial software like Ansys fluent can access even logical processors, but Openfoam can access only
the physical cores.
So we will see how to find out the physical cores in your PC, because this is the number or value which
you have to remember while decomposing.
So I have given a set of methods to find out the course in your PC.
So you just have to open your task manager and you will go to the performance section.
And inside that you will go to CPU section.
Under there you will go to course and you can find the number of course.
So you just have to remember it.
Okay.
Sometimes your laptop comes with the stickers saying uh number.
Of course if it is a gaming laptop, but if you are on a very regular laptop, then mostly it won't
be there.
So you have to find it out.
So to do that, either you can open task manager from this or any shortcut methods which you know,
there are a lot of shortcuts for this.
So I'll go here, click on performance and on CPU.
As you can see we have the number of cores here.
In my system it is eight.
So whenever I'm using eight for decomposing and MPI please remember that you have to use the num value
which your PC is supposed to have.
Just because I am typing eight somewhere, please don't follow the same and uh, face errors, so just
replace it in the appropriate places.
I will close the task manager now.
Okay, now we are going to see the decomposing methods.
So decomposing in open form is done through a file called decompose uh part dict okay.
Uh we will see the file as well.
So this is how the file actually looks like.
It will have number of subdomains.
And it will ask you for a method.
If you choose hierarchical then you have to define the coefficients.
So the coefficients are like if you have an entire mesh and in each direction how many subdivisions
do you need.
So in this example we are subdividing the x in four subdivisions the Y into two subdivisions, and the
Z is going to be just one, which means it might be a 2D case.
We are interested in decomposing only x and y.
So what is important about the 4211 and why did I choose it?
It is like when you multiply x by y by z you have to get the number of processors.
So in this case it is four times two times one which is eight which is the same as number of subdomains.
It is not mandatory that you always have to use all the cores which you have.
If you have eight cores, you can still use just six or just two or just, uh, four.
Okay.
But it is very recommended that you use even numbers and not odd numbers.
So use two, four, 6 or 8.
Things like that.
But don't use odd numbers.
Mostly it can't work well.
That is why laptops or computers come with even numbers, of course.
Okay, so you always use even numbers.
If you want to find out why it has to be even numbers, you have to study about message passing interface.
Okay.
Now in uh, other method which is called scotch, you don't have to define the coefficients.
The program will do it for you.
So you just have to specify the number of subdomains and the method.
So to execute the decompose predict file and decompose your case the command is just decompose part
okay.
The purpose of decomposing is to divide the computational domain into smaller parts.
The benefit is it enables parallel processing and reduces computational time by splitting the work to
all the processors.
When you are running in series, the computation will be done in a series manner by one processor,
but you are doing parallel processing.
The work will be split to multiple processor and it runs in parallel, so you get it faster.
So the method is like first you split the domain into sub domains and assign different tasks to each
processor, and you will be able to run the simulation or mesh.
So the Openfoam command is decomposed part.
Okay, so before we jump into what parallel processing and how to do it just we will see how to do the
decomposing.
I'll go to the terminal.
I'll clear this and go to the second tutorial of today.
Okay, we have zero constant and system as usual, but if you see under system we have one more file
called decompose bardic.
So that is what we are going to view now.
Okay I will go to the second folder.
We have decompose bardic.
Here initially I have chosen Scotch, but if you want to trial with hierarchical, you can do it.
So we have the number of subdomains where I have specified eight.
You have to specify the number.
Of course you are.
And the method in this case is scotch.
Otherwise it is just normal daily case which we run here for transient phenomena.
We will see the control dict.
So we are again using pimple form only and the time step is delta t is equal to 0.0001.
And let the maximum see will be five.
Sorry, this shouldn't be there.
So that was my mistake okay so we have the delta T as 0.001 and maximum current number as five.
Okay.
So we are going to decompose it.
Now.
As you can see initially we have only zero constant and system.
So this zero file has u p nu t k and epsilon.
Because we are using k epsilon turbulence model, all you need as turbulence parameters is just these
three turbulence viscosity k and epsilon.
If you want to explore what I said for the boundary condition, you can go in and check it.
But that's not the scope of this video.
Okay, so we have zero.
We don't have any other time step because we didn't run it.
Now I will go here and I will execute decomposing.
So the command is decompose part with P capital hit enter.
As you can see it is saying that it is subdividing.
Okay.
It is subdividing the time zero into 0 to 7 which is eight.
uh, field transfer.
And you can see the number of cells, number of points has been assigned to each processor.
So it might be a little bit more or less.
But each processor has a set of mesh which it has to, uh, work on and do the simulation.
Okay.
So after we do this we got these files processor zero to processor seven.
So when you go into processes zero you have made a copy of process uh zero files and the constant file
under Polymesh you will have only the mesh this processor is assigned to you.
It will not have all the mesh which you generated using block mesh.
It will have only the mesh content which is necessary for this processor.
And same applies to every processor Okay.
So it has the zero file because we are going to run things in parallel and it needs a reference for
zero.
So it has the zeroth time step.
Now I will explain what parallel processing is and how to do it.
So parallel processing using MPI.
So MPI is a message passing interface.
The definition is it is standard for parallel computing.
And the functionality is functionalities it allows processes to communicate with each other.
In implementation for Openfoam, we will enable parallel processing for faster simulation, which is
the same for any CFD software.
And you will, uh, run a piece of foam simulation for this.
Uh, as an example for yourself, you will try a piece of foam tutorial if you want and you can try
it using MPI.
For now, we will be sticking with the simple form tutorial and we will see a demonstration.
But if you want to do it with icofom or simple form, the methodology remains the same.
All you have to do is you have to copy this decomposed par dict and put it into any system directory
of any case, and you can decompose it.
You just have to set everything properly like the number of subdomains.
Okay.
So that is the only thing which you have to do.
Okay.
The benefit is it utilizes multiple processes simultaneously.
And it scales well with increasing computational resources.
So let's see what is the step to do parallel processing using MPI.
The first thing is decompose power.
But but before that you must have a mesh and initial boundary condition in zero five.
So that's what I mentioned as poly mesh must be available because not just block mesh.
You could have generated that with snappy hex mesh or imported from Ansys fluent mesh, which we will
see later.
So anyways, it will all the mesh will be in polymer, so it has to be there.
Then you are running decompose power which will subdivide everything, every mesh for each process.
Then the command to initiate the solution or simulation is MPI run space hyphen NP space.
The number of processor, which in my case is eight and uh process which is in this case pimple foam.
If it is a simple form then you have to do simple form.
If it is a micro form you have to type ICO form in place of process and space hyphen parallel.
So this is what will initiate the solver to run in parallel.
I have put some examples.
If it is an eight core processor, it will be mpirun space hyphen NP space eight and the command if
it is simple form.
Simple form space hyphen parallel.
If it is six cores, then NP six.
Simple form parallel.
Okay, we will see about reconstruct, uh, after we run the simulation, actually.
Okay.
Now that we have all the decomposed files, we can initiate it through Mpirun NP eight.
Eight.
In my case, simple form.
Parallel.
When I hit enter, it will start to do the same process, which we did previously, but in parallel.
So it is going to end super fast.
As you can see, it is running super fast.
Then what it was running previously because it is just eight times faster right now.
So let's wait for the simulation to end and I will get back to you.
So the simulation is about to end.
Okay, it is done.
Now I will do ls again.
All you can see is processes 0 to 7.
We are not able to see the time step.
But what happened because everything is inside processor.
So we have 0.1 to 0.3 everything here for every processor.
Okay.
So we have to reconstruct everything and then we can, uh, see the visualization.
So what reconstructing will do is it will take the mesh information from every processor, collectively
put it, and just save everything as, uh, separate time step.
And then it would look something like this.
But if you don't want to reconstruct because it takes a bit of time, you can open paraview Paraview
and instead of directly clicking on apply, you can change it here.
Instead of reconstructed case, you can go to decomposed Case and then click on apply.
Okay.
Now what if I just click on reconstructed case.
You are not going to see anything because it doesn't know that if there are any files at all, because
it is expecting the time 0.01, but it is not there.
So you have to give decomposed case.
So it will go inside every processor and try to recollect it for you.
For visualization.
Now I can see the velocity.
Right now if I play, it is going to be playing because it is trying to recollect.
But since the mesh is very less, mesh count is less.
We are not getting stuck.
But when the mesh count is very high, let's say in a 3D case where where there are millions of cells,
then every loading time step is going to be very high.
That's why we are going to reconstruct and then visualize it very easily.
Okay.
Because it takes time for paraview to reconstruct every single time step without storing it and displaying
it to you.
It's too much on the memory, so we will see how to reconstruct it.
To reconstruct the very simple thing is just run, reconstruct part.
That's all you have to do.
So just like how you did decompose part, now you have to do reconstruct part.
Okay.
Now I will go to my terminal and I will do reconstruct part.
And you will see what happens.
It is starting to reconstruct every single time step by putting the time step name.
See it is saying time 0.01 and it is reconstructing all the fields.
Volume, scalar field, vector field and surface scalar fields.
So as you can see it is taking a bit of time.
It is running slow.
We will also see a method to run this parallel as well.
But for now this is the most popular method.
So let it run.
We are not going to wait for it to end completely because this is just for demonstration.
We will stop it at 0.05.
Till then, let's wait.
Okay, now it is done before it starts with 0.06.
If you want to end any process, just hit Ctrl C and it will be interrupted by the keyboard.
If I go here now, you can see we have 0.01 to 0.05.
Okay, but let's assume that you have reconstructed everything, okay?
And, uh, you don't need these files anymore because these are going to consume a lot of space.
Since this is a very small scale, it is less.
Otherwise it's going to be in gigabytes.
So we don't want these anymore because the data has been reconstructed.
So what you can do is arm space minus r proc star.
So it just says that delete everything and everything inside those folder which starts with the four
letters p, r o, c.
And we don't care what comes later.
So anything any folder that starts with proc will be deleted.
When you're doing through terminal, it's going to be faster than what you will be manually clicking
and deleting through windows.
Since this is through WSL, it's going to be faster than what windows can even do.
So as you can see, it is slowly getting deleted one by one.
And now it is all done.
Okay, now you can go to paraview and click on Reconstructed Case.
Click on apply and it will still work.
But we have only 0.05 seconds of data.
Okay, now let's say like you don't want these time step.
Also, you want to start from uh scratch by changing let's say delta t or maximum quota number if you
want to choose it as two.
And if you want to run it, you have to delete all the time steps.
Right now it is just like, uh, around 100 time step.
But what if it is so much you can't delete everything one by one?
Or just even if you select everything and delete windows is going to take a lot of time.
So Openfoam gives you this nice command for list times.
Notice that L and T are capital space hyphen m.
Hit enter and all the time steps will be gone, like in an instant.
So you have deleted all the time steps through this command.
So this is just some additional information apart from today's topic.
So this is just nice to know because when we are working with terminal, it will be much faster than
what you can do directly with windows.
Okay.
now we know how to decompose a case and run it in parallel using MPI and also reconstruct part.
Okay, now we are going to see how to run parallel snappy hex mesh.
Snap hex mesh is a meshing process.
And we are going to do meshing itself as uh parallel processing.
As I was saying, we must have a poly mesh to generate any sort of decomposing, right?
Because we need a poly mesh to even put it in constant and split the mesh to the processor.
But snappy mesh itself is a mesh.
So what we are going to do is we will generate the block mesh and split the block mesh to different
processor, and we will do snappy mesh as a process to every processor.
So I think you get the point and we will do the tutorial so you understand it better.
I'll clear this.
Go to the third case for this class.
Okay.
Now we just have constant and system no zero file because we are not interested in running simulation.
So just this now what I'm going to do is I'm going to do block mesh because first we are going to run
the block mesh.
So this is the pipe external case which we made if you remember meshing around the pipe.
Okay.
Now I have generated the block mesh.
Then the next command is to decompose this.
So I will decompose using decompose part.
Ah.
Okay, now we have decomposed the block mesh.
Now, the next thing is we have to initiate snap x mesh.
So the command is same Mpirun NP eight.
And the process name which is snappy x mesh.
As usual parallel.
If you remember we always do snappy x mesh with space overwrite, so we can also include that it doesn't
matter if you put parallel first or overwrite first, it's going to be the same.
So what I have done is let me shorten this so that you can see it better.
Right.
Okay.
It is mpirun I am not able to put it in the a single line or can I?
Yeah.
So it is just like MPI run PNP, snappy hex mesh, parallel override.
Now I can hit enter and this will start the snappy hex mesh process.
Now you see this running much faster.
If you remember at what speed it was running when you initiated the mesh, you would know that it is
much, much faster.
So now let's wait for it to end and we will reconstruct the mesh through a special command called reconstruct
per mesh.
So as you remember, we just did reconstruct part when we are doing the time step reconstruction.
But in this case we have to do reconstruct per mesh space hyphen constant.
Because we are trying to write this mesh inside the constant folder.
So I will do reconstruct power mesh hyphen constant.
I'll hit enter.
Now you can see it is taking data from all eight processors and putting it in the.
Poly mesh.
Okay now we don't need these processor 0 to 7 anymore.
So what we can do is r minus r proc.
And it will delete all the processor files.
So we can save upon some space.
Now if you just want to view the mesh you can go to para Para view.
Click on apply.
You can go to wireframe and you can see we have the mesh.
So the output is going to be the same but the process will be faster.
That is the advantage of using MPI.
So I hope you understood how to do the uh decomposing as well as reconstruction.
Now let's say you have a zero file also.
And now you want to run things in parallel.
So what you can do is after deleting all the processor files now, then reconstruct, just like how
you would do for any simulation case like this process.
So again you have to decompose.
Then you can run things in parallel and reconstruct part.
So that is the best method.
So now we have an additional tip.
What if you want to reconstruct in parallel.
Because reconstruct if it has like too many time steps.
Like the previous case it had a lot of time steps, right?
So if the case is like that, then it's going to take a lot of time to reconstruct.
You saw how much time it took to reconstruct that.
So what I will do is I will again run that case and show you how much time it takes.
When we are reconstructing it in parallel, it's going to take a lot less time.
So I'll just run this case and get back to you once this is over.
I'm just going to run a few time steps.
Not completely.
So we have five time steps, or maybe four because I stopped it early.
Yeah, we have five time steps.
now.
You remember how much time it took when we tried to reconstruct it?
It was very, very slow.
But now we are going to try to use this command and see how fast it is going to reconstruct, because
it's running in parallel.
So it is Mpirun NP eight again, the same thing.
Then we are going to run a reduced tribute pa PA.
Reconstruct.
Parallel.
New times.
So you just type this.
I hope I didn't make any mistake in spelling and hit enter.
Now you see just how fast it is reconstructing.
Now it is just done.
This was the time it took to just reconstruct two time steps.
So, uh, this is not very popularly known among a lot of users.
So if you use this, it's an advantage to you.
Okay.
If you have any questions about anything related to this video, please feel free to contact me.
See you in the next class.
Thank you.