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

mass flow split BC

Register Blogs Community New Posts Updated Threads Search

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old   November 23, 2012, 11:52
Default mass flow split BC
  #1
Member
 
Join Date: Jul 2012
Posts: 31
Rep Power: 14
kpax is on a distinguished road
Fellow FOAMers,

i am currently simulating the flow in a tube with one inlet and two outlets. In Fluent, there is a mass flow split BC (http://hpce.iitm.ac.in/website/Manua...ug/node246.htm):
if you set, e.g., 0.5 for both outlets, the inlet flow will be split to 50% for each outlet (no matter what the geometry looks like).

Does something like that exist in OF? I couldn't find anything... maybe it could be built from flowRateInletVelocity?


Any help or advice is appreciated.

kpax
kpax is offline   Reply With Quote

Old   November 23, 2012, 14:02
Default
  #2
Assistant Moderator
 
Bernhard Gschaider
Join Date: Mar 2009
Posts: 4,225
Rep Power: 51
gschaider will become famous soon enoughgschaider will become famous soon enough
Quote:
Originally Posted by kpax View Post
Fellow FOAMers,

i am currently simulating the flow in a tube with one inlet and two outlets. In Fluent, there is a mass flow split BC (http://hpce.iitm.ac.in/website/Manua...ug/node246.htm):
if you set, e.g., 0.5 for both outlets, the inlet flow will be split to 50% for each outlet (no matter what the geometry looks like).

Does something like that exist in OF? I couldn't find anything... maybe it could be built from flowRateInletVelocity?


Any help or advice is appreciated.
I don't think there is something built in (but I'm willing to be taught differently).
Such a boundary condition (or something more flexible ) can be constructed with groovyBC from the swak4Foam-suite which allows boundary conditions to access the values on other patches
__________________
Note: I don't use "Friend"-feature on this forum out of principle. Ah. And by the way: I'm not on Facebook either. So don't be offended if I don't accept your invitation/friend request
gschaider is offline   Reply With Quote

Old   November 26, 2012, 07:59
Default
  #3
Member
 
Join Date: Jul 2012
Posts: 31
Rep Power: 14
kpax is on a distinguished road
ok...

does someone know then how the mass flow split BC is implemented in FLUENT?

I would think that the easiest way would be to adjust the pressure at the outlets in a way that ensure the prescribed mass flow split, but i'm not sure how that could be done.
Or maybe modify the outlet velocities? That seems difficult to me because they can have arbitrary profiles..
kpax is offline   Reply With Quote

Old   November 27, 2012, 07:52
Default
  #4
Member
 
Robert
Join Date: Aug 2012
Location: Berlin
Posts: 74
Rep Power: 14
vainilreb is on a distinguished road
Well there is the mass flow BC for the inlet which calculates the velocity by the mass flow and the density. Maybe you could simply take the formula of this BC to calculate the flux over the inlet and then simply set your outlet BC with the mass flow BC, but half of the inlet mass flow.

Does this help you?
vainilreb is offline   Reply With Quote

Old   November 27, 2012, 09:25
Default
  #5
Member
 
Join Date: Jul 2012
Posts: 31
Rep Power: 14
kpax is on a distinguished road
well, that was my first idea too, but as far as i understand flowRateInletVelocity, it sets a uniform velocity profile at the patch (be it outlet or inlet). at the outlet, however, i certainly have a developed velocity profile, so using this BC would not give a correct solution.

any other ideas?
kpax is offline   Reply With Quote

Old   November 27, 2012, 09:39
Default
  #6
Member
 
Robert
Join Date: Aug 2012
Location: Berlin
Posts: 74
Rep Power: 14
vainilreb is on a distinguished road
If you know your inlet mass flow, you could calculate the outlet mass flow for each pipe and assume the velocity profile to be a fully developed turbulent or laminar profile... Afaik this should be implementable using Swak4Foam or groovyBC, you just have to calculate the radial gradient of the velocity.

But then this would influence the flow behaviour upstream the outlets, too. :/

Or maybe you could specify a pressure at the outlets so that the flow departs itself in two equivalent mass flows? I think knowing the real setup you're trying to simulate would help finding the best solution!
vainilreb is offline   Reply With Quote

Old   November 27, 2012, 09:49
Default
  #7
Member
 
Join Date: Jul 2012
Posts: 31
Rep Power: 14
kpax is on a distinguished road
hey vainilreb, thx for the swift answer!


Quote:
Originally Posted by vainilreb View Post
If you know your inlet mass flow, you could calculate the outlet mass flow for each pipe and assume the velocity profile to be a fully developed turbulent or laminar profile... Afaik this should be implementable using Swak4Foam or groovyBC, you just have to calculate the radial gradient of the velocity.
the velocity profiles at the oulets are not fully developed (i.e., parabolic), because the geometry right before the outlets is curved. so assuming anything about the velocity profile will probably give false results, imo.


Quote:
Originally Posted by vainilreb View Post
Or maybe you could specify a pressure at the outlets so that the flow departs itself in two equivalent mass flows? I think knowing the real setup you're trying to simulate would help finding the best solution!
how could this pressure be set? the simulation is transient, with a varying velocity inlet profile, so the pressure values that give the correct flow split would have to be calculated for each time step..
i could create a new solver that iteratively calculates these pressure values for every time step by applying PISO repeatedly and adjusting the p values. but i think that would be quite time-consuming, and since a simple mass flow split BC exists in fluent, i thought there must be an easier way?
kpax is offline   Reply With Quote

Old   November 27, 2012, 10:07
Default
  #8
Member
 
Robert
Join Date: Aug 2012
Location: Berlin
Posts: 74
Rep Power: 14
vainilreb is on a distinguished road
I would have made a first try by setting the pressure as fixedValue, but even then it's a tough task finding the right pressure level. I would have tried keeping pi*r²*p equal for both outlets. You could set the pressure at the smaller outlet equal to ambient pressure and calculate the pressure at the larger outlet from this value. But I can't say if it will work.

Can you give more information on flow past the outlets? If you get two equal mass flows in reality, this must result from something?

Physically you must realize an equal pressure loss from inlet to outlet1 and from inlet to outlet2... Or setup a pressure acting against the flow direction, which equals the difference in pressure loss.
vainilreb is offline   Reply With Quote

Old   November 27, 2012, 10:56
Default
  #9
Assistant Moderator
 
Bernhard Gschaider
Join Date: Mar 2009
Posts: 4,225
Rep Power: 51
gschaider will become famous soon enoughgschaider will become famous soon enough
Quote:
Originally Posted by vainilreb View Post
Well there is the mass flow BC for the inlet which calculates the velocity by the mass flow and the density. Maybe you could simply take the formula of this BC to calculate the flux over the inlet and then simply set your outlet BC with the mass flow BC, but half of the inlet mass flow.
But resist the temptation to fix the mass flux on the other outlet too. Fixing the velocity on all boundaries usual ends in tears (violated mass conservation)
__________________
Note: I don't use "Friend"-feature on this forum out of principle. Ah. And by the way: I'm not on Facebook either. So don't be offended if I don't accept your invitation/friend request
gschaider is offline   Reply With Quote

Old   November 27, 2012, 11:02
Talking
  #10
Member
 
Robert
Join Date: Aug 2012
Location: Berlin
Posts: 74
Rep Power: 14
vainilreb is on a distinguished road
But it's be possible to fix all three pressure levels to get the desired mass flow without bursting into tears, does it?
vainilreb is offline   Reply With Quote

Old   November 27, 2012, 13:43
Default
  #11
Assistant Moderator
 
Bernhard Gschaider
Join Date: Mar 2009
Posts: 4,225
Rep Power: 51
gschaider will become famous soon enoughgschaider will become famous soon enough
Quote:
Originally Posted by vainilreb View Post
But it's be possible to fix all three pressure levels to get the desired mass flow without bursting into tears, does it?
Well. If you know the pressure that is necessary to get a specific mass flow then the question is: why do you want to do CFD in the first place. Because it seems that your system is simple enough to be treated with a Bernoulli equation
__________________
Note: I don't use "Friend"-feature on this forum out of principle. Ah. And by the way: I'm not on Facebook either. So don't be offended if I don't accept your invitation/friend request
gschaider is offline   Reply With Quote

Old   November 29, 2012, 04:34
Default
  #12
Member
 
Robert
Join Date: Aug 2012
Location: Berlin
Posts: 74
Rep Power: 14
vainilreb is on a distinguished road
Sounds reasonable... But I'm afraid it won't help kpax to list all the things that will NOT work?
vainilreb is offline   Reply With Quote

Old   November 29, 2012, 05:51
Default
  #13
Assistant Moderator
 
Bernhard Gschaider
Join Date: Mar 2009
Posts: 4,225
Rep Power: 51
gschaider will become famous soon enoughgschaider will become famous soon enough
Quote:
Originally Posted by vainilreb View Post
Sounds reasonable... But I'm afraid it won't help kpax to list all the things that will NOT work?
OK. To summarize. What I'd do (it would need a bit of playing):

- inlet: fixed velocity, p zeroGradient
- outlet1: fixed p. U inletOutlet
- outlet2: p zeroGradient. U mass flow set to x% of inlet

outlet2 for a first test could be a simple fixedValue with a calculated value. Later a groovyBC that gets the MF from the inlet. If you want a developed profile at the outlet you might use groovyBC to rescale the velocity on the outlet, but that might be a bit tricky: a) during startup b) if you have backflow. Underrelaxation might be your friend
__________________
Note: I don't use "Friend"-feature on this forum out of principle. Ah. And by the way: I'm not on Facebook either. So don't be offended if I don't accept your invitation/friend request
gschaider is offline   Reply With Quote

Old   November 29, 2012, 11:30
Default
  #14
Member
 
Join Date: Jul 2012
Posts: 31
Rep Power: 14
kpax is on a distinguished road
thx guys, I'll think I will try to implement both your idea and a pressure-adjusting solver - we'll see what works best! :>
kpax is offline   Reply With Quote

Old   September 9, 2016, 07:45
Default
  #15
Member
 
Rudolf Hellmuth
Join Date: Sep 2012
Location: Dundee, Scotland
Posts: 40
Rep Power: 14
rudolf.hellmuth is on a distinguished road
I've got a slightly different, which has worked very well.

Since I knew the inlet flow rate (Q_in=40e-6 m^3 s^-1), I imposed outlet flow rates (70% / 30%), and left the velocity field as zeroGradient at the inlet. Pressure field uniform 0 at the inlet, and zeroGradient at the outlets.

The BC dictionaries follow below:

Code:
/*--------------------------------*- C++ -*----------------------------------*\
| =========                 |                                                 |
| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
|  \\    /   O peration     | Version:  v1606+                                |
|   \\  /    A nd           | Web:      www.OpenFOAM.com                      |
|    \\/     M anipulation  |                                                 |
\*---------------------------------------------------------------------------*/
FoamFile
{
    version     2.0;
    format      ascii;
    class       volVectorField;
    object      U;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

dimensions      [0 1 -1 0 0 0 0];

internalField   uniform (0 0 0);

boundaryField
{
    inlet
    {
        type            zeroGradient;
    }

    outlet1
    {
        type        flowRateInletVelocity;
        volumetricFlowRate  -28e-6;
        value       uniform (0 0 0); // placeholder
    }

    outlet2
    {
        type        flowRateInletVelocity;
        volumetricFlowRate  -12e-6;
        value       uniform (0 0 0); // placeholder
    }
    defaultFaces
    {
        type            noSlip;
    }
}

// ************************************************************************* //
Code:
/*--------------------------------*- C++ -*----------------------------------*\
| =========                 |                                                 |
| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
|  \\    /   O peration     | Version:  v1606+                                |
|   \\  /    A nd           | Web:      www.OpenFOAM.com                      |
|    \\/     M anipulation  |                                                 |
\*---------------------------------------------------------------------------*/
FoamFile
{
    version     2.0;
    format      ascii;
    class       volScalarField;
    object      p;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

dimensions      [0 2 -2 0 0 0 0];

internalField   uniform 0;

boundaryField
{
    inlet
    {
        type        fixedValue;    
        value       uniform 0;
    }

    outlet1
    {
        type            zeroGradient;
    }

    outlet2
    {
        type            zeroGradient;
    }

    defaultFaces
    {
        type            zeroGradient;
    }
}

// ************************************************************************* //
Cheers,
Rudolf
rudolf.hellmuth is offline   Reply With Quote

Old   September 12, 2016, 10:13
Default
  #16
Member
 
Rudolf Hellmuth
Join Date: Sep 2012
Location: Dundee, Scotland
Posts: 40
Rep Power: 14
rudolf.hellmuth is on a distinguished road
If you really want to impose the inlet velocity BC, you can try this coded BC for all outlets but one.

U:
Code:
/*--------------------------------*- C++ -*----------------------------------*\
| =========                 |                                                 |
| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
|  \\    /   O peration     | Version:  v1606+                                |
|   \\  /    A nd           | Web:      www.OpenFOAM.com                      |
|    \\/     M anipulation  |                                                 |
\*---------------------------------------------------------------------------*/
FoamFile
{
    version     2.0;
    format      ascii;
    class       volVectorField;
    object      U;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

dimensions      [0 1 -1 0 0 0 0];

internalField   uniform (0 0 0);

boundaryField
{
    inlet
    {
        type            fixedValue;
        value           uniform (0.1 0 0);
    }

    outlet1
    {
        type            codedFixedValue;
        value           uniform (1 0 0);
        redirectType    flowSplit;
        
        code
        #{
            scalar flowRatio = 0.7;
            const word refPatchName = "inlet";
            
            //----------------------------------------------------------------//
            const scalar& pi = constant::mathematical::pi;
            
            const fvPatchVectorField& thisBF = *this;
            scalar thisPatchArea = gSum(thisBF.patch().magSf());
            vector nf = gSum(thisBF.patch().magSf()*thisBF.patch().nf())
                        /thisPatchArea;
            
            const volVectorField& U = thisBF.db().lookupObject<volVectorField>("U");
            const surfaceScalarField& phi = thisBF.db().lookupObject<surfaceScalarField>("phi");
            
            const label refPatchLabel = U.mesh().boundaryMesh().findPatchID(refPatchName); 
            const fvPatchVectorField& refBF = U.boundaryField()[refPatchLabel];
            const fvsPatchScalarField& refBflux = phi.boundaryField()[refPatchLabel];
            
            scalar refFlowRate = gSum(refBflux);

            // Info << nl << "Flow rate at " << refPatchName 
                 // << ": " << refFlowRate << endl;

            operator==(-nf*flowRatio*refFlowRate/thisPatchArea);
        #};
    }

    outlet2
    {
        type    zeroGradient;
    }
    defaultFaces
    {
        type            noSlip;
    }
}

// ************************************************************************* //
p:
Code:
/*--------------------------------*- C++ -*----------------------------------*\
| =========                 |                                                 |
| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
|  \\    /   O peration     | Version:  v1606+                                |
|   \\  /    A nd           | Web:      www.OpenFOAM.com                      |
|    \\/     M anipulation  |                                                 |
\*---------------------------------------------------------------------------*/
FoamFile
{
    version     2.0;
    format      ascii;
    class       volScalarField;
    object      p;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

dimensions      [0 2 -2 0 0 0 0];

internalField   uniform 0;

boundaryField
{
    inlet
    {
        type            zeroGradient;
    }

    outlet1
    {
        type            zeroGradient;
    }

    outlet2
    {
        type            fixedValue;    
        value           uniform 0;
    }

    defaultFaces
    {
        type            zeroGradient;
    }
}

// ************************************************************************* //

It is a plug flow on outlet1, but it is developed flow on outlet2. I am not sure this is how Star-CCM+ does it, because I've heard it has plug flow in both splitted BCs, which I find funny because of the reasons Bernhard Gschaider has pointed out. Probably there is some black magic behind Star-CCM+ to keep the continuity equation right.

Cheers,
Rudolf
Attached Images
File Type: png 70to30flowSplit.png (14.8 KB, 24 views)
rudolf.hellmuth is offline   Reply With Quote

Old   September 19, 2016, 07:37
Default
  #17
Member
 
Rudolf Hellmuth
Join Date: Sep 2012
Location: Dundee, Scotland
Posts: 40
Rep Power: 14
rudolf.hellmuth is on a distinguished road
I wasn't happy with the fixed constant pressure field at outlet1, because it looked very artificial to have both the pressure at the inlet and outlet2 changing depending on the split ratio. Therefore, against gschaider advices, I set all pressure BCs as zeroGradient, and I imposed the flow rates on both outlets. Of course, I had to set pRefCell=0 and pRefValue=0 in the fvSolution dictionary.

Surprisingly for me, the continuity residuals didn't explode, even when I oscillated the flow split ratio. I verified the flow rates in Paraview, which resulted in Phi.inlet = Phi.outlet1 + Phi.outlet2 for all times. Pressure at the inlet is constant, and it oscillates freely between outlets.

It seems that this is the way StarCCM+ does that, according to what I've seen from simulations using the flow split BC in StarCCM+. In Star, the split BCs have constant velocity at the outlet, and pressure is not constraint.

The OpenFOAM BC dictionaries follow:

p:
Code:
/*--------------------------------*- C++ -*----------------------------------*\
| =========                 |                                                 |
| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
|  \\    /   O peration     | Version:  v1606+                                |
|   \\  /    A nd           | Web:      www.OpenFOAM.com                      |
|    \\/     M anipulation  |                                                 |
\*---------------------------------------------------------------------------*/
FoamFile
{
    version     2.0;
    format      ascii;
    class       volScalarField;
    object      p;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

dimensions      [0 2 -2 0 0 0 0];

internalField   uniform 0;

boundaryField
{
    inlet
    {
        type            zeroGradient;
    }

    outlet1
    {
        type            zeroGradient;
    }

    outlet2
    {
        type            zeroGradient;
    }

    defaultFaces
    {
        type            zeroGradient;
    }
}
U:
Code:
/*--------------------------------*- C++ -*----------------------------------*\
| =========                 |                                                 |
| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
|  \\    /   O peration     | Version:  v1606+                                |
|   \\  /    A nd           | Web:      www.OpenFOAM.com                      |
|    \\/     M anipulation  |                                                 |
\*---------------------------------------------------------------------------*/
FoamFile
{
    version     2.0;
    format      ascii;
    class       volVectorField;
    object      U;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //


dimensions      [0 1 -1 0 0 0 0];

internalField   uniform (0 0 0);

boundaryField
{
    inlet
    {
        type            fixedValue;
        value           uniform (0.1 0 0);
    }
    
    outlet1 
    {
        type            codedFixedValue;
        value           uniform (1 0 0);
        redirectType    flowSplit1;
        
        code
        #{
            scalar flowRatio = 1;
            const word refPatchName = "inlet";
            
            // ----------------------------------------------------------------//
            const scalar& pi = constant::mathematical::pi;
            
            const fvPatchVectorField& thisBF = *this;
            scalar thisPatchArea = gSum(thisBF.patch().magSf());
            vector nf = gSum(thisBF.patch().magSf()*thisBF.patch().nf())
                        /thisPatchArea;
            
            const volVectorField& U = thisBF.db().lookupObject<volVectorField>("U");
            const surfaceScalarField& phi = thisBF.db().lookupObject<surfaceScalarField>("phi");
            
            const label refPatchLabel = U.mesh().boundaryMesh().findPatchID(refPatchName); 
            const fvPatchVectorField& refBF = U.boundaryField()[refPatchLabel];
            const fvsPatchScalarField& refBFlux = phi.boundaryField()[refPatchLabel];
            
            scalar refFlowRate = gSum(refBFlux);
                 
            scalar t = this->db().time().value();

            operator==
            (
                -nf*flowRatio*refFlowRate/thisPatchArea
                 *0.5*(sin(2*pi*t + pi) + 1.0)
            );
        #};
    }

    outlet2
    {
        type            codedFixedValue;
        value           uniform (1 0 0);
        redirectType    flowSplit2;
        
        code
        #{
            scalar flowRatio = 1;
            const word refPatchName = "inlet";
            
            // ----------------------------------------------------------------//
            const scalar& pi = constant::mathematical::pi;
            
            const fvPatchVectorField& thisBF = *this;
            scalar thisPatchArea = gSum(thisBF.patch().magSf());
            vector nf = gSum(thisBF.patch().magSf()*thisBF.patch().nf())
                        /thisPatchArea;
            
            const volVectorField& U = thisBF.db().lookupObject<volVectorField>("U");
            const surfaceScalarField& phi = thisBF.db().lookupObject<surfaceScalarField>("phi");
            
            const label refPatchLabel = U.mesh().boundaryMesh().findPatchID(refPatchName); 
            const fvPatchVectorField& refBF = U.boundaryField()[refPatchLabel];
            const fvsPatchScalarField& refBFlux = phi.boundaryField()[refPatchLabel];
            
            scalar refFlowRate = gSum(refBFlux);
                 
            scalar t = this->db().time().value();

            operator==
            (
                -nf*flowRatio*refFlowRate/thisPatchArea
                 *0.5*(sin(2*pi*t) + 1.0)
            );
        #};
    }
    defaultFaces
    {
        type            noSlip;
    }
}
Note that the split oscillations have a phase shift = pi rad, between outlet1 and outlet2.

blockMeshDict:
Code:
/*--------------------------------*- C++ -*----------------------------------*\
| =========                 |                                                 |
| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
|  \\    /   O peration     | Version:  v1606+                                |
|   \\  /    A nd           | Web:      www.OpenFOAM.com                      |
|    \\/     M anipulation  |                                                 |
\*---------------------------------------------------------------------------*/
FoamFile
{
    version     2.0;
    format      ascii;
    class       dictionary;
    object      blockMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

//           outlet1
//             +-+
//             | |
//             | |
//             | |
//             | |
// +-----------+ |
// |inlet        |
// +-----------+ |
//             | |
//             | |
//             | |
//             | |
//             +-+
//           outlet2

convertToMeters 1;

vertices
(
    (0.0  -0.01 0)   //0
    (0.2  -0.01 0)
    (0.2   0.01 0)   //2
    (0.0   0.01 0)

    (0.22 -0.01 0)  //4
    (0.22  0.01 0)

    (0.2  -0.21 0)  //6
    (0.22 -0.21 0)

    (0.2   0.21 0)  //8
    (0.22  0.21 0)

    // Z
    (0.0  -0.01 0.02)   //0
    (0.2  -0.01 0.02)
    (0.2   0.01 0.02)   //2
    (0.0   0.01 0.02)

    (0.22 -0.01 0.02)  //4
    (0.22  0.01 0.02)

    (0.2  -0.21 0.02)  //6
    (0.22 -0.21 0.02)

    (0.2   0.21 0.02)  //8
    (0.22  0.21 0.02)

);

blocks
(
    // inlet block
    hex (0 1 2 3  10 11 12 13) (100 10 10) simpleGrading (1 1 1)

    // central block
    hex (1 4 5 2  11 14 15 12) (10 10 10) simpleGrading (1 1 1)

    // bottom block
    hex (6 7 4 1  16 17 14 11) (10 100 10) simpleGrading (1 1 1)

    // top block
    hex (2 5 9 8  12 15 19 18) (10 100 10) simpleGrading (1 1 1)
);

edges
(
);

boundary
(
    inlet
    {
        type patch;
        faces
        (
            (0 10 13 3)
        );
    }

    outlet1
    {
        type patch;
        faces
        (
            (6 7 17 16)
        );
    }

    outlet2
    {
        type patch;
        faces
        (
            (8 18 19 9)
        );
    }

    defaultFaces
    {
        type wall;
        faces ();
    }
);

mergePatchPairs
(
);

// ************************************************************************* //
Watch the video.

Best regards,
Rudolf

Last edited by rudolf.hellmuth; September 19, 2016 at 13:00.
rudolf.hellmuth is offline   Reply With Quote

Old   October 13, 2016, 09:29
Default
  #18
Member
 
Rudolf Hellmuth
Join Date: Sep 2012
Location: Dundee, Scotland
Posts: 40
Rep Power: 14
rudolf.hellmuth is on a distinguished road
I transcribed the codedFixedValue that I used above to prototype my BC to an actual C++ BC class. I used the template given by the foamNewBC -f -v script. The new BC name is flowSplit, and its class is called flowSplitFvPatchVectorField.

flowSplitFvPatchVectorField working, but not exactly as the codedFixedValue. It is not converging with all pressure BCs as zeroGradient and a pRefCell. I have now to set a pressure BC as fixedValue. I don't know why is that happening. Otherwise, the solution is correct.

flowSplitFvPatchVectorField.H
Code:
/*---------------------------------------------------------------------------*\
  =========                 |
  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
   \\    /   O peration     |
    \\  /    A nd           | Copyright (C) 2016 OpenFOAM Foundation
     \\/     M anipulation  |
-------------------------------------------------------------------------------
License
    This file is part of OpenFOAM.

    OpenFOAM is free software: you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    for more details.

    You should have received a copy of the GNU General Public License
    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.

Class
    Foam::flowSplitFvPatchVectorField

Group
    grpGenericBoundaryConditions

Description
    This boundary condition provides a flowSplit condition,
    calculated as:

        \f[
            Q_{patch} = s*Q_{ref}
        \f]

    where
    \vartable
        s           | Flow ratio [dimLess]
        Q_{patch}   | Flow rate on this patch [m^3/s]
        Q_{ref}     | vector field across patch [units]
    \endtable

    Other patches can also use this BC, provided that the sum of all flow ratios
    is \f[ \sum s_i = 1 \f], if there is no other free stream patch.
    
    \heading Patch usage

    \table
        Property        | Description           | Req'd? | Default
        refPatchName    | reference patch name  | yes    | no
        flowRatio       | Flow ratio [dimLess]  | yes    | no
    \endtable

    Example of the boundary condition specification:
    \verbatim
    myPatch
    {
        type            flowSplit;
        refPatchName    inlet;
        flowRatio       0.5;
    }
    \endverbatim

Note
    - Take care about the continuity equation (\f[ \sum Q_{in} = \sum Q_{out} \f])!
    - Pressure value must be specified on one patch.

SeeAlso
    Foam::fixedValueFvPatchField
    Foam::Function1Types
    
    
SourceFiles
    flowSplitFvPatchVectorField.C

\*---------------------------------------------------------------------------*/

#ifndef flowSplitFvPatchVectorField_H
#define flowSplitFvPatchVectorField_H

#include "fixedValueFvPatchFields.H"
#include "Function1.H"

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

namespace Foam
{

/*---------------------------------------------------------------------------*\
     Class flowSplitFvPatchVectorField Declaration
\*---------------------------------------------------------------------------*/

class flowSplitFvPatchVectorField
:
    public fixedValueFvPatchVectorField
{
    // Private data

        //- Reference patch name
        word refPatchName_;
        
        //- Flow rate fraction of the reference patch
        scalar flowRatio_;
        
        //- Rference patch label
        label refPatchLabel_;


public:

    //- Runtime type information
    TypeName("flowSplit");


    // Constructors

        //- Construct from patch and internal field
        flowSplitFvPatchVectorField
        (
            const fvPatch&,
            const DimensionedField<vector, volMesh>&
        );

        //- Construct from patch, internal field and dictionary
        flowSplitFvPatchVectorField
        (
            const fvPatch&,
            const DimensionedField<vector, volMesh>&,
            const dictionary&
        );

        //- Construct by mapping given fixedValueTypeFvPatchField
        //  onto a new patch
        flowSplitFvPatchVectorField
        (
            const flowSplitFvPatchVectorField&,
            const fvPatch&,
            const DimensionedField<vector, volMesh>&,
            const fvPatchFieldMapper&
        );

        //- Construct as copy
        flowSplitFvPatchVectorField
        (
            const flowSplitFvPatchVectorField&
        );

        //- Construct and return a clone
        virtual tmp<fvPatchVectorField> clone() const
        {
            return tmp<fvPatchVectorField>
            (
                new flowSplitFvPatchVectorField(*this)
            );
        }

        //- Construct as copy setting internal field reference
        flowSplitFvPatchVectorField
        (
            const flowSplitFvPatchVectorField&,
            const DimensionedField<vector, volMesh>&
        );

        //- Construct and return a clone setting internal field reference
        virtual tmp<fvPatchVectorField> clone
        (
            const DimensionedField<vector, volMesh>& iF
        ) const
        {
            return tmp<fvPatchVectorField>
            (
                new flowSplitFvPatchVectorField
                (
                    *this,
                    iF
                )
            );
        }


    // Member functions

        // Evaluation functions

            //- Update the coefficients associated with the patch field
            virtual void updateCoeffs();


        //- Write
        virtual void write(Ostream&) const;
};


// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

} // End namespace Foam

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //


#endif

// ************************************************************************* //
flowSplitFvPatchVectorField.C
Code:
/*---------------------------------------------------------------------------*\
  =========                 |
  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
   \\    /   O peration     |
    \\  /    A nd           | Copyright (C) 2016 OpenFOAM Foundation
     \\/     M anipulation  |
-------------------------------------------------------------------------------
License
    This file is part of OpenFOAM.

    OpenFOAM is free software: you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    for more details.

    You should have received a copy of the GNU General Public License
    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.

\*---------------------------------------------------------------------------*/

#include "flowSplitFvPatchVectorField.H"
#include "addToRunTimeSelectionTable.H"
#include "fvPatchFieldMapper.H"
#include "volFields.H"
#include "surfaceFields.H"

// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //

// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //

Foam::flowSplitFvPatchVectorField::
flowSplitFvPatchVectorField
(
    const fvPatch& p,
    const DimensionedField<vector, volMesh>& iF
)
:
    fixedValueFvPatchVectorField(p, iF),
    refPatchName_("wordDefault"),
    flowRatio_(0.0),
    refPatchLabel_(-1)
{
}


Foam::flowSplitFvPatchVectorField::
flowSplitFvPatchVectorField
(
    const fvPatch& p,
    const DimensionedField<vector, volMesh>& iF,
    const dictionary& dict
)
:
    fixedValueFvPatchVectorField(p, iF),
    refPatchName_(dict.lookup("refPatchName")),
    flowRatio_(readScalar(dict.lookup("flowRatio"))),
    refPatchLabel_(-1)
{
    const volVectorField& U = db().lookupObject<volVectorField>("U");
    refPatchLabel_ = U.mesh().boundaryMesh().findPatchID(refPatchName_); 
}


Foam::flowSplitFvPatchVectorField::
flowSplitFvPatchVectorField
(
    const flowSplitFvPatchVectorField& ptf,
    const fvPatch& p,
    const DimensionedField<vector, volMesh>& iF,
    const fvPatchFieldMapper& mapper
)
:
    fixedValueFvPatchVectorField(ptf, p, iF, mapper),
    refPatchName_(ptf.refPatchName_),
    flowRatio_(ptf.flowRatio_),
    refPatchLabel_(ptf.refPatchLabel_)
{}


Foam::flowSplitFvPatchVectorField::
flowSplitFvPatchVectorField
(
    const flowSplitFvPatchVectorField& ptf
)
:
    fixedValueFvPatchVectorField(ptf),
    refPatchName_(ptf.refPatchName_),
    flowRatio_(ptf.flowRatio_),
    refPatchLabel_(ptf.refPatchLabel_)
{}


Foam::flowSplitFvPatchVectorField::
flowSplitFvPatchVectorField
(
    const flowSplitFvPatchVectorField& ptf,
    const DimensionedField<vector, volMesh>& iF
)
:
    fixedValueFvPatchVectorField(ptf, iF),
    refPatchName_(ptf.refPatchName_),
    flowRatio_(ptf.flowRatio_),
    refPatchLabel_(ptf.refPatchLabel_)
{}


// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //

void Foam::flowSplitFvPatchVectorField::updateCoeffs()
{
    if (this->updated())
    {
        return;
    }
    
    scalar thisPatchArea = gSum(patch().magSf());
    
    // - patch average normal vector
    vector nf = gSum(patch().magSf()*patch().nf())
                /thisPatchArea;
    
    const surfaceScalarField& phi =
        db().lookupObject<surfaceScalarField>("phi");
    
    const fvsPatchScalarField& refPhip = phi.boundaryField()[refPatchLabel_];
    
    scalar refFlowRate = gSum(refPhip);
    
    operator==
    (
        -nf*flowRatio_*refFlowRate/thisPatchArea
    );

    fixedValueFvPatchVectorField::updateCoeffs();
}


void Foam::flowSplitFvPatchVectorField::write
(
    Ostream& os
) const
{
    fvPatchVectorField::write(os);
    os.writeKeyword("refPatchName") << refPatchName_ 
        << token::END_STATEMENT << nl;
    os.writeKeyword("flowRatio") << flowRatio_
        << token::END_STATEMENT << nl;
    os.writeKeyword("refPatchLabel") << refPatchLabel_ 
        << token::END_STATEMENT << nl;
    writeEntry("value", os);
}


// * * * * * * * * * * * * * * Build Macro Function  * * * * * * * * * * * * //

namespace Foam
{
    makePatchTypeField
    (
        fvPatchVectorField,
        flowSplitFvPatchVectorField
    );
}

// ************************************************************************* //
Any idea why is that happening?
rudolf.hellmuth is offline   Reply With Quote

Old   October 14, 2016, 07:34
Default
  #19
Member
 
Rudolf Hellmuth
Join Date: Sep 2012
Location: Dundee, Scotland
Posts: 40
Rep Power: 14
rudolf.hellmuth is on a distinguished road
Ok, I've figured it out. The BC class generated by codedFixedValue has a the constructor:
Code:
flowSplit1FixedValueFvPatchVectorField::
flowSplit1FixedValueFvPatchVectorField
(
    const fvPatch& p,
    const DimensionedField<vector, volMesh>& iF,
    const dictionary& dict
)
:
    fixedValueFvPatchField<vector>(p, iF, dict)
{
    if (false)
    {
        Info<<"construct flowSplit1 sha1: 59459d9eb2e11d9298b390a91c95556476fe80ed"
            " from patch/dictionary\n";
    }
}
This initialises the patch with fixedValueFvPatchField<vector>(p, iF, dict), and the same constructor given by the foamNewBC script initialises the patch with fixedValueFvPatchVectorField(p, iF). The former initialisation constructor requires the value entry in the dictionary, whereas the latter does not.

I've solved this issue by including a patch initialisation within the constructor, as suggested by the foamNewBC script:
Code:
Foam::flowSplitFvPatchVectorField::
flowSplitFvPatchVectorField
(
    const fvPatch& p,
    const DimensionedField<vector, volMesh>& iF,
    const dictionary& dict
)
:
    fixedValueFvPatchVectorField(p, iF),
    refPatchName_(dict.lookup("refPatchName")),
    flowRatio_(readScalar(dict.lookup("flowRatio"))),
    refPatchLabel_(-1)
{
    const volVectorField& U = db().lookupObject<volVectorField>("U");
    refPatchLabel_ = U.mesh().boundaryMesh().findPatchID(refPatchName_);
    
    // Initialise with the value entry if evaluation is not possible
    fvPatchVectorField::operator=
    (
        vectorField(patchInternalField())
    );
}
In this way, it is not required enter an initial value in the BC dictionary, but it copies the values from the neighbour cells to the patch. Another option would be to change the patch initialisation to fixedValueFvPatchScalarField(p, iF, dict), so that the initial value will be required.

All the best,
Rudolf
rudolf.hellmuth is offline   Reply With Quote

Old   October 14, 2016, 07:36
Default
  #20
Member
 
Rudolf Hellmuth
Join Date: Sep 2012
Location: Dundee, Scotland
Posts: 40
Rep Power: 14
rudolf.hellmuth is on a distinguished road
Sorry, I wanted to delete this post.
rudolf.hellmuth 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
mass flow inlet and pressure outlet with target mass flow rate Zigainer FLUENT 13 October 26, 2018 06:58
Convergence problem with target mass flow rate ADL FLUENT 2 May 29, 2012 22:11
different mass flow rates michael FLUENT 4 February 21, 2005 04:48
Determine mass flow rate along flow path Atit Koonsrisuk CFX 2 October 5, 2003 05:47
Mass Flow Inlet Pravir Kumar Rai FLUENT 0 February 17, 2003 20:23


All times are GMT -4. The time now is 20:45.