CFD Online Logo CFD Online URL
www.cfd-online.com
[Sponsors]
Home > Forums > Software User Forums > OpenFOAM > OpenFOAM Programming & Development

meshToMesh every timestep parallel OF2.3.1

Register Blogs Community New Posts Updated Threads Search

Like Tree5Likes
  • 2 Post By Carlen
  • 2 Post By rt08
  • 1 Post By rt08

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old   April 2, 2015, 05:12
Default meshToMesh every timestep parallel OF2.3.1
  #1
Member
 
Join Date: Jul 2012
Posts: 67
Rep Power: 13
Carlen is on a distinguished road
Hi foamers,

I want to map fields from a fine mesh to a coarse mesh on a regular basis (every timestep). I have searched many posts in this forum and found these very useful:

http://www.cfd-online.com/Forums/ope...time-step.html

http://www.cfd-online.com/Forums/ope...-parallel.html

http://www.cfd-online.com/Forums/ope...shes-used.html

However, I am rather confused about how in above implementations the createMesh.H and createFields.H are written. I understand you have to have the sourcemesh and targetmesh for mapping, and you define them separately by
Code:
Foam::fvMesh mesh
(
Foam::IOobject
(
"Primary", //I have two regions of same geometry (Primary and Secondary)
runTime.timeName(),
runTime,
Foam::IOobject::MUST_READ
)
);

Foam::fvMesh mesh2
(
Foam::IOobject
(
"Secondary",
runTime.timeName(),
runTime,
Foam::IOobject::MUST_READ
)
);
I then use meshToMesh to map fields from mesh to mesh2 and then mesh2 to mesh. This is where I get stuck.

My question is for the mesh2 part.
As I understand that in createFields.H all IOobject use mesh, e.g.
Code:
volVectorField U
    (
        IOobject
        (
            "U",
            runTime.timeName(),
            mesh,
            IOobject::MUST_READ,
            IOobject::AUTO_WRITE
        ),
        mesh
    );
Can I change mesh to mesh2 in above code? or I have to modify all files in the Secondary (mesh to mesh2). This will be very complicated because I have to take care of all files included in the make/options.
Or is there another way to do calculations on two meshes in one solver?

PS: I just want to know how the creatMesh.H and createFields.H are written for such a purpose
linhan.ge and charryzzz like this.
Carlen is offline   Reply With Quote

Old   April 2, 2015, 09:44
Default
  #2
New Member
 
Ryan Tunstall
Join Date: Sep 2013
Posts: 10
Rep Power: 12
rt08 is on a distinguished road
Quote:
Originally Posted by Carlen View Post
Hi foamers,

I want to map fields from a fine mesh to a coarse mesh on a regular basis (every timestep). I have searched many posts in this forum and found these very useful:

http://www.cfd-online.com/Forums/ope...time-step.html

http://www.cfd-online.com/Forums/ope...-parallel.html

http://www.cfd-online.com/Forums/ope...shes-used.html

However, I am rather confused about how in above implementations the createMesh.H and createFields.H are written. I understand you have to have the sourcemesh and targetmesh for mapping, and you define them separately by
Code:
Foam::fvMesh mesh
(
Foam::IOobject
(
"Primary", //I have two regions of same geometry (Primary and Secondary)
runTime.timeName(),
runTime,
Foam::IOobject::MUST_READ
)
);

Foam::fvMesh mesh2
(
Foam::IOobject
(
"Secondary",
runTime.timeName(),
runTime,
Foam::IOobject::MUST_READ
)
);
I then use meshToMesh to map fields from mesh to mesh2 and then mesh2 to mesh. This is where I get stuck.

My question is for the mesh2 part.
As I understand that in createFields.H all IOobject use mesh, e.g.
Code:
volVectorField U
    (
        IOobject
        (
            "U",
            runTime.timeName(),
            mesh,
            IOobject::MUST_READ,
            IOobject::AUTO_WRITE
        ),
        mesh
    );
Can I change mesh to mesh2 in above code? or I have to modify all files in the Secondary (mesh to mesh2). This will be very complicated because I have to take care of all files included in the make/options.
Or is there another way to do calculations on two meshes in one solver?

PS: I just want to know how the creatMesh.H and createFields.H are written for such a purpose
You can change mesh to mesh2 but remember you can only have one volVectorField called U e.g. you would need to call U for second mesh U2 or similar

A good way to approach this is using multiple regions. That way existing utilities like decomposePar etc will be compatible with your new solver.

Basically have a look at chtMultiRegionFoam and how it makes use of regionProperties. Basically you want to set it up so that each mesh is a different region. Then instead of having a volVectorField for U on each mesh you can have a single PtrList of length 2 where each element in the PtrList is a pointer to the U field on that mesh
rt08 is offline   Reply With Quote

Old   April 2, 2015, 10:39
Default
  #3
Member
 
Join Date: Jul 2012
Posts: 67
Rep Power: 13
Carlen is on a distinguished road
Hi Ryan,

Thank you very much for your reply. Yes I have setup my code in a way similar to the solver you mentioned. I have two regions (Primary and Secondary) for fine and coarse meshes, and they have identical geometry and boundary conditions. So I can decompose it using decomposePar -region Primary or Secondary respectively. However, I am confused by the use of PrtList as I am new to OpenFoam. How is it implemented?

kind regards,
carlen
Carlen is offline   Reply With Quote

Old   April 2, 2015, 10:52
Default
  #4
Member
 
Join Date: Jul 2012
Posts: 67
Rep Power: 13
Carlen is on a distinguished road
Hi Ryan,
is this correct. I have to have U for the fine mesh and Utgt for the coarse mesh. I then write
Code:
PrtList<fvMesh> fluidRegions(2);

forAll(fluidRegions, i)
{
   fluidRegions.set
        (
            i,
            new fvMesh
            (
                IOobject
                (
                    fluidNames[i],
                    runTime.timeName(),
                    runTime,
                    IOobject::MUST_READ
                )
            )
        );
}
Then I put this in createMesh.H for creating both the fine and coarse mesh. Is this right?

Then in createFields,
Code:
volVectorField U
    (
        IOobject
        (
            "U",
            runTime.timeName(),
            Primary,
            IOobject::MUST_READ,
            IOobject::AUTO_WRITE
        ),
        Primary
    );

volVectorField Utgt
    (
        IOobject
        (
            "U",
            runTime.timeName(),
            Secondary,
            IOobject::MUST_READ,
            IOobject::AUTO_WRITE
        ),
        Secondary
    );
is this right?

Also, I notice that many equations in my solver needs mesh for example in the readGravitatioanlAcceleration.H it needs the registry to be mesh not my Primary and Secondary registries. Does that mean I have to modified all related openFoam files and recompile the whole OpenFoam. Or is there any other way to do it?

Best,
carlen
Carlen is offline   Reply With Quote

Old   April 2, 2015, 10:53
Default
  #5
New Member
 
Ryan Tunstall
Join Date: Sep 2013
Posts: 10
Rep Power: 12
rt08 is on a distinguished road
Quote:
Originally Posted by Carlen View Post
Hi Ryan,

Thank you very much for your reply. Yes I have setup my code in a way similar to the solver you mentioned. I have two regions (Primary and Secondary) for fine and coarse meshes, and they have identical geometry and boundary conditions. So I can decompose it using decomposePar -region Primary or Secondary respectively. However, I am confused by the use of PrtList as I am new to OpenFoam. How is it implemented?

kind regards,
carlen
Have a look in createFluidFields.H:

Code:
PtrList<volVectorField> UFluid(fluidRegions.size());

forAll(fluidRegions, i)
{
        Info<< "    Adding to UFluid\n" << endl;
        UFluid.set
        (
            i,
            new volVectorField
            (
                IOobject
                (
                    "U",
                    runTime.timeName(),
                    fluidRegions[i],
                    IOobject::MUST_READ,
                    IOobject::AUTO_WRITE
                ),
                fluidRegions[i]
            )
        );
}
PtrList is basically a list of pointers. For each region, the above code will create a new volVectorField for "U" for that mesh. Note that it is an IOobject, it will be initially read from and subsequently written to the path [timeDir]/[regionName]/U - e.g you should have the files: 0/mesh1/U and 0/mesh2/U if you defined the fluid region names as mesh1 and mesh2 in constant/regionProperties.

The ptrList UFluid is then a bit like a 1D array, there is an element for each fluid region and each element contains a pointer to the volVectorField created. So if you do UFluid[1] you will get the U field for mesh1 and if you do UFluid[2] you will get the U field for mesh 2.

This means we don't have to clutter the programme up with lot's of variable names, can make use of loops for more concise code etc. Best of all it is very generic, so we can have more than two meshes if we want to.

Note that you can create a PtrList for a volScalarField etc too
Carlen and charryzzz like this.
rt08 is offline   Reply With Quote

Old   April 2, 2015, 11:00
Default
  #6
New Member
 
Ryan Tunstall
Join Date: Sep 2013
Posts: 10
Rep Power: 12
rt08 is on a distinguished road
Quote:
Originally Posted by Carlen View Post
Hi Ryan,
is this correct. I have to have U for the fine mesh and Utgt for the coarse mesh. I then write
Code:
PrtList<fvMesh> fluidRegions(2);

forAll(fluidRegions, i)
{
   fluidRegions.set
        (
            i,
            new fvMesh
            (
                IOobject
                (
                    fluidNames[i],
                    runTime.timeName(),
                    runTime,
                    IOobject::MUST_READ
                )
            )
        );
}
Then I put this in createMesh.H for creating both the fine and coarse mesh. Is this right?
I would recommend using the regionProperties class (https://github.com/OpenFOAM/OpenFOAM...gionProperties) and then create your meshes using the way shown in createFluidMeshes.H. If like me you don't have solid regions you can make your own version of regionProperties that only has fluids; by doing it this way a lot of things like the file structure of cases etc. is already taken care of and will be compatible with existing utilities. For example decomposePar has a -region [regionName] option, so if you design your solver to use the regionProperties class you will be able to use decomposePar with it easily.
Carlen likes this.
rt08 is offline   Reply With Quote

Old   April 2, 2015, 11:09
Default
  #7
Member
 
Join Date: Jul 2012
Posts: 67
Rep Power: 13
Carlen is on a distinguished road
Thank you very much Ryan,
Now I feel more confident writing my own solver. One more question, do I need to make changes to Ueqn, pEqn etc.? because from what I see they use
Code:
 

fvc::interpolate(rho*HbyA) & mesh.Sf()
to calculate the flux. Then my question is what "mesh" in the above equation refers to? In my case "Primary" or "Secondary", or it is completely different from what I understand?

kind regards,
carlen
Carlen is offline   Reply With Quote

Old   April 2, 2015, 11:21
Default
  #8
New Member
 
Ryan Tunstall
Join Date: Sep 2013
Posts: 10
Rep Power: 12
rt08 is on a distinguished road
Quote:
Originally Posted by Carlen View Post
Thank you very much Ryan,
Now I feel more confident writing my own solver. One more question, do I need to make changes to Ueqn, pEqn etc.? because from what I see they use
Code:
 

fvc::interpolate(rho*HbyA) & mesh.Sf()
to calculate the flux. Then my question is what "mesh" in the above equation refers to? In my case "Primary" or "Secondary", or it is completely different from what I understand?

kind regards,
carlen
The main solver has a time loop, in the time loop there is a second loop to loop through the regions. At the start of this second loop is setRegionFluidFields.H. This does things like this:

Code:
volVectorField& U = UFluid[i];
So on each time-step you loop though the regions, and at the start of the region loop you are creating a new U variable which is basically a link to the U of the mesh we are solving for at the minute (note though the & after volVectorField, meaning that U is not a copy of UFluid[i] but a reference to it). This is how it selects the variables from the correct mesh

I think this is just done to make the code that follows more concise. However I find it easier to just use the existing PtrList, so if I want U from mesh i I put UFluid[i]; then there is no need for setRegionFluidFields.H
rt08 is offline   Reply With Quote

Old   April 2, 2015, 11:49
Default
  #9
Member
 
Join Date: Jul 2012
Posts: 67
Rep Power: 13
Carlen is on a distinguished road
Thank you Ryan!
That's much more clear! I will try to write my solver and can I get back to you if I have more questions?

Best,
carlen
Carlen is offline   Reply With Quote

Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
MeshToMesh parallel ganeshv OpenFOAM Programming & Development 17 December 21, 2023 13:58
simpleFoam parallel AndrewMortimer OpenFOAM Running, Solving & CFD 12 August 7, 2015 18:45
simpleFoam in parallel issue plucas OpenFOAM Running, Solving & CFD 3 July 17, 2013 11:30
Parallel running runtime modifiable timestep sampaio OpenFOAM Running, Solving & CFD 1 May 26, 2005 19:18
transient, parallel - problem with timestep Peter CFX 5 March 8, 2005 16:15


All times are GMT -4. The time now is 00:18.