View Issue Details

IDProjectCategoryView StatusLast Update
0001765OpenFOAMBugpublic2015-06-26 21:43
ReporterDanielJ Assigned Tohenry  
PrioritynormalSeverityfeatureReproducibilityN/A
Status closedResolutionno change required 
PlatformGNU/LinuxOSUbuntuOS Version14.10
Summary0001765: Additional options for dynamicRefineFvMesh
DescriptionDynamicRefineFvMesh would be easier to use with following options:
 - normalisation - define refinement threshold relative to minimum and maximum values of the refined field
 - gradient based refinemet - refine based on gradient of the field and not the value - useful for shock waves
 - refinement based on magnitude of vector field


I attached patch with modifications providing this functionality with backward compatibility of the configuration files. I also attached the modified source code and 'forwardStep' test case for sonicDyMFoam.
TagsNo tags attached.

Activities

DanielJ

2015-06-26 15:55

reporter  

dynamicRefineFvMesh-normalisation-and-gradient.patch (4,502 bytes)   
From e27c691fd295f994b6bfb5adbd790db3519ae09d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20Jasi=C5=84ski?= <daniel.jasinski@gmail.com>
Date: Fri, 26 Jun 2015 16:52:13 +0200
Subject: [PATCH] dynamicRefineFvMesh: normalisation and gradient

---
 .../dynamicRefineFvMesh/dynamicRefineFvMesh.C      | 63 ++++++++++++++++++++--
 .../dynamicRefineFvMesh/dynamicRefineFvMesh.H      |  4 ++
 2 files changed, 64 insertions(+), 3 deletions(-)
 mode change 100644 => 100755 src/dynamicFvMesh/dynamicRefineFvMesh/dynamicRefineFvMesh.C
 mode change 100644 => 100755 src/dynamicFvMesh/dynamicRefineFvMesh/dynamicRefineFvMesh.H

diff --git a/src/dynamicFvMesh/dynamicRefineFvMesh/dynamicRefineFvMesh.C b/src/dynamicFvMesh/dynamicRefineFvMesh/dynamicRefineFvMesh.C
old mode 100644
new mode 100755
index fc8fcce..20130fe
--- a/src/dynamicFvMesh/dynamicRefineFvMesh/dynamicRefineFvMesh.C
+++ b/src/dynamicFvMesh/dynamicRefineFvMesh/dynamicRefineFvMesh.C
@@ -33,6 +33,7 @@ License
 #include "pointFields.H"
 #include "sigFpe.H"
 #include "cellSet.H"
+#include "fvcGrad.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -1265,8 +1266,64 @@ bool Foam::dynamicRefineFvMesh::update()
         }
 
         const word fieldName(refineDict.lookup("field"));
+        const word base
+        (
+            refineDict.lookupOrDefault<word>("refinementBase","value")
+        );
+        const bool normalised(refineDict.lookupOrDefault("normalised",false));
+
+        tmp<volScalarField> tFld;
+
+        if(foundObject<volScalarField>(fieldName))
+        {
+            tFld = tmp<volScalarField>
+                   (
+                       new volScalarField
+                       (
+                           lookupObject<volScalarField>(fieldName)
+                       )
+                   );
+        }
+        else if(foundObject<volVectorField>(fieldName))
+        {
+            tFld = mag(lookupObject<volVectorField>(fieldName));
+        }
+        else
+        {
+            FatalErrorIn("dynamicRefineFvMesh::update()")
+                << "Field " << fieldName <<" does not exist."<< nl
+                << exit(FatalError);
+        }
+
+        if(base == "gradient")
+        {
+            tFld = mag(fvc::grad(tFld()));
+        }
+        else if(base != "value")
+        {
+            FatalErrorIn("dynamicRefineFvMesh::update()")
+                << "Illegal refinement base: " << base << nl
+                << "Valid options are: value, gradient." << nl
+                << exit(FatalError);
+        }
+
+        if(normalised)
+        {
+            dimensionedScalar fieldMin(min(tFld()));
+            dimensionedScalar fieldMax(max(tFld()));
 
-        const volScalarField& vFld = lookupObject<volScalarField>(fieldName);
+            scalar scale = fieldMax.value() - fieldMin.value();
+
+            // Normalise to near zero on constant fields
+            if(scale < VSMALL)
+            {
+                tFld().internalField() = 0.0;
+            }
+            else
+            {
+                tFld = (tFld() - fieldMin)/scale;
+            }
+        }
 
         const scalar lowerRefineLevel =
             readScalar(refineDict.lookup("lowerRefineLevel"));
@@ -1288,7 +1345,7 @@ bool Foam::dynamicRefineFvMesh::update()
         (
             lowerRefineLevel,
             upperRefineLevel,
-            vFld,
+            tFld(),
             refineCell
         );
 
@@ -1364,7 +1421,7 @@ bool Foam::dynamicRefineFvMesh::update()
                 (
                     unrefineLevel,
                     refineCell,
-                    maxCellField(vFld)
+                    maxCellField(tFld())
                 )
             );
 
diff --git a/src/dynamicFvMesh/dynamicRefineFvMesh/dynamicRefineFvMesh.H b/src/dynamicFvMesh/dynamicRefineFvMesh/dynamicRefineFvMesh.H
old mode 100644
new mode 100755
index fc4db3b..7bee598
--- a/src/dynamicFvMesh/dynamicRefineFvMesh/dynamicRefineFvMesh.H
+++ b/src/dynamicFvMesh/dynamicRefineFvMesh/dynamicRefineFvMesh.H
@@ -34,6 +34,10 @@ Description
         refineInterval  1;
         // Field to be refinement on
         field           alpha.water;
+        // Use value or gradient of the field (default=value)
+        refinementBase gradient;
+        // Normalise by extreme velues in the domain (default=false)
+        normalised true;
         // Refine field inbetween lower..upper
         lowerRefineLevel 0.001;
         upperRefineLevel 0.999;
-- 
1.9.1

DanielJ

2015-06-26 15:56

reporter  

sonicDyMFoam-test.zip (214,193 bytes)

DanielJ

2015-06-26 15:56

reporter  

DanielJ

2015-06-26 16:04

reporter   ~0005007

Just realised that I forgot to retrieve min and max value from entire domain, not just current processor.

user4

2015-06-26 16:06

 

magGradMach (2,176 bytes)   
/*--------------------------------*- C++ -*----------------------------------*\
| =========                 |                                                 |
| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
|  \\    /   O peration     | Version:  dev                                   |
|   \\  /    A nd           | Web:      www.OpenFOAM.org                      |
|    \\/     M anipulation  |                                                 |
\*---------------------------------------------------------------------------*/
FoamFile
{
    version     2.0;
    format      ascii;
    class       dictionary;
    location    "system";
    object      controlDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

indicator
{
    // Load the library containing the 'coded' functionObject
    functionObjectLibs ("libutilityFunctionObjects.so");
    type coded;
    // Name of on-the-fly generated functionObject
    redirectType indicatorField;
    code
    #{
        if (!mesh().foundObject<volScalarField>("magGradMach"))
        {
            // Lookup alpha
            Info<< "Looking up field Mach\n" << endl;
            const volScalarField& Mach =
                mesh().lookupObject<volScalarField>("Mach");

            Info<< "Creating and storing field magGradMach\n" << endl;
            tmp<volScalarField> tmagGradMach(mag(fvc::grad(Mach)));
            volScalarField& magGradMach = tmagGradMach();

            magGradMach.rename("magGradMach");
            magGradMach.writeOpt() = IOobject::AUTO_WRITE;
            magGradMach.writeMinMax(Info);

            tmagGradMach.ptr()->store();

        }

        Info<< "Looking up field magGradMach\n" << endl;
        volScalarField& magGradMach = const_cast<volScalarField&>
        (
            mesh().lookupObject<volScalarField>("magGradMach")
        );

        Info<< "Looking up field Mach\n" << endl;
        const volScalarField& Mach =
            mesh().lookupObject<volScalarField>("Mach");

        magGradMach = mag(fvc::grad(Mach));
    #};
}

// ************************************************************************* //
magGradMach (2,176 bytes)   

user4

2015-06-26 16:08

  ~0005008

The same (and more) can be done with the 'coded' functionObject framework. I've uploaded an example that calculates a field called "magGradMach". This can now be used to drive refinement - dynamicRefineFvMesh can operate on any registered field.

henry

2015-06-26 16:16

manager   ~0005009

> - gradient based refinemet - refine based on gradient of the field and not the value

The field used for refinement could be a gradient so why is there a need for a special option?

I agree with Mattijs; we want to avoid a proliferation a specialised options and concentrate on general and flexible functionality.

DanielJ

2015-06-26 16:28

reporter   ~0005010

This are basic and very useful options and would be nice if were available without writing code.

Usually only pressure gradient can be accessed directly for refinement.

henry

2015-06-26 16:34

manager   ~0005011

You can cache any gradients that are calculated in the code and calculate any others using functionObjects.

henry

2015-06-26 21:43

manager   ~0005012

I don't think that hard-coding this specific functionality into the dynamicRefineFvMesh class is a good idea. If we were to code all usage options on if-statements in this manner the code would quickly become unmanagable and unmaintainable.

If you are not happy with Mattijs' 'coded' functionObject suggestion you could create a functionObject which includes the functionality you inserted directly in dynamicRefineFvMesh and generates the field to control refinement. This way other options can be coded and maintained independently of dynamicRefineFvMesh and selected at run-time.

Issue History

Date Modified Username Field Change
2015-06-26 15:55 DanielJ New Issue
2015-06-26 15:55 DanielJ File Added: dynamicRefineFvMesh-normalisation-and-gradient.patch
2015-06-26 15:56 DanielJ File Added: sonicDyMFoam-test.zip
2015-06-26 15:56 DanielJ File Added: dynamicRefineFvMesh-code.zip
2015-06-26 16:04 DanielJ Note Added: 0005007
2015-06-26 16:06 user4 File Added: magGradMach
2015-06-26 16:08 user4 Note Added: 0005008
2015-06-26 16:16 henry Note Added: 0005009
2015-06-26 16:28 DanielJ Note Added: 0005010
2015-06-26 16:34 henry Note Added: 0005011
2015-06-26 21:43 henry Note Added: 0005012
2015-06-26 21:43 henry Status new => closed
2015-06-26 21:43 henry Assigned To => henry
2015-06-26 21:43 henry Resolution open => no change required