/*--------------------------------*- C++ -*----------------------------------*\
| =========                 |                                                 |
| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
|  \\    /   O peration     | Version:  v2012                                 |
|   \\  /    A nd           | Website:  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
{

    "(left|top|bottom)"                     
    {                                              
        // Dirichlet boundary                        
        type        codedFixedValue;                 
        value       uniform (0 0 0);                      
                                                   
        name        U_dirichlet;                              
                                                   
        code                                         
        #{                                           
                                                   
            // Gets current patch                      
            const fvPatch& boundaryPatch = patch();    
                                                   
            // Gets the patch face centres values      
            const vectorField& Cf = boundaryPatch.Cf(); 
                                                   
            // Gets the current field                  
            vectorField& field = *this;                         
                                                   
            // MMS                                     
                                                 
            // Loops over the patch                    
            forAll(Cf, faceI)                          
            {                                          
                // Gets the x component of the current cell 
                const scalar x = Cf[faceI].x(); 

                //Gets the y component of the current cell 
                const scalar y = Cf[faceI].y(); 
                                                  
                const scalar tmp0 = 2*M_PI*y; 
                const scalar tmp1 = 2.5 - Foam::sqrt(6.25 + 4*Foam::pow(M_PI, 2)); 
                const scalar tmp2 = Foam::exp(tmp1*x); 
                const scalar U_1 = -tmp2*Foam::cos(tmp0) + 1; 
                const scalar U_2 = (1.0/2.0)*tmp1*tmp2*Foam::sin(tmp0)/M_PI; 
                const scalar U_3 = 0; 
                                                 
                
                const vector U( U_1, U_2, U_3 ); 
                field[faceI] = U; 
                                           
            }                                          

        #};                                          
    }

    right
    {                                              
        // Neumann boundary                          
        type            codedMixed;                  
        refValue        uniform (0 0 0);                  
        refGradient     uniform (0 0 0);                  
        valueFraction   uniform 0;                   
                                                   
        name        U_Neumann;                              
                                                   
        code                                         
        #{                                           
                                                   
            // Gets current patch                      
            const fvPatch& boundaryPatch = patch();    
                                                   
            // Gets the patch face centres values      
            const vectorField& Cf = boundaryPatch.Cf(); 
                                                   
            const vectorField nf = patch().nf();       
                                                   
            // MMS                                     
                                                   
                                                 
            // Loops over the patch                    
            forAll(this->patch(), faceI)               
            {                                          
                // Gets the x component of the current cell 
                const scalar x = Cf[faceI].x(); 

                //Gets the y component of the current cell 
                const scalar y = Cf[faceI].y(); 
                                                  
                const scalar tmp0_0 = 2*M_PI; 
                const scalar tmp0_1 = tmp0_0*y; 
                const scalar tmp0_2 = 2.5 - Foam::sqrt(6.25 + 4*Foam::pow(M_PI, 2)); 
                const scalar tmp0_3 = Foam::exp(tmp0_2*x); 
                const scalar dU1_dx = -tmp0_2*tmp0_3*Foam::cos(tmp0_1); 
                const scalar dU1_dy = tmp0_0*tmp0_3*Foam::sin(tmp0_1); 
                const scalar dU1_dz = 0; 
                const scalar tmp1_0 = 2*M_PI*y; 
                const scalar tmp1_1 = 2.5 - Foam::sqrt(6.25 + 4*Foam::pow(M_PI, 2)); 
                const scalar tmp1_2 = Foam::exp(tmp1_1*x); 
                const scalar dU2_dx = (1.0/2.0)*tmp1_2*Foam::sin(tmp1_0)*(tmp1_1*tmp1_1)/M_PI; 
                const scalar dU2_dy = tmp1_1*tmp1_2*Foam::cos(tmp1_0); 
                const scalar dU2_dz = 0; 
                const scalar dU3_dx = 0; 
                const scalar dU3_dy = 0; 
                const scalar dU3_dz = 0; 
                                                 

                const scalar normal_1 = vector(dU1_dx, dU1_dy, dU1_dz) & nf[faceI] ; 

                const scalar normal_2 = vector(dU2_dx, dU2_dy, dU2_dz) & nf[faceI] ; 

                const scalar normal_3 = vector(dU3_dx, dU3_dy, dU3_dz) & nf[faceI] ; 

                const vector normalGradient (normal_1, normal_2, normal_3); 
                this->refGrad()[faceI] = normalGradient; 
                this->valueFraction()[faceI] = scalar(0); 
                                                 
            }                                          

        #};                                          
    }

    frontAndBack
    {
        type            empty;
    }
}


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