├── .gitignore ├── Make ├── files └── options ├── .vscode ├── settings.json ├── tasks.json └── c_cpp_properties.json ├── .gitlab-ci.yml ├── README.md ├── convergenceDetectionDict ├── convergenceDetection.H ├── convergenceDetection.C └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | InInclde* 2 | Make/linux64GccDPInt32Opt/* 3 | -------------------------------------------------------------------------------- /Make/files: -------------------------------------------------------------------------------- 1 | convergenceDetection.C 2 | 3 | LIB = $(FOAM_USER_LIBBIN)/libconvergenceDetection 4 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "*Dict": "OpenFOAM", 4 | "*Properties": "OpenFOAM", 5 | "fvSchemes": "OpenFOAM", 6 | "fvSolution": "OpenFOAM", 7 | "**/constant/g": "OpenFOAM", 8 | "**/0/*": "OpenFOAM", 9 | "averaging": "OpenFOAM", 10 | "convergenceDetection.C": "cpp", 11 | "convergenceDetection.H": "cpp" 12 | } 13 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "type": "shell", 6 | "label": "wmake-build", 7 | "command": "wmake -j", 8 | "problemMatcher": [ 9 | "$gcc" 10 | ], 11 | "group": { 12 | "kind": "build", 13 | "isDefault": true 14 | } 15 | } 16 | ] 17 | } -------------------------------------------------------------------------------- /Make/options: -------------------------------------------------------------------------------- 1 | EXE_INC = \ 2 | -I$(LIB_SRC)/finiteVolume/lnInclude \ 3 | -I$(LIB_SRC)/meshTools/lnInclude \ 4 | -I$(LIB_SRC)/functionObjects/forces/lnInclude \ 5 | -I$(LIB_SRC)/functionObjects/field/lnInclude \ 6 | -I$(LIB_SRC)/surfMesh/lnInclude \ 7 | -I$(LIB_SRC)/sampling/lnInclude 8 | 9 | LIB_LIBS = \ 10 | -lfiniteVolume \ 11 | -lmeshTools \ 12 | -lforces \ 13 | -lfieldFunctionObjects \ 14 | -lsurfMesh \ 15 | -lsampling 16 | -------------------------------------------------------------------------------- /.vscode/c_cpp_properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [ 3 | { 4 | "name": "Linux", 5 | "includePath": [ 6 | "${workspaceFolder}/**", 7 | "/usr/lib/openfoam/openfoam2206/src/**" 8 | ], 9 | "defines": [], 10 | "compilerPath": "/usr/bin/gcc", 11 | "cStandard": "gnu11", 12 | "cppStandard": "gnu++14", 13 | "intelliSenseMode": "gcc-x86" 14 | } 15 | ], 16 | "version": 4 17 | } -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | image: "google/cloud-sdk:alpine" 2 | 3 | stages: 4 | - upload 5 | 6 | before_script: 7 | - echo "$GOOGLE_SERVICE_ACCOUNT" >> "/root/google.json" 8 | 9 | upload_zip: 10 | stage: upload 11 | script: 12 | - git archive -o ${CI_PROJECT_NAME}-${CI_COMMIT_REF_NAME}.zip -9 HEAD 13 | - gcloud auth activate-service-account --project=halogen-chemist-162620 --key-file=/root/google.json 14 | - gsutil -h Cache-Control:private cp ./${CI_PROJECT_NAME}-${CI_COMMIT_REF_NAME}.zip gs://airshaper-releases 15 | except: 16 | - /^feature\/.*$/ 17 | tags: 18 | - feature 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Openfoam.com convergence detection 2 | 3 | ## Motivation 4 | 5 | Why we think this is better when runTimeControl in openfoam and residuals 6 | 7 | ## How it works 8 | 9 | This functionObject runs every iteration, it pulls force data and it stores the total force which is later used for the gradient calculation. 10 | 11 | ## Parameters explanation 12 | 13 | ### windowNormalization 0.5; 14 | 15 | ### windowGradient 0.5; 16 | 17 | ### windowGradientAveraging 0.99; 18 | 19 | ### windowEvaluation 0.333; 20 | 21 | ### windowEvaluationAveraging 0.333; 22 | 23 | ### thresholdConvergence 0.075; 24 | 25 | ### thresholdAveraging 0.025; 26 | 27 | ### iterationMaxConvergence 4000; 28 | 29 | If simulation does not converge start forced averging at 4000 iterations 30 | 31 | ### iterationMaxAveraging 2000; 32 | 33 | If simulation does not converge within 4000 iterations run 2000 averaging iterations so in total simulation will have 6000 iterations 34 | 35 | ### iterationMinConvergence 200; 36 | 37 | Minimum number of iterations in case simulation converges before 200 iterations 38 | 39 | ### iterationMinAveraging 200; 40 | 41 | Minimum number of averaging iterations in case simulation converges at iterationMinConvergence 42 | 43 | ### forceStabilityFactor 2; 44 | 45 | In case forces explode this factor is used to check if forces are 2 times higher or lower when the converged value and in case of that it stops the simulation. If this happens it means your mesh is not good enough. 46 | 47 | ## Credits 48 | 49 | Original Python implementation by João Miranda 50 | 51 | OpenFoam C++ Implementation by Nikola Majksner 52 | -------------------------------------------------------------------------------- /convergenceDetectionDict: -------------------------------------------------------------------------------- 1 | convergenceDetection1 2 | { 3 | libs (libconvergenceDetection); 4 | type convergenceDetection; 5 | 6 | // default settings 7 | // windowNormalization 0.5; 8 | // windowGradient 0.5; 9 | // windowGradientAveraging 0.99; 10 | // windowEvaluation 0.333; 11 | // windowEvaluationAveraging 0.333; 12 | // thresholdConvergence 0.075; 13 | // thresholdAveraging 0.025; 14 | // iterationMaxConvergence 4000; 15 | // iterationMaxAveraging 2000; 16 | // iterationMinConvergence 200; 17 | // iterationMinAveraging 200; 18 | // convergenceStabilityFactor 2; 19 | 20 | rotation_forces { 21 | forces_rotation_local_CS_o-1_m-1 22 | { 23 | 24 | type forces; 25 | libs ("libforces.so"); //Lib to load 26 | patches (rotating_o-1_m-1); // change to your patch name 27 | writeControl outputTime; 28 | writeToFile false; 29 | pName p; 30 | UName U; 31 | rho rhoInf; // Indicates incompressible 32 | log yes; 33 | rhoInf 1.225; //Reference density for fluid 34 | origin (5.7195773108383204e-05 0.00048790520819794116 -7.06637150485188e-09); 35 | rotation 36 | { 37 | type axes; 38 | e1 (0.018186134589979835 0.0012717031291784764 -1.3326080284815782e-09); 39 | e2 (1.2717044617865047e-13 -1.334426641940576e-09 -0.001271703127359863); 40 | e3 (-1.6172288464513707e-06 2.3127364232664738e-05 -2.4268224233840492e-11); 41 | } 42 | } 43 | } 44 | 45 | // forces - required 46 | // modify according to your case 47 | patches ( #CHANGEME# ); 48 | rho rhoInf; 49 | log false; 50 | rhoInf 1.225; // for water 1000 51 | CofR ( 0 0 0 ); 52 | // end of forces - required 53 | 54 | writeControl timeStep; 55 | timeInterval 1; 56 | log true; 57 | } -------------------------------------------------------------------------------- /convergenceDetection.H: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------*\ 2 | ========= | 3 | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox 4 | \\ / O peration | 5 | \\ / A nd | www.openfoam.com 6 | \\/ M anipulation | 7 | ------------------------------------------------------------------------------- 8 | Copyright (C) 2022 Nikola Majksner, Wouter Remmerie, AirShaper 9 | ------------------------------------------------------------------------------- 10 | License 11 | This file is part of OpenFOAM. 12 | 13 | OpenFOAM is free software: you can redistribute it and/or modify it 14 | under the terms of the GNU General Public License as published by 15 | the Free Software Foundation, either version 3 of the License, or 16 | (at your option) any later version. 17 | 18 | OpenFOAM is distributed in the hope that it will be useful, but WITHOUT 19 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 20 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 21 | for more details. 22 | 23 | You should have received a copy of the GNU General Public License 24 | along with OpenFOAM. If not, see . 25 | 26 | Class 27 | Foam::functionObjects::convergenceDetection 28 | 29 | Group 30 | grpFieldFunctionObjects 31 | 32 | Description 33 | 34 | 35 | 36 | \f[ 37 | x = x_{ref}^x + \rho \omega 38 | \f] 39 | 40 | 41 | where 42 | \vartable 43 | \rho | [units, e.g. kg/m3] 44 | \omega | \f$ \nabla \cdot \vec U \f$ 45 | ... | ... 46 | \endvartable 47 | 48 | 49 | where \f$ x_k \f$ is ... 50 | 51 | 52 | \table 53 | Operand | Type | Location 54 | input | {vol,surface}\Field(s) |$FOAM_CASE/\/\s 56 | output file | dat | $FOAM_CASE/postProcessing/\/\/\ 58 | output field | volScalarField | $FOAM_CASE/\/\ 59 | \endtable 60 | 61 | Usage 62 | Minimal example by using \c system/controlDict.functions: 63 | \verbatim 64 | convergenceDetection1 65 | { 66 | // Mandatory entries (unmodifiable) 67 | type convergenceDetection; 68 | libs (convergenceDetectionFunctionObject); 69 | 70 | // Mandatory entries (runtime modifiable) 71 | ... 72 | 73 | // Mandatory (inherited) entries (unmodifiable) 74 | ... 75 | 76 | // Mandatory (inherited) entries (runtime unmodifiable) 77 | ... 78 | 79 | // Optional entries (unmodifiable) 80 | ... 81 | 82 | // Optional entries (runtime modifiable) 83 | boolData ; 84 | labelData