instructional workshop on openfoam programming lecture # 5€¦ · instructional workshop on...

32
Instructional workshop on OpenFOAM programming LECTURE # 5 Pavanakumar Mohanamuraly April 28, 2014

Upload: others

Post on 21-Oct-2020

11 views

Category:

Documents


1 download

TRANSCRIPT

  • Instructional workshop on OpenFOAMprogramming

    LECTURE # 5

    Pavanakumar Mohanamuraly

    April 28, 2014

  • Outline

    User defined boundary conditions - part I

    User defined boundary conditions - part II

  • Recap

    I fvMatrix class and boundaryCoeffs and internalCoeffsI Typos in Day 2 slides

    I FVPatch should have been FvPatchI Make/files - missed an ‘s ′ in RobinFvPatchFields.C

  • Implementing Robins BC

    I No need for two versions to be implemented fvm and fvc

    I Need to read in three extra parameter φ′, a and b

    aφ(0) + bφ′(0) and/or aφ(L) + bφ′(L) (1)

    I This will introduce one extra RHS source term to theDirichlet BC

    I Makes sense to use the Dirichlet BC and modify it for Robin

  • Hands on - Setting upI Copy the contents of

    FOAM SRC/finiteVolume/fields/fvPatchFields/basic/fixedValueto a folder named MY FOLDER/RobinBC

    I Rename all files having prefix fixedValueFvPatchField toRobinFvPatchField

    for name in fixedValueFvPatchField*do

    newname=RobinFvPatchField"$(echo "$name" | cut -c23-)"

    mv "$name" "$newname"done

    I Find and replace text fixedValueFvPatchField toRobinFvPatchField in all files

    sed -i 's/fixedValueFvPatchField/RobinFvPatchField/g' RobinFvPatchField*

  • Hands on - Make changes

    I Replace all fixedValue fields with Robin

    sed -i 's/fixedValue/Robin/g' RobinFvPatchField*

    I Runtime type information

    TypeName("Robin");

    I Runtime object selection

    RobinFvPatchFields.C:37:makePatchFields(Robin);RobinFvPatchFields.H:39:makePatchTypeFieldTypedefs(

    Robin)RobinFvPatchFieldsFwd.H:40:

    makePatchTypeFieldTypedefs(Robin)

    I wclean and

    I wmake libso to create library libRobinBC .so

  • Hands on - Compile code

    I Create the Make folder with files and options as follows

    files

    RobinFvPatchFields.C

    LIB = libRobinBC

    options

    EXE_INC = \-I$(LIB_SRC)/finiteVolume/lnInclude -g

    EXE_LIBS = -lfiniteVolume

    I wmake libso to create library libRobinBC .so

  • Hands on - More changes

    I Make the fixesValue() boolean function return false in fileRobinFvPatchField .H

    virtual bool fixesValue() const{return false;

    }

  • Hands on - Preliminary testing I

    I Go to the 1d case folder and add the following tosystem/controlDict

    libs ("libRobinBC.so");

    I Set the library environment search path to theMake/linux ∗ ∗ ∗ ∗∗ folder (where the libRobinBC .so iscreated)

    I Run the previous hands on example and check if you get errors

    I If you get a warning as shown below

    From function dlLibraryTable::open(const fileName&functionLibName)

    in file db/dlLibraryTable/dlLibraryTable.C at line85

    could not load dlopen(libRobinBC.so, 9): image notfound

    I Check your library path and see if the lib file exists

  • Hands on - Preliminary testing II

    I In the fields file replace all fixedValue types to Robin

    I Re-run the code and it should give the same results as runusing fixedValue

    I This ensures that the BC is compiled, loaded and setupcorrectly

  • Getting inputs - φ′, a and b

    I Declare variables (RobinFvPatchField.H)

    templateclass RobinFvPatchField: public fvPatchField{//- The $\phi'$ valueField gradPhiBoundary_;//- The const parameter a and bscalar a_, b_;

    I gradPhiBoundary is of type ”Field < Type > ” (scalar ,vector or tensor)

  • Getting inputs - φ′, a and b

    I Constructor - 1 (RobinFvPatchField.C)

    //- Construct from patch and internal fieldtemplateRobinFvPatchField::RobinFvPatchField(

    const fvPatch& p,const DimensionedField& iF

    ):fvPatchField( p, iF ),gradPhiBoundary_( p.size(), pTraits::zero ),a_(), b_(){}

  • Getting inputs - φ′, a and b

    I Constructor - 2 (RobinFvPatchField.C)

    templateRobinFvPatchField::RobinFvPatchField(

    const fvPatch& p,const DimensionedField& iF,const dictionary& dict

    ):fvPatchField( p, iF, dict, true ),gradPhiBoundary_( "gradient", dict, p.size() ),a_(dict.lookupOrDefault( "a", scalar(1.0))),b_(dict.lookupOrDefault( "b", scalar(0.0))){ }

  • Getting inputs - φ′, a and b

    I Constructor - 3 (RobinFvPatchField.C)

    templateRobinFvPatchField::RobinFvPatchField(

    const RobinFvPatchField& ptf,const fvPatch& p,const DimensionedField& iF,const fvPatchFieldMapper& mapper

    ):fvPatchField( ptf, p, iF, mapper ),gradPhiBoundary_( ptf.gradPhiBoundary_ ),a_( ptf.a_ ), b_( ptf.b_ ){}

  • Getting inputs - φ′, a and b

    I Constructor - 4 (RobinFvPatchField.C)

    templateRobinFvPatchField::RobinFvPatchField(

    const RobinFvPatchField& ptf):fvPatchField( ptf ),gradPhiBoundary_( ptf.gradPhiBoundary_ ),a_( ptf.a_ ), b_( ptf.b_ ){}

  • Getting inputs - φ′, a and b

    I Constructor - 5 (RobinFvPatchField.C)

    templateRobinFvPatchField::RobinFvPatchField(

    const RobinFvPatchField& ptf,const DimensionedField& iF

    ):fvPatchField( ptf, iF ),gradPhiBoundary_( ptf.gradPhiBoundary_ ),a_( ptf.a_ ), b_( ptf.b_ ){}

  • Getting inputs - φ′, a and b

    I Printing the boundary patch information(RobinFvPatchField.C)

    templatevoid RobinFvPatchField::write(Ostream& os)

    const{

    fvPatchField::write(os);this->writeEntry( "value", os);gradPhiBoundary_.writeEntry( "gradient", os);os.writeKeyword("a")

  • Hands on - Testing BC inputI Compile code again to create libRobinBC .soI Modify example (laplacian solver) - loop over boundaryFields

    and print field

    Info

  • Some concepts - deltaCoeffs()

    I deltaCoeffs() is the reciprocal distanceI Between owner and neighbour cell centroids of an internal face

    surfaceInterpolation.C : lines (234 - 242)

    // Set local references to mesh dataconst volVectorField& C = mesh_.C();const labelUList& owner = mesh_.owner();const labelUList& neighbour = mesh_.neighbour();

    forAll(owner, facei){DeltaCoeffs[facei] = 1.0/mag(C[neighbour[facei]] -

    C[owner[facei]]);}

  • Some concepts - deltaCoeffs()I deltaCoeffs() is the reciprocal distance

    I Between owner and boundary face centroid of patch face

    surfaceInterpolation.C : lines (244 - 248)

    forAll(DeltaCoeffs.boundaryField(), patchi){DeltaCoeffs.boundaryField()[patchi] =1.0/mag(mesh_.boundary()[patchi].delta());

    }

    fvPatch.C : lines (141 - 143)

    Foam::tmp Foam::fvPatch::delta()const

    {return Cf() - Cn();

    }

  • Some concepts - Patch gradient and value coefficients

    Patch object should return the following to evaluate patch BC foroperators

    I valueInternalCoeffs()I Return the matrix diagonal coefficients corresponding to the

    evaluation of the value of the patchField with given weights

    I valueBoundaryCoeffs()I Return the matrix source coefficients corresponding to the

    evaluation of the value of the patchField with given weight

    I gradientInternalCoeffs()I Return the matrix diagonal coefficients corresponding to the

    evaluation of the gradient of the patchField

    I gradientBoundaryCoeffs()I Return the matrix source coefficients corresponding to the

    evaluation of the gradient of this patchField

  • Some concepts - Patch value coefficients example

    Using the value internal/boundary coefficients to get fvMatrixentries (Gauss-Gradient scheme)

    gaussConvectionScheme.C (::fvmDiv function)

    forAll(fvm.psi().boundaryField(), patchI){

    const fvPatchField& psf =fvm.psi().boundaryField()[patchI];

    const fvsPatchScalarField& patchFlux =faceFlux.boundaryField()[patchI];

    const fvsPatchScalarField& pw =weights.boundaryField()[patchI];

    fvm.internalCoeffs()[patchI] =patchFlux*psf.valueInternalCoeffs(pw);

    fvm.boundaryCoeffs()[patchI] =-patchFlux*psf.valueBoundaryCoeffs(pw);

    }

  • Rationale behind value coefficients (face valueinterpolation)

    i=Ni=1

    i=Ni=1

    R L

    RL

    f1 f2

    L R

    ii-1 i+1

    iRL

    f1 f2

    R L

    i-1 i+1

    i = 1fx=0

    R L

    i = 2

    i = NRL

    fx=L

    I Dirichlet type

    φf = φ0︸︷︷︸RHS source

    + 0︸︷︷︸LHS coeff

    I Neumann boundary conditions

    δ∫0

    fx=0dx =

    δ∫0

    φf − φ1δ

    dx = φf − φ1

    φf = 1︸︷︷︸LHS coeff

    ×φ1 + fx=0δ︸ ︷︷ ︸RHS source

    (2)

  • Some concepts - fixedValue patch coefficients

    fixedValueFvPatchField.C

    templatetmp fixedValueFvPatchField::

    valueInternalCoeffs( const tmp& ) const{

    return tmp( new Field(this->size(), pTraits::zero) );

    }

    fixedValueFvPatchField.C

    templatetmp fixedValueFvPatchField::

    valueBoundaryCoeffs( const tmp& ) const{ return *this; } /// this has base class Field

  • Some concepts - fixedGradient patch coefficients

    fixedGradientFvPatchField.C

    templatetmp fixedGradientFvPatchField::

    valueInternalCoeffs( const tmp& ) const{

    return tmp(new Field(this->size(), pTraits::one));

    }

    fixedGradientFvPatchField.C

    templatetmp fixedGradientFvPatchField::

    valueBoundaryCoeffs( const tmp& ) const{ return gradient()/this->patch().deltaCoeffs(); }

  • Some concepts - Patch gradient coefficients example

    Using the value internal/boundary coefficients to get fvMatrixentries (Gauss-Laplacian scheme)

    gaussLaplacianScheme.C (::fvmLaplacianUncorrected function)

    forAll(fvm.psi().boundaryField(), patchI){

    const fvPatchField& psf = fvm.psi().boundaryField()[patchI];

    const fvsPatchScalarField& patchGamma =gammaMagSf.boundaryField()[patchI];

    fvm.internalCoeffs()[patchI] = patchGamma*psf.gradientInternalCoeffs();

    fvm.boundaryCoeffs()[patchI] = -patchGamma*psf.gradientBoundaryCoeffs();

    }

  • Rationale behind gradient coefficients (one-sided facegradient)

    i=Ni=1

    i=Ni=1

    R L

    RL

    f1 f2

    L R

    ii-1 i+1

    iRL

    f1 f2

    R L

    i-1 i+1

    i = 1fx=0

    R L

    i = 2

    i = NRL

    fx=L

    I Dirichlet type

    fx=0 =φfdx

    =φf − φ1

    δ=

    φfδ︸︷︷︸

    RHS source

    − 1δ︸︷︷︸

    LHS coeff

    φ1

    I Neumann boundary conditions

    fx=0 = φ′x=0︸︷︷︸

    RHS source

    + 0︸︷︷︸LHS coeff

  • Some concepts - fixedValue patch coefficients

    fixedValueFvPatchField.C

    templatetmp fixedValueFvPatchField::gradientInternalCoeffs() const{

    return -pTraits::one*this->patch().deltaCoeffs();}

    fixedValueFvPatchField.C

    templatetmp fixedValueFvPatchField::gradientBoundaryCoeffs() const{

    return this->patch().deltaCoeffs()*(*this);}

  • Some concepts - fixedGradient patch coefficients

    fixedGradientFvPatchField.C

    templatetmp fixedGradientFvPatchField::gradientInternalCoeffs() const{

    return tmp( new Field(this->size(), pTraits::zero) );

    }

    fixedGradientFvPatchField.C

    templatetmp fixedGradientFvPatchField::gradientBoundaryCoeffs() const{

    return gradient();}

  • Hands on - RobinBC implementation

    I Use the value and gradient coefficients shown in previousslides and implement the following Robin BC

    I At x = 0aφ(0) + bφ′(0) (3)

    I At x = Laφ(L) + bφ′(L) (4)

    I Compile the libRobinBC .so and test the code

    Custom BC done !

  • Robin BC

    i=Ni=1

    i=Ni=1

    R L

    RL

    f1 f2

    L R

    ii-1 i+1

    iRL

    f1 f2

    R L

    i-1 i+1

    i = 1fx=0

    R L

    i = 2

    i = NRL

    fx=L

    I Value Coefficients

    aφdirf + bφneuf = a︸︷︷︸

    LHS

    ×φ1 + bfx=0δ + aφ0︸ ︷︷ ︸RHS

    I Gradient Coefficients

    aφ′dirf + bφ′neuf = −

    a

    δ︸︷︷︸LHS

    ×φ1 +aφfδ

    + bφ′x=0︸ ︷︷ ︸RHS

    (5)

    I Remember a and b are between [0, 1] 0 ≤ a, b ≤ 1

  • End of Week 2 Day 3

    User defined boundary conditions - part IUser defined boundary conditions - part II