Code Monkey home page Code Monkey logo

meshbalancing's Introduction

meshBalancing

This contains a single library, dynamicRefineBalancedFvMesh which is based on dynamicRefineFvMesh but adds mesh balancing for parallel cases to the update() function.

This works in OpenFOAM-2.3.x with the interFoam family of solvers, but not the chemistry-based solvers yet, due to an issue with the redistribution of DimensionedFields. Per Mantis Bug Report #1203 this should be resolved in the next version of OpenFOAM.

Usage

To use the balancing library with an existing 'DyM' solver you have to make the following edits to the case (in addition to the changes to the source code in the section below)

  1. Add a linking statement to the new library in controlDict

    libs ( "libdynamicFvMesh-dev.so" );

  2. Add the balanceParDict dictionary to the system folder (example in the library folder)

  3. Change the mesh type in dynamicMeshDict to dynamicRefineBalancedFvMesh

  4. Add the following two entries to the dynamicRefineFvMeshCoeffs dictionary (see the example in the library folder)

    enableBalancing true; allowableImbalance 0.15;

  5. You can also add a refinementControl entry to enable refinement based on field gradients, field curl, and specified regions of refinement.

Notes

To use this with interDyMFoam, you have to move the call to createPrghCorrTypes inside correctPhi.H to avoid a crash when the number of patches changes and recompile the solver.

OpenFOAM Source Changes (for 2.3.x)

To use this library with interDyMFoam and similar solvers, you do not need to make all the listed edits. Fixing issue 1 should allow most simulations to be run without errors or warnings. If you are using non-Newtonian viscosity models you will have to fix issue 7 too.

  1. [ WARNINGS ] There was a small change in version 2.2.x in src/dynamicMesh/fvMeshAdder/fvMeshAdderTemplates.C which results in an excessive number of warnings. In the MapVolField function, there are two calls to calcPatchMap. The map given to the patches may contain unmapped cells until the last mapping. To supress the warnings, change the unmapped value entry from -1 to 0 (the value it used to be) on lines 139 and 201. A similar edit is required in MapSurfaceField on lines 447 and 508.

    This switch to a default of -1 was also included in src/finiteVolume/fvMesh/fvMeshSubSet/fvMeshSubsetInterpolate.C in a number of places. Find where directAddressing is set to a default of -1 and change it to use a default of 0.

  2. [ CRASH ] DimensionedFields are not properly distributed in the current implementation. To enable distribution of DimensionedFields you will have to make the following changes (NOTE: This may still not work):

1. Add a constructor for DimensionedField which is consistent with the one
   used in fvMeshSubset. I recommend you recompile the entire src directory 
   after this step.
     
   **src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedField.H**

   _line 151ish, add:_

        //- Construct from dictionary
        DimensionedField
        (
            const IOobject&,
            const Mesh& mesh,
            const dictionary& fieldDict,
            const word& fieldDictEntry="value"
        );
        
   **src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldIO.C**

   _line 82ish, add:_

        template<class Type, class GeoMesh>
        Foam::DimensionedField<Type, GeoMesh>::DimensionedField
        (
            const IOobject& io,
            const Mesh& mesh,
            const dictionary& fieldDict,
            const word& fieldDictEntry
        )
        :
            regIOobject(io),
            Field<Type>(0),
            mesh_(mesh),
            dimensions_(dimless)
        {
            readField(fieldDict, fieldDictEntry);
        }
  
2. Add an interpolate template to fvMeshSubset that can handle
   a DimensionedField<type,volMesh> input
  
    **src/finiteVolume/fvMesh/fvMeshSubset/fvMeshSubset.H**

    _somewhere in the public functions, add:_

        //- Map dimensioned fields
        template<class Type>
        static tmp<DimensionedField<Type, volMesh> >
        interpolate
        (
            const DimensionedField<Type, volMesh>&,
            const fvMesh& sMesh,
            const labelList& cellMap
        );
        
        template<class Type>
        tmp<DimensionedField<Type, volMesh> >
        interpolate
        (
            const DimensionedField<Type, volMesh>&
        ) const;
        
    **src/finiteVolume/fvMesh/fvMeshSubset/fvMeshSubsetInterpolate.C**

    _line 38ish, add:_

        template<class Type>
        tmp<DimensionedField<Type, volMesh> > fvMeshSubset::interpolate
        (
            const DimensionedField<Type, volMesh>& df,
            const fvMesh& sMesh,
            const labelList& cellMap
        )
        {
            // Create and map the internal-field values
            Field<Type> internalField(df, cellMap);

            // Create the complete field from the pieces
            tmp<DimensionedField<Type, volMesh> > tresF
            (
                new DimensionedField<Type, volMesh>
                (
                    IOobject
                    (
                        "subset"+df.name(),
                        sMesh.time().timeName(),
                        sMesh,
                        IOobject::NO_READ,
                        IOobject::NO_WRITE
                    ),
                    sMesh,
                    df.dimensions(),
                    internalField
                )
            );

            return tresF;
        }


        template<class Type>
        tmp<DimensionedField<Type, volMesh> > fvMeshSubset::interpolate
        (
            const DimensionedField<Type, volMesh>& df
        ) const
        {
            return interpolate
            (
                df,
                subMesh(),
                cellMap()
            );
        }
  
3. Update the field mapping in fvMeshAdder
  
    **src/dynamicMesh/fvMeshAdder/fvMeshAdder.H**

    _in the private functions, add:_

        //- Update single dimensioned Field.
        template<class Type>
        static void MapDimField
        (
            const mapAddedPolyMesh& meshMap,

            DimensionedField<Type, volMesh>& fld,
            const DimensionedField<Type, volMesh>& fldToAdd
        );

    _in the public functions, add:_

        //- Map all dimensionedFields of Type
        template<class Type>
        static void MapDimFields
        (
            const mapAddedPolyMesh&,
            const fvMesh& mesh,
            const fvMesh& meshToAdd
        );

    **src/dynamicMesh/fvMeshAdder/fvMeshAdderTemplates.C**

    _anywhere in the member functions section, add:_

        template<class Type>
        void Foam::fvMeshAdder::MapDimField
        (
            const mapAddedPolyMesh& meshMap,

            DimensionedField<Type, volMesh>& fld,
            const DimensionedField<Type, volMesh>& fldToAdd
        )
        {
            const fvMesh& mesh = fld.mesh();

            // Internal field
            // ~~~~~~~~~~~~~~

            {
                // Store old internal field
                Field<Type> oldInternalField(fld);

                // Modify internal field
                Field<Type>& intFld = fld;

                intFld.setSize(mesh.nCells());

                intFld.rmap(oldInternalField, meshMap.oldCellMap());
                intFld.rmap(fldToAdd, meshMap.addedCellMap());
            }
        }


        template<class Type>
        void Foam::fvMeshAdder::MapDimFields
        (
            const mapAddedPolyMesh& meshMap,
            const fvMesh& mesh,
            const fvMesh& meshToAdd
        )
        {
            // This is a fix for the fact that the lookupClass function
            // now returns all the internal fields of GeometricFields when
            // called for a DimensionedField, but the typeName approach
            // differentiates between them.
            
            const wordList dimFieldNames
            (
                mesh.names(DimensionedField<Type, volMesh>::typeName)
            );
            
            const wordList dimFieldNamesToAdd
            (
                meshToAdd.names(DimensionedField<Type, volMesh>::typeName)
            );
            
            
            HashTable<const DimensionedField<Type, volMesh>&> fields
            (
                dimFieldNames.size()
            );
            
            HashTable<const DimensionedField<Type, volMesh>&> fieldsToAdd
            (
                dimFieldNamesToAdd.size()
            );
            
            forAll(dimFieldNames, i)
            {
                fields.insert
                (
                    dimFieldNames[i],
                    mesh.lookupObject<DimensionedField<Type, volMesh> >
                    (
                        dimFieldNames[i]
                    )
                );
            }
            
            forAll(dimFieldNamesToAdd, i)
            {
                fieldsToAdd.insert
                (
                    dimFieldNamesToAdd[i],
                    meshToAdd.lookupObject<DimensionedField<Type, volMesh> >
                    (
                        dimFieldNamesToAdd[i]
                    )
                );
            }

            for
            (
                typename HashTable<const DimensionedField<Type, volMesh>&>::
                    iterator fieldIter = fields.begin();
                fieldIter != fields.end();
                ++fieldIter
            )
            {
                DimensionedField<Type, volMesh>& fld =
                    const_cast<DimensionedField<Type, volMesh>&>
                    (
                        fieldIter()
                    );

                if (fieldsToAdd.found(fld.name()))
                {
                    const DimensionedField<Type, volMesh>& fldToAdd =
                        fieldsToAdd[fld.name()];

                    MapDimField<Type>(meshMap, fld, fldToAdd);
                }
                else
                {
                    WarningIn("fvMeshAdder::MapDimFields(..)")
                        << "Not mapping field " << fld.name()
                        << " since not present on mesh to add"
                        << endl;
                }
            }
        }

    **src/dynamicMesh/fvMeshAdder/fvMeshAdder.C**

    _line 104ish, in the `add` function, add:_

        fvMeshAdder::MapDimFields<scalar>(mapPtr, mesh0, mesh1);
        fvMeshAdder::MapDimFields<vector>(mapPtr, mesh0, mesh1);
        fvMeshAdder::MapDimFields<sphericalTensor>(mapPtr, mesh0, mesh1);
        fvMeshAdder::MapDimFields<symmTensor>(mapPtr, mesh0, mesh1);
        fvMeshAdder::MapDimFields<tensor>(mapPtr, mesh0, mesh1);
        
4. Add in the actual distribution if the different types of
     DimensionedFields in fvMeshDistribute.
     
    **src/dynamicMesh/fvMeshDistribute/fvMeshDistribute.C**
            
    _line 1527ish, add:_
        
        const wordList dimScalarFields
        (
            mesh_.names(DimensionedField<scalar, volMesh>::typeName)
        );
        checkEqualWordList("dimScalarFields", dimScalarFields);
        
        const wordList dimVectorFields
        (
            mesh_.names(DimensionedField<vector, volMesh>::typeName)
        );
        checkEqualWordList("dimVectorFields", dimVectorFields);
        
        const wordList dimSphericalTensorFields
        (
            mesh_.names(DimensionedField<sphericalTensor, volMesh>::typeName)
        );
        checkEqualWordList("dimSphericalTensorFields", dimSphericalTensorFields);
        
        const wordList dimSymmTensorFields
        (
            mesh_.names(DimensionedField<symmTensor, volMesh>::typeName)
        );
        checkEqualWordList("dimSymmTensorFields", dimSymmTensorFields);
        
        const wordList dimTensorFields
        (
            mesh_.names(DimensionedField<tensor, volMesh>::typeName)
        );
        checkEqualWordList("dimTensorFields", dimTensorFields);
        
        
        
    _line 1790ish (immediately after the sendFields<surfaceTensorField>, add:_
        
        sendFields<DimensionedField<scalar,volMesh> >
        (
            recvProc,
            dimScalarFields,
            subsetter,
            str
        );
        sendFields<DimensionedField<vector,volMesh> >
        (
            recvProc,
            dimVectorFields,
            subsetter,
            str
        );
        sendFields<DimensionedField<sphericalTensor,volMesh> >
        (
            recvProc,
            dimSphericalTensorFields,
            subsetter,
            str
        );
        sendFields<DimensionedField<symmTensor,volMesh> >
        (
            recvProc,
            dimSymmTensorFields,
            subsetter,
            str
        );
        sendFields<DimensionedField<tensor,volMesh> >
        (
            recvProc,
            dimTensorFields,
            subsetter,
            str
        );
        
    _line 1970ish (after the PtrList<surfaceTensorField> line), add:_

        PtrList<DimensionedField<scalar,volMesh> > isf;
        PtrList<DimensionedField<vector,volMesh> > ivf;
        PtrList<DimensionedField<sphericalTensor,volMesh> > istf;
        PtrList<DimensionedField<symmTensor,volMesh> > isytf;
        PtrList<DimensionedField<tensor,volMesh> > itf;
        
    _line 2080ish (after the receiveFields<surfaceTensorField> call), add:_

        receiveFields<DimensionedField<scalar,volMesh> >
        (
            sendProc,
            dimScalarFields,
            domainMesh,
            isf,
            fieldDicts.subDict(DimensionedField<scalar,volMesh>::typeName)
        );
        receiveFields<DimensionedField<vector,volMesh> >
        (
            sendProc,
            dimVectorFields,
            domainMesh,
            ivf,
            fieldDicts.subDict(DimensionedField<vector,volMesh>::typeName)
        );
        receiveFields<DimensionedField<sphericalTensor,volMesh> >
        (
            sendProc,
            dimSphericalTensorFields,
            domainMesh,
            istf,
            fieldDicts.subDict(DimensionedField<sphericalTensor,volMesh>::typeName)
        );
        receiveFields<DimensionedField<symmTensor,volMesh> >
        (
            sendProc,
            dimSymmTensorFields,
            domainMesh,
            isytf,
            fieldDicts.subDict(DimensionedField<symmTensor,volMesh>::typeName)
        );
        receiveFields<DimensionedField<tensor,volMesh> >
        (
            sendProc,
            dimTensorFields,
            domainMesh,
            itf,
            fieldDicts.subDict(DimensionedField<tensor,volMesh>::typeName)
        );
  1. [ CRASH ] When using viscosity models other than Newtonian in multiphase systems, each model creates a field named "nu" which conflict with each other when re-balancing the mesh. To fix it, for example in BirdCarreau.C, change "nu" on line 79 to "BirdCarreauNu."+name so the field has a unique name. A similar modification can be made for the other viscosity models if needed.

meshbalancing's People

Contributors

tgvoskuilen avatar

Watchers

James Cloos avatar Abhishek Verma avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.