diff --git a/.cirrus.yml b/.cirrus.yml new file mode 100644 index 0000000..8fd597a --- /dev/null +++ b/.cirrus.yml @@ -0,0 +1,33 @@ +latest_task: + container: + image: opencfd/openfoam-dev:latest + cpu: 4 + memory: 10G + test_script: + - apt-get update + - apt-get install -y python3 python-is-python3 + - /usr/bin/openfoam ./Allwmake -j +v2206_task: + container: + image: opencfd/openfoam-dev:2206 + cpu: 1 + test_script: + - apt-get update + - apt-get install -y python3 python-is-python3 + - /usr/bin/openfoam ./Allwmake +v2112_task: + container: + cpu: 1 + image: opencfd/openfoam-dev:2112 + test_script: + - apt-get update + - apt-get install -y python3 python-is-python3 + - /usr/bin/openfoam ./Allwmake +v2106_task: + container: + cpu: 1 + image: opencfd/openfoam-dev:2106 + test_script: + - apt-get update + - apt-get install -y python3 python-is-python3 + - /usr/bin/openfoam ./Allwmake diff --git a/AUTHORS.md b/AUTHORS.md new file mode 100644 index 0000000..242e52b --- /dev/null +++ b/AUTHORS.md @@ -0,0 +1,3 @@ +* Timofey Mukha is the main developer of the library and the current maintainer +* Saleh Rezaeiravesh contributed code during the initial development phase in 2017 +* Jan Gärtner contributed a patch that enables using compressible solvers in 2021 \ No newline at end of file diff --git a/Allwmake b/Allwmake index 3156172..2603e17 100755 --- a/Allwmake +++ b/Allwmake @@ -1,4 +1,5 @@ #! /bin/bash +. "${WM_PROJECT_DIR:?}"/wmake/scripts/AllwmakeParseArguments echo "Current OpenFOAM version is $WM_PROJECT_VERSION." if [ -e foamVersionThisIsCompiledFor ]; then diff --git a/CHANGELOG.md b/CHANGELOG.md index 2002825..5a2e1ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,41 @@ # CHANGELOG +## v0.7.0 + +### For users +- The main repository is now on Github. Use Github issues instead of Bitbucket to get help! + +- The library works with up to release v2212 from OpenCFD. + +- Ambition to support Foundation version is dropped. Pull requests are much welcome though. + +- The field for the sampling distance height is now called `hSampler` to avoid name collisions with enthalpy. + However, if `hSampler` is not found, `h` will be picked up. + +- It is now possible to use the library with compressible solvers. + +- Intracell interpolation should work properly now. + +- New parameter "silent", which suppresses time consumption output. + +- Messages like "Sampling field ... for patch ..." are now only printed in debug mode. + Use `DebugSwitches` in the `controlDict` to enable debug. + +- A new law of the wall is added, the `RoughLogLaw`, suitable for rough surfaces. + +- As a beta release, multi-cell sampling is implemented. + No simulations have been run using it as of yet. + +- The online documentation is improved. + +### For developers +- The SampledField classes now have `TypeName`. + +- 'excludeWallAdjacent' is now in the base Sampler class. + +- Slightly different methods to get the viscosity internal field and patch field in the base wall model class (to accommodate compressible solvers). + + ## v0.6.1 ### For users diff --git a/Make/files b/Make/files index 0d23cac..e87f3f7 100644 --- a/Make/files +++ b/Make/files @@ -19,12 +19,14 @@ lawsOfTheWall/WernerWengleLawOfTheWall/WernerWengleLawOfTheWall.C lawsOfTheWall/IntegratedWernerWengleLawOfTheWall/IntegratedWernerWengleLawOfTheWall.C lawsOfTheWall/IntegratedReichardtLawOfTheWall/IntegratedReichardtLawOfTheWall.C lawsOfTheWall/ReichardtLawOfTheWall/ReichardtLawOfTheWall.C +lawsOfTheWall/RoughLogLawOfTheWall/RoughLogLawOfTheWall.C eddyViscosities/EddyViscosity/EddyViscosity.C eddyViscosities/VanDriest/VanDriestEddyViscosity.C eddyViscosities/Duprat/DupratEddyViscosity.C wallModels/wallModelFvPatchScalarField.C wallModels/KnownWallShearStressWallModelFvPatchScalarField.C wallModels/LOTWWallModelFvPatchScalarField.C +wallModels/MulticellLOTWWallModelFvPatchScalarField.C wallModels/EquilibriumODEWallModelFvPatchScalarField.C wallModels/ODEWallModelFvPatchScalarField.C wallModels/PGradODEWallModelFvPatchScalarField.C diff --git a/README.md b/README.md index f32f206..52d66c6 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,9 @@ # README # -libWallModelledLES is a library based on OpenFOAM® technology, extending the capabilities of OpenFOAM in the area of -wall-modelled LES (WMLES). -This is a turbulence modelling methodology, which allows to make LES cheaper by not resolving the inner region of -turbulent boundary layers. +libWallModelledLES is a library based on OpenFOAM® technology, extending the capabilities of OpenFOAM in the area of wall-modelled LES (WMLES). +This is a turbulence modelling methodology, which allows to make LES cheaper by not resolving the inner region of turbulent boundary layers. -If you use the library, please cite the following publication. This is also a good source for understanding the theory -behind the models. +If you use the library, please cite the following publication. This is also a good source for understanding the theory behind the models. https://doi.org/10.1016/j.cpc.2019.01.016 @@ -14,6 +11,7 @@ https://doi.org/10.1016/j.cpc.2019.01.016 ## News ## +- **2023-04-25** Development moves to [Github](https://github.com/timofeymukha/libWallModelledLES/), Bitbucket remains as a mirror. - **2023-01-05** Version 0.6.1 released. - **2021-08-30** Version 0.6.0 released. - **2019-10-28** Version 0.5.1 released. @@ -26,22 +24,23 @@ https://doi.org/10.1016/j.cpc.2019.01.016 ## Compatibility ## -See "Installation" section on the documentation portal. In short: the latest ESI and Foundation releases should work. +See "Installation" section on the documentation portal. In short: the latest ESI versions should work, Foundation version 7 and below should work. ## Getting help -Please open [an issue on Bitbucket](https://bitbucket.org/lesituu/libwallmodelledles/issues?status=new&status=open)! +Please first read the troubleshooting section in the documentation. +If that does not help, please open [an issue on Github](https://github.com/timofeymukha/libWallModelledLES/issues)! ## Where this code lives This code is available on several public repositories: -- [Bitbucket](https://bitbucket.org/lesituu/libwallmodelledles/) --- the main repository, where all the development happens, and where you should open issues to get help. +- [Github](https://github.com/timofeymukha/libWallModelledLES) --- the main repository, where all the development happens, and where you should open issues to get help. +- [Bitbucket](https://bitbucket.org/lesituu/libwallmodelledles/) --- mirror, which only gets update upon new releases. + - [Gitlab](https://gitlab.com/chalmers-marine-technology/libwallmodelledles) --- mirror, which only gets updated upon new releases. -- [Github](https://github.com/timofeymukha/libWallModelledLES) --- mirror, which only gets updated upon releases. - - ## Published works using the library -If your works is missing from this glorious list and you want it here, [open an issue](https://bitbucket.org/lesituu/libwallmodelledles/issues?status=new&status=open)! + +If your works is missing from this glorious list and you want it here, [open an issue](https://github.com/timofeymukha/libWallModelledLES/issues)! - Mukha, T., Rezaeiravesh, S., & Liefvendahl, M. (2017). An OpenFOAM library for wall-modelled Large-Eddy Simulation. In proceedings of the 12th OpenFOAM Workshop, Exeter, UK. diff --git a/cellFinders/CellFinder/CellFinder.H b/cellFinders/CellFinder/CellFinder.H index 4a55528..aa6e5d2 100644 --- a/cellFinders/CellFinder/CellFinder.H +++ b/cellFinders/CellFinder/CellFinder.H @@ -19,7 +19,7 @@ License Class Foam::CellFinder -Description +@brief Class for searching for sampling cells. Contributors/Copyright: diff --git a/cellFinders/CrawlingCellFinder/CrawlingCellFinder.H b/cellFinders/CrawlingCellFinder/CrawlingCellFinder.H index e7861cf..85b10a5 100644 --- a/cellFinders/CrawlingCellFinder/CrawlingCellFinder.H +++ b/cellFinders/CrawlingCellFinder/CrawlingCellFinder.H @@ -19,7 +19,7 @@ License Class Foam::CrawlingCellFinder -Description +@brief Class for searching for sampling cells by crawling through opposite faces. Contributors/Copyright: diff --git a/cellFinders/TreeCellFinder/TreeCellFinder.C b/cellFinders/TreeCellFinder/TreeCellFinder.C index ec9b26c..c6e72de 100644 --- a/cellFinders/TreeCellFinder/TreeCellFinder.C +++ b/cellFinders/TreeCellFinder/TreeCellFinder.C @@ -512,8 +512,21 @@ Foam::TreeCellFinder::findCandidateCellLabels Foam::tmp Foam::TreeCellFinder::distanceField() const { + + word hName; + // Grab h for the current patch - const volScalarField & h = mesh_.lookupObject ("h"); + if (mesh_.foundObject("hSampler")) + { + hName = "hSampler"; + } + else + { + hName = "h"; + } + const volScalarField & h = mesh_.lookupObject(hName); + + if (debug) { Info<< "CellFinder: Creating dist field" << nl; diff --git a/cellFinders/TreeCellFinder/TreeCellFinder.H b/cellFinders/TreeCellFinder/TreeCellFinder.H index 235f34b..66b673e 100644 --- a/cellFinders/TreeCellFinder/TreeCellFinder.H +++ b/cellFinders/TreeCellFinder/TreeCellFinder.H @@ -19,7 +19,7 @@ License Class Foam::TreeCellFinder -Description +@brief Class for searching for sampling cells using. Contributors/Copyright: diff --git a/docs/.readthedocs.yaml b/docs/.readthedocs.yaml new file mode 100644 index 0000000..48248f7 --- /dev/null +++ b/docs/.readthedocs.yaml @@ -0,0 +1,9 @@ +version: 2 + +build: + os: "ubuntu-22.04" + tools: + python: miniconda3-4.7 + +conda: + environment: docs/environment.yaml diff --git a/docs/Doxyfile b/docs/Doxyfile index c42f17f..e37c0f4 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -1,4 +1,4 @@ -# Doxyfile 1.8.13 +# Doxyfile 1.9.7 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. @@ -12,16 +12,26 @@ # For lists, items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (\" \"). +# +# Note: +# +# Use doxygen to compare the used configuration file with the template +# configuration file: +# doxygen -x [configFile] +# Use doxygen to compare the used configuration file with the template +# configuration file without replacing the environment variables or CMake type +# replacement variables: +# doxygen -x_noenv [configFile] #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all text -# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv -# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv -# for the list of possible encodings. +# This tag specifies the encoding used for all characters in the configuration +# file that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# https://www.gnu.org/software/libiconv/ for the list of possible encodings. # The default value is: UTF-8. DOXYFILE_ENCODING = UTF-8 @@ -60,16 +70,28 @@ PROJECT_LOGO = OUTPUT_DIRECTORY = -# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- -# directories (in 2 levels) under the output directory of each output format and -# will distribute the generated files over these directories. Enabling this +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create up to 4096 +# sub-directories (in 2 levels) under the output directory of each output format +# and will distribute the generated files over these directories. Enabling this # option can be useful when feeding doxygen a huge amount of source files, where # putting all generated files in the same directory would otherwise causes -# performance problems for the file system. +# performance problems for the file system. Adapt CREATE_SUBDIRS_LEVEL to +# control the number of sub-directories. # The default value is: NO. CREATE_SUBDIRS = NO +# Controls the number of sub-directories that will be created when +# CREATE_SUBDIRS tag is set to YES. Level 0 represents 16 directories, and every +# level increment doubles the number of directories, resulting in 4096 +# directories at level 8 which is the default and also the maximum value. The +# sub-directories are organized in 2 levels, the first level always has a fixed +# number of 16 directories. +# Minimum value: 0, maximum value: 8, default value: 8. +# This tag requires that the tag CREATE_SUBDIRS is set to YES. + +CREATE_SUBDIRS_LEVEL = 8 + # If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII # characters to appear in the names of generated files. If set to NO, non-ASCII # characters will be escaped, for example _xE3_x81_x84 will be used for Unicode @@ -81,14 +103,14 @@ ALLOW_UNICODE_NAMES = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. -# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, -# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), -# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, -# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), -# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, -# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, -# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, -# Ukrainian and Vietnamese. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Bulgarian, +# Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, English +# (United States), Esperanto, Farsi (Persian), Finnish, French, German, Greek, +# Hindi, Hungarian, Indonesian, Italian, Japanese, Japanese-en (Japanese with +# English messages), Korean, Korean-en (Korean with English messages), Latvian, +# Lithuanian, Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, +# Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, +# Swedish, Turkish, Ukrainian and Vietnamese. # The default value is: English. OUTPUT_LANGUAGE = English @@ -179,6 +201,16 @@ SHORT_NAMES = YES JAVADOC_AUTOBRIEF = NO +# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line +# such as +# /*************** +# as being the beginning of a Javadoc-style comment "banner". If set to NO, the +# Javadoc-style will behave just like regular comments and it will not be +# interpreted by doxygen. +# The default value is: NO. + +JAVADOC_BANNER = NO + # If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first # line (until the first dot) of a Qt-style comment as the brief description. If # set to NO, the Qt-style will behave just like regular Qt-style comments (thus @@ -199,6 +231,14 @@ QT_AUTOBRIEF = NO MULTILINE_CPP_IS_BRIEF = NO +# By default Python docstrings are displayed as preformatted text and doxygen's +# special commands cannot be used. By setting PYTHON_DOCSTRING to NO the +# doxygen's special commands can be used and the contents of the docstring +# documentation blocks is shown as doxygen documentation. +# The default value is: YES. + +PYTHON_DOCSTRING = YES + # If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the # documentation from any documented member that it re-implements. # The default value is: YES. @@ -222,20 +262,19 @@ TAB_SIZE = 4 # the documentation. An alias has the form: # name=value # For example adding -# "sideeffect=@par Side Effects:\n" +# "sideeffect=@par Side Effects:^^" # will allow you to put the command \sideeffect (or @sideeffect) in the # documentation, which will result in a user-defined paragraph with heading -# "Side Effects:". You can put \n's in the value part of an alias to insert -# newlines. +# "Side Effects:". Note that you cannot put \n's in the value part of an alias +# to insert newlines (in the resulting output). You can put ^^ in the value part +# of an alias to insert a newline as if a physical newline was in the original +# file. When you need a literal { or } or , in the value part of an alias you +# have to escape them by means of a backslash (\), this can lead to conflicts +# with the commands \{ and \} for these it is advised to use the version @{ and +# @} or use a double escape (\\{ and \\}) ALIASES = -# This tag can be used to specify a number of word-keyword mappings (TCL only). -# A mapping has the form "name=value". For example adding "class=itcl::class" -# will allow you to use the command class in the itcl::class meaning. - -TCL_SUBST = - # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources # only. Doxygen will then generate output that is more tailored for C. For # instance, some of the names that are used will be different. The list of all @@ -264,28 +303,40 @@ OPTIMIZE_FOR_FORTRAN = NO OPTIMIZE_OUTPUT_VHDL = NO +# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice +# sources only. Doxygen will then generate output that is more tailored for that +# language. For instance, namespaces will be presented as modules, types will be +# separated into more groups, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_SLICE = NO + # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, and -# language is one of the parsers supported by doxygen: IDL, Java, Javascript, -# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: -# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: -# Fortran. In the later case the parser tries to guess whether the code is fixed -# or free formatted code, this is the default for Fortran type files), VHDL. For -# instance to make doxygen treat .inc files as Fortran files (default is PHP), -# and .f files as C (default is Fortran), use: inc=Fortran f=C. +# language is one of the parsers supported by doxygen: IDL, Java, JavaScript, +# Csharp (C#), C, C++, Lex, D, PHP, md (Markdown), Objective-C, Python, Slice, +# VHDL, Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: +# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser +# tries to guess whether the code is fixed or free formatted code, this is the +# default for Fortran type files). For instance to make doxygen treat .inc files +# as Fortran files (default is PHP), and .f files as C (default is Fortran), +# use: inc=Fortran f=C. # # Note: For files without extension you can use no_extension as a placeholder. # # Note that for custom extensions you also need to set FILE_PATTERNS otherwise -# the files are not read by doxygen. +# the files are not read by doxygen. When specifying no_extension you should add +# * to the FILE_PATTERNS. +# +# Note see also the list of default file extension mappings. EXTENSION_MAPPING = # If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments # according to the Markdown format, which allows for more readable -# documentation. See http://daringfireball.net/projects/markdown/ for details. +# documentation. See https://daringfireball.net/projects/markdown/ for details. # The output of markdown processing is further processed by doxygen, so you can # mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in # case of backward compatibilities issues. @@ -297,11 +348,22 @@ MARKDOWN_SUPPORT = NO # to that level are automatically included in the table of contents, even if # they do not have an id attribute. # Note: This feature currently applies only to Markdown headings. -# Minimum value: 0, maximum value: 99, default value: 0. +# Minimum value: 0, maximum value: 99, default value: 5. # This tag requires that the tag MARKDOWN_SUPPORT is set to YES. TOC_INCLUDE_HEADINGS = 0 +# The MARKDOWN_ID_STYLE tag can be used to specify the algorithm used to +# generate identifiers for the Markdown headings. Note: Every identifier is +# unique. +# Possible values are: DOXYGEN Use a fixed 'autotoc_md' string followed by a +# sequence number starting at 0. and GITHUB Use the lower case version of title +# with any whitespace replaced by '-' and punctations characters removed.. +# The default value is: DOXYGEN. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +MARKDOWN_ID_STYLE = DOXYGEN + # When enabled doxygen tries to link words that correspond to documented # classes, or namespaces to their corresponding documentation. Such a link can # be prevented in individual cases by putting a % sign in front of the word or @@ -327,7 +389,7 @@ BUILTIN_STL_SUPPORT = NO CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip (see: -# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen +# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen # will parse them like normal C++ but will assume all classes use public instead # of private inheritance when no explicit protection keyword is present. # The default value is: NO. @@ -413,6 +475,19 @@ TYPEDEF_HIDES_STRUCT = NO LOOKUP_CACHE_SIZE = 0 +# The NUM_PROC_THREADS specifies the number of threads doxygen is allowed to use +# during processing. When set to 0 doxygen will based this on the number of +# cores available in the system. You can set it explicitly to a value larger +# than 0 to get more control over the balance between CPU load and processing +# speed. At this moment only the input processing can be done using multiple +# threads. Since this is still an experimental feature the default is set to 1, +# which effectively disables parallel processing. Please report any issues you +# encounter. Generating dot graphs in parallel is controlled by the +# DOT_NUM_THREADS setting. +# Minimum value: 0, maximum value: 32, default value: 1. + +NUM_PROC_THREADS = 1 + #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- @@ -433,6 +508,12 @@ EXTRACT_ALL = YES EXTRACT_PRIVATE = NO +# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual +# methods of a class will be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIV_VIRTUAL = NO + # If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal # scope will be included in the documentation. # The default value is: NO. @@ -470,6 +551,13 @@ EXTRACT_LOCAL_METHODS = NO EXTRACT_ANON_NSPACES = NO +# If this flag is set to YES, the name of an unnamed parameter in a declaration +# will be determined by the corresponding definition. By default unnamed +# parameters remain unnamed in the output. +# The default value is: YES. + +RESOLVE_UNNAMED_PARAMS = YES + # If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all # undocumented members inside documented classes or files. If set to NO these # members will be included in the various overviews, but no documentation @@ -481,14 +569,15 @@ HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. If set # to NO, these classes will be included in the various overviews. This option -# has no effect if EXTRACT_ALL is enabled. +# will also hide undocumented C++ concepts if enabled. This option has no effect +# if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend -# (class|struct|union) declarations. If set to NO, these declarations will be -# included in the documentation. +# declarations. If set to NO, these declarations will be included in the +# documentation. # The default value is: NO. HIDE_FRIEND_COMPOUNDS = NO @@ -507,12 +596,20 @@ HIDE_IN_BODY_DOCS = NO INTERNAL_DOCS = NO -# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file -# names in lower-case letters. If set to YES, upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. -# The default value is: system dependent. +# With the correct setting of option CASE_SENSE_NAMES doxygen will better be +# able to match the capabilities of the underlying filesystem. In case the +# filesystem is case sensitive (i.e. it supports files in the same directory +# whose names only differ in casing), the option must be set to YES to properly +# deal with such files in case they appear in the input. For filesystems that +# are not case sensitive the option should be set to NO to properly deal with +# output files written for symbols that only differ in casing, such as for two +# classes, one named CLASS and the other named Class, and to also support +# references to files without having to specify the exact matching casing. On +# Windows (including Cygwin) and MacOS, users should typically set this option +# to NO, whereas on Linux or other Unix flavors it should typically be set to +# YES. +# Possible values are: SYSTEM, NO and YES. +# The default value is: SYSTEM. CASE_SENSE_NAMES = YES @@ -530,6 +627,12 @@ HIDE_SCOPE_NAMES = YES HIDE_COMPOUND_REFERENCE= NO +# If the SHOW_HEADERFILE tag is set to YES then the documentation for a class +# will show which file needs to be included to use the class. +# The default value is: YES. + +SHOW_HEADERFILE = YES + # If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of # the files that are included by a file in the documentation of that file. # The default value is: YES. @@ -687,7 +790,8 @@ FILE_VERSION_FILTER = # output files in an output format independent way. To create the layout file # that represents doxygen's defaults, run doxygen with the -l option. You can # optionally specify a file name after the option, if omitted DoxygenLayout.xml -# will be used as the name of the layout file. +# will be used as the name of the layout file. See also section "Changing the +# layout of pages" for information. # # Note that if you run doxygen from a directory containing a file called # DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE @@ -698,7 +802,7 @@ LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files containing # the reference definitions. This must be a list of .bib files. The .bib # extension is automatically appended if omitted. This requires the bibtex tool -# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. +# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. # For LaTeX the style of the bibliography can be controlled using # LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the # search path. See also \cite for info how to create references. @@ -733,23 +837,50 @@ WARNINGS = YES WARN_IF_UNDOCUMENTED = YES # If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some parameters -# in a documented function, or documenting parameters that don't exist or using -# markup commands wrongly. +# potential errors in the documentation, such as documenting some parameters in +# a documented function twice, or documenting parameters that don't exist or +# using markup commands wrongly. # The default value is: YES. WARN_IF_DOC_ERROR = YES +# If WARN_IF_INCOMPLETE_DOC is set to YES, doxygen will warn about incomplete +# function parameter documentation. If set to NO, doxygen will accept that some +# parameters have no documentation without warning. +# The default value is: YES. + +WARN_IF_INCOMPLETE_DOC = YES + # This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that # are documented, but have no documentation for their parameters or return -# value. If set to NO, doxygen will only warn about wrong or incomplete -# parameter documentation, but not about the absence of documentation. +# value. If set to NO, doxygen will only warn about wrong parameter +# documentation, but not about the absence of documentation. If EXTRACT_ALL is +# set to YES then this flag will automatically be disabled. See also +# WARN_IF_INCOMPLETE_DOC # The default value is: NO. WARN_NO_PARAMDOC = NO +# If WARN_IF_UNDOC_ENUM_VAL option is set to YES, doxygen will warn about +# undocumented enumeration values. If set to NO, doxygen will accept +# undocumented enumeration values. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: NO. + +WARN_IF_UNDOC_ENUM_VAL = NO + # If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when -# a warning is encountered. +# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS +# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but +# at the end of the doxygen process doxygen will return with a non-zero status. +# If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS_PRINT then doxygen behaves +# like FAIL_ON_WARNINGS but in case no WARN_LOGFILE is defined doxygen will not +# write the warning messages in between other messages but write them at the end +# of a run, in case a WARN_LOGFILE is defined the warning messages will be +# besides being in the defined file also be shown at the end of a run, unless +# the WARN_LOGFILE is defined as - i.e. standard output (stdout) in that case +# the behavior will remain as with the setting FAIL_ON_WARNINGS. +# Possible values are: NO, YES, FAIL_ON_WARNINGS and FAIL_ON_WARNINGS_PRINT. # The default value is: NO. WARN_AS_ERROR = NO @@ -760,13 +891,27 @@ WARN_AS_ERROR = NO # and the warning text. Optionally the format may contain $version, which will # be replaced by the version of the file (if it could be obtained via # FILE_VERSION_FILTER) +# See also: WARN_LINE_FORMAT # The default value is: $file:$line: $text. WARN_FORMAT = "$file:$line: $text" +# In the $text part of the WARN_FORMAT command it is possible that a reference +# to a more specific place is given. To make it easier to jump to this place +# (outside of doxygen) the user can define a custom "cut" / "paste" string. +# Example: +# WARN_LINE_FORMAT = "'vi $file +$line'" +# See also: WARN_FORMAT +# The default value is: at line $line of file $file. + +WARN_LINE_FORMAT = "at line $line of file $file" + # The WARN_LOGFILE tag can be used to specify a file to which warning and error # messages should be written. If left blank the output is written to standard -# error (stderr). +# error (stderr). In case the file specified cannot be opened for writing the +# warning and error messages are written to standard error. When as file - is +# specified the warning and error messages are written to standard output +# (stdout). WARN_LOGFILE = @@ -785,12 +930,23 @@ INPUT = ../ # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses # libiconv (or the iconv built into libc) for the transcoding. See the libiconv -# documentation (see: http://www.gnu.org/software/libiconv) for the list of -# possible encodings. +# documentation (see: +# https://www.gnu.org/software/libiconv/) for the list of possible encodings. +# See also: INPUT_FILE_ENCODING # The default value is: UTF-8. INPUT_ENCODING = UTF-8 +# This tag can be used to specify the character encoding of the source files +# that doxygen parses The INPUT_FILE_ENCODING tag can be used to specify +# character encoding on a per file pattern basis. Doxygen will compare the file +# name with each pattern and apply the encoding instead of the default +# INPUT_ENCODING) if there is a match. The character encodings are a list of the +# form: pattern=encoding (like *.php=ISO-8859-1). See cfg_input_encoding +# "INPUT_ENCODING" for further information on supported encodings. + +INPUT_FILE_ENCODING = + # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and # *.h) to filter out the source-files in the directories. @@ -799,11 +955,15 @@ INPUT_ENCODING = UTF-8 # need to set EXTENSION_MAPPING for the extension otherwise the files are not # read by doxygen. # +# Note the list of default checked file patterns might differ from the list of +# default file extension mappings. +# # If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, # *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, -# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, -# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, -# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf. +# *.hh, *.hxx, *.hpp, *.h++, *.l, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, +# *.inc, *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C +# comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, +# *.vhdl, *.ucf, *.qsf and *.ice. FILE_PATTERNS = *.H \ *.C \ @@ -845,7 +1005,7 @@ EXCLUDE_PATTERNS = */lnInclude/* \ # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test +# ANamespace::AClass, ANamespace::*Test # # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories use the pattern */test/* @@ -893,6 +1053,11 @@ IMAGE_PATH = # code is scanned, but not when the output code is generated. If lines are added # or removed, the anchors will not be placed correctly. # +# Note that doxygen will use the data processed and written to standard output +# for further processing, therefore nothing else, like debug statements or used +# commands (so in case of a Windows batch file always use @echo OFF), should be +# written to standard output. +# # Note that for custom extensions or not directly supported extensions you also # need to set EXTENSION_MAPPING for the extension otherwise the files are not # properly processed by doxygen. @@ -934,6 +1099,15 @@ FILTER_SOURCE_PATTERNS = USE_MDFILE_AS_MAINPAGE = +# The Fortran standard specifies that for fixed formatted Fortran code all +# characters from position 72 are to be considered as comment. A common +# extension is to allow longer lines before the automatic comment starts. The +# setting FORTRAN_COMMENT_AFTER will also make it possible that longer lines can +# be processed before the automatic comment starts. +# Minimum value: 7, maximum value: 10000, default value: 72. + +FORTRAN_COMMENT_AFTER = 72 + #--------------------------------------------------------------------------- # Configuration options related to source browsing #--------------------------------------------------------------------------- @@ -961,7 +1135,7 @@ INLINE_SOURCES = NO STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES then for each documented -# function all documented functions referencing it will be listed. +# entity all documented functions referencing it will be listed. # The default value is: NO. REFERENCED_BY_RELATION = YES @@ -993,12 +1167,12 @@ SOURCE_TOOLTIPS = YES # If the USE_HTAGS tag is set to YES then the references to source code will # point to the HTML generated by the htags(1) tool instead of doxygen built-in # source browser. The htags tool is part of GNU's global source tagging system -# (see http://www.gnu.org/software/global/global.html). You will need version +# (see https://www.gnu.org/software/global/global.html). You will need version # 4.8.6 or higher. # # To use it do the following: # - Install the latest version of global -# - Enable SOURCE_BROWSER and USE_HTAGS in the config file +# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file # - Make sure the INPUT points to the root of the source tree # - Run doxygen as normal # @@ -1020,25 +1194,6 @@ USE_HTAGS = NO VERBATIM_HEADERS = YES -# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the -# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the -# cost of reduced performance. This can be particularly helpful with template -# rich C++ code for which doxygen's built-in parser lacks the necessary type -# information. -# Note: The availability of this option depends on whether or not doxygen was -# generated with the -Duse-libclang=ON option for CMake. -# The default value is: NO. - -CLANG_ASSISTED_PARSING = NO - -# If clang assisted parsing is enabled you can provide the compiler with command -# line options that you would normally use when invoking the compiler. Note that -# the include paths will already be set by doxygen for the files and directories -# specified with INPUT and INCLUDE_PATH. -# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. - -CLANG_OPTIONS = - #--------------------------------------------------------------------------- # Configuration options related to the alphabetical class index #--------------------------------------------------------------------------- @@ -1050,17 +1205,11 @@ CLANG_OPTIONS = ALPHABETICAL_INDEX = YES -# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in -# which the alphabetical index list will be split. -# Minimum value: 1, maximum value: 20, default value: 5. -# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. - -COLS_IN_ALPHA_INDEX = 1 - -# In case all classes in a project start with a common prefix, all classes will -# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag -# can be used to specify a prefix (or a list of prefixes) that should be ignored -# while generating the index headers. +# The IGNORE_PREFIX tag can be used to specify a prefix (or a list of prefixes) +# that should be ignored while generating the index headers. The IGNORE_PREFIX +# tag works for classes, function and member names. The entity will be placed in +# the alphabetical list under the first letter of the entity name that remains +# after removing the prefix. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. IGNORE_PREFIX = @@ -1107,7 +1256,7 @@ HTML_FILE_EXTENSION = .html # of the possible markers and block names see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. -#HTML_HEADER =Header +HTML_HEADER = # The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each # generated HTML page. If the tag is left blank doxygen will generate a standard @@ -1117,7 +1266,7 @@ HTML_FILE_EXTENSION = .html # that doxygen normally uses. # This tag requires that the tag GENERATE_HTML is set to YES. -#HTML_FOOTER = Footer +HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading style # sheet that is used by each HTML page. It can be used to fine-tune the look of @@ -1139,10 +1288,16 @@ HTML_STYLESHEET = # Doxygen will copy the style sheet files to the output directory. # Note: The order of the extra style sheet files is of importance (e.g. the last # style sheet in the list overrules the setting of the previous ones in the -# list). For an example see the documentation. +# list). +# Note: Since the styling of scrollbars can currently not be overruled in +# Webkit/Chromium, the styling will be left out of the default doxygen.css if +# one or more extra stylesheets have been specified. So if scrollbar +# customization is desired it has to be added explicitly. For an example see the +# documentation. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_EXTRA_STYLESHEET = +#HTML_EXTRA_STYLESHEET = /home/timofey/Software/doxygen-awesome-css/doxygen-awesome.css \ +# /home/timofey/Software/doxygen-awesome-css/doxygen-awesome-sidebar-only.css # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note @@ -1154,10 +1309,23 @@ HTML_EXTRA_STYLESHEET = HTML_EXTRA_FILES = +# The HTML_COLORSTYLE tag can be used to specify if the generated HTML output +# should be rendered with a dark or light theme. +# Possible values are: LIGHT always generate light mode output, DARK always +# generate dark mode output, AUTO_LIGHT automatically set the mode according to +# the user preference, use light mode if no preference is set (the default), +# AUTO_DARK automatically set the mode according to the user preference, use +# dark mode if no preference is set and TOGGLE allow to user to switch between +# light and dark mode via a button. +# The default value is: AUTO_LIGHT. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE = AUTO_LIGHT + # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen # will adjust the colors in the style sheet and background images according to -# this color. Hue is specified as an angle on a colorwheel, see -# http://en.wikipedia.org/wiki/Hue for more information. For instance the value +# this color. Hue is specified as an angle on a color-wheel, see +# https://en.wikipedia.org/wiki/Hue for more information. For instance the value # 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 # purple, and 360 is red again. # Minimum value: 0, maximum value: 359, default value: 220. @@ -1166,7 +1334,7 @@ HTML_EXTRA_FILES = HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors -# in the HTML output. For a value of 0 the output will use grayscales only. A +# in the HTML output. For a value of 0 the output will use gray-scales only. A # value of 255 will produce the most vivid colors. # Minimum value: 0, maximum value: 255, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. @@ -1193,6 +1361,17 @@ HTML_COLORSTYLE_GAMMA = 80 HTML_TIMESTAMP = NO +# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML +# documentation will contain a main index with vertical navigation menus that +# are dynamically created via JavaScript. If disabled, the navigation index will +# consists of multiple levels of tabs that are statically embedded in every HTML +# page. Disable this option to support browsers that do not have JavaScript, +# like the Qt help browser. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_MENUS = YES + # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. @@ -1216,13 +1395,14 @@ HTML_INDEX_NUM_ENTRIES = 100 # If the GENERATE_DOCSET tag is set to YES, additional index files will be # generated that can be used as input for Apple's Xcode 3 integrated development -# environment (see: http://developer.apple.com/tools/xcode/), introduced with -# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a -# Makefile in the HTML output directory. Running make will produce the docset in -# that directory and running make install will install the docset in +# environment (see: +# https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To +# create a documentation set, doxygen will generate a Makefile in the HTML +# output directory. Running make will produce the docset in that directory and +# running make install will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at -# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html -# for more information. +# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy +# genXcode/_index.html for more information. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. @@ -1236,6 +1416,13 @@ GENERATE_DOCSET = NO DOCSET_FEEDNAME = "Doxygen generated docs" +# This tag determines the URL of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDURL = + # This tag specifies a string that should uniquely identify the documentation # set bundle. This should be a reverse domain-name style string, e.g. # com.mycompany.MyDocSet. Doxygen will append .docset to the name. @@ -1261,8 +1448,12 @@ DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three # additional HTML index files: index.hhp, index.hhc, and index.hhk. The # index.hhp is a project file that can be read by Microsoft's HTML Help Workshop -# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on -# Windows. +# on Windows. In the beginning of 2021 Microsoft took the original page, with +# a.o. the download links, offline the HTML help workshop was already many years +# in maintenance mode). You can download the HTML help workshop from the web +# archives at Installation executable (see: +# http://web.archive.org/web/20160201063255/http://download.microsoft.com/downlo +# ad/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/htmlhelp.exe). # # The HTML Help Workshop contains a compiler that can convert all HTML output # generated by doxygen into a single compiled HTML file (.chm). Compiled HTML @@ -1292,7 +1483,7 @@ CHM_FILE = HHC_LOCATION = # The GENERATE_CHI flag controls if a separate .chi index file is generated -# (YES) or that it should be included in the master .chm file (NO). +# (YES) or that it should be included in the main .chm file (NO). # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. @@ -1337,7 +1528,8 @@ QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help # Project output. For more information please see Qt Help Project / Namespace -# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). +# (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_QHP is set to YES. @@ -1345,8 +1537,8 @@ QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt # Help Project output. For more information please see Qt Help Project / Virtual -# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- -# folders). +# Folders (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders). # The default value is: doc. # This tag requires that the tag GENERATE_QHP is set to YES. @@ -1354,30 +1546,30 @@ QHP_VIRTUAL_FOLDER = doc # If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom # filter to add. For more information please see Qt Help Project / Custom -# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- -# filters). +# Filters (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_NAME = # The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see Qt Help Project / Custom -# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- -# filters). +# Filters (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's filter section matches. Qt Help Project / Filter Attributes (see: -# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_SECT_FILTER_ATTRS = -# The QHG_LOCATION tag can be used to specify the location of Qt's -# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the -# generated .qhp file. +# The QHG_LOCATION tag can be used to specify the location (absolute path +# including file name) of Qt's qhelpgenerator. If non-empty doxygen will try to +# run qhelpgenerator on the generated .qhp file. # This tag requires that the tag GENERATE_QHP is set to YES. QHG_LOCATION = @@ -1420,15 +1612,27 @@ DISABLE_INDEX = NO # to work a browser that supports JavaScript, DHTML, CSS and frames is required # (i.e. any modern browser). Windows users are probably better off using the # HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can -# further fine-tune the look of the index. As an example, the default style -# sheet generated by doxygen has an example that shows how to put an image at -# the root of the tree instead of the PROJECT_NAME. Since the tree basically has -# the same information as the tab index, you could consider setting -# DISABLE_INDEX to YES when enabling this option. +# further fine tune the look of the index (see "Fine-tuning the output"). As an +# example, the default style sheet generated by doxygen has an example that +# shows how to put an image at the root of the tree instead of the PROJECT_NAME. +# Since the tree basically has the same information as the tab index, you could +# consider setting DISABLE_INDEX to YES when enabling this option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. -GENERATE_TREEVIEW = NO +GENERATE_TREEVIEW = YES + +# When both GENERATE_TREEVIEW and DISABLE_INDEX are set to YES, then the +# FULL_SIDEBAR option determines if the side bar is limited to only the treeview +# area (value NO) or if it should extend to the full height of the window (value +# YES). Setting this to YES gives a layout similar to +# https://docs.readthedocs.io with more room for contents, but less room for the +# project logo, title, and description. If either GENERATE_TREEVIEW or +# DISABLE_INDEX is set to NO, this option has no effect. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FULL_SIDEBAR = NO # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that # doxygen will group on one line in the generated HTML documentation. @@ -1454,6 +1658,24 @@ TREEVIEW_WIDTH = 250 EXT_LINKS_IN_WINDOW = NO +# If the OBFUSCATE_EMAILS tag is set to YES, doxygen will obfuscate email +# addresses. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +OBFUSCATE_EMAILS = YES + +# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg +# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see +# https://inkscape.org) to generate formulas as SVG images instead of PNGs for +# the HTML output. These images will generally look nicer at scaled resolutions. +# Possible values are: png (the default) and svg (looks nicer but requires the +# pdf2svg or inkscape tool). +# The default value is: png. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FORMULA_FORMAT = png + # Use this tag to change the font size of LaTeX formulas included as images in # the HTML documentation. When you change the font size after a successful # doxygen run you need to manually remove any form_*.png images from the HTML @@ -1463,19 +1685,14 @@ EXT_LINKS_IN_WINDOW = NO FORMULA_FONTSIZE = 10 -# Use the FORMULA_TRANPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are not -# supported properly for IE 6.0, but are supported on all modern browsers. -# -# Note that when changing this option you need to delete any form_*.png files in -# the HTML output directory before the changes have effect. -# The default value is: YES. -# This tag requires that the tag GENERATE_HTML is set to YES. +# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands +# to create new LaTeX commands to be used in formulas as building blocks. See +# the section "Including formulas" for details. -FORMULA_TRANSPARENT = YES +FORMULA_MACROFILE = # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see -# http://www.mathjax.org) which uses client side Javascript for the rendering +# https://www.mathjax.org) which uses client side JavaScript for the rendering # instead of using pre-rendered bitmaps. Use this if you do not have LaTeX # installed or if you want to formulas look prettier in the HTML output. When # enabled you may also need to install MathJax separately and configure the path @@ -1485,11 +1702,29 @@ FORMULA_TRANSPARENT = YES USE_MATHJAX = NO +# With MATHJAX_VERSION it is possible to specify the MathJax version to be used. +# Note that the different versions of MathJax have different requirements with +# regards to the different settings, so it is possible that also other MathJax +# settings have to be changed when switching between the different MathJax +# versions. +# Possible values are: MathJax_2 and MathJax_3. +# The default value is: MathJax_2. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_VERSION = MathJax_2 + # When MathJax is enabled you can set the default output format to be used for -# the MathJax output. See the MathJax site (see: -# http://docs.mathjax.org/en/latest/output.html) for more details. +# the MathJax output. For more details about the output format see MathJax +# version 2 (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) and MathJax version 3 +# (see: +# http://docs.mathjax.org/en/latest/web/components/output.html). # Possible values are: HTML-CSS (which is slower, but has the best -# compatibility), NativeMML (i.e. MathML) and SVG. +# compatibility. This is the name for Mathjax version 2, for MathJax version 3 +# this will be translated into chtml), NativeMML (i.e. MathML. Only supported +# for NathJax 2. For MathJax version 3 chtml will be used instead.), chtml (This +# is the name for Mathjax version 3, for MathJax version 2 this will be +# translated into HTML-CSS) and SVG. # The default value is: HTML-CSS. # This tag requires that the tag USE_MATHJAX is set to YES. @@ -1502,22 +1737,29 @@ MATHJAX_FORMAT = HTML-CSS # MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax # Content Delivery Network so you can quickly see the result without installing # MathJax. However, it is strongly recommended to install a local copy of -# MathJax from http://www.mathjax.org before deployment. -# The default value is: http://cdn.mathjax.org/mathjax/latest. +# MathJax from https://www.mathjax.org before deployment. The default value is: +# - in case of MathJax version 2: https://cdn.jsdelivr.net/npm/mathjax@2 +# - in case of MathJax version 3: https://cdn.jsdelivr.net/npm/mathjax@3 # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest # The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax # extension names that should be enabled during MathJax rendering. For example +# for MathJax version 2 (see +# https://docs.mathjax.org/en/v2.7-latest/tex.html#tex-and-latex-extensions): # MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# For example for MathJax version 3 (see +# http://docs.mathjax.org/en/latest/input/tex/extensions/index.html): +# MATHJAX_EXTENSIONS = ams # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_EXTENSIONS = # The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces # of code that will be used on startup of the MathJax code. See the MathJax site -# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an +# (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an # example see the documentation. # This tag requires that the tag USE_MATHJAX is set to YES. @@ -1545,7 +1787,7 @@ MATHJAX_CODEFILE = SEARCHENGINE = YES # When the SERVER_BASED_SEARCH tag is enabled the search engine will be -# implemented using a web server instead of a web client using Javascript. There +# implemented using a web server instead of a web client using JavaScript. There # are two flavors of web server based searching depending on the EXTERNAL_SEARCH # setting. When disabled, doxygen will generate a PHP script for searching and # an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing @@ -1564,7 +1806,8 @@ SERVER_BASED_SEARCH = NO # # Doxygen ships with an example indexer (doxyindexer) and search engine # (doxysearch.cgi) which are based on the open source search engine library -# Xapian (see: http://xapian.org/). +# Xapian (see: +# https://xapian.org/). # # See the section "External Indexing and Searching" for details. # The default value is: NO. @@ -1577,8 +1820,9 @@ EXTERNAL_SEARCH = NO # # Doxygen ships with an example indexer (doxyindexer) and search engine # (doxysearch.cgi) which are based on the open source search engine library -# Xapian (see: http://xapian.org/). See the section "External Indexing and -# Searching" for details. +# Xapian (see: +# https://xapian.org/). See the section "External Indexing and Searching" for +# details. # This tag requires that the tag SEARCHENGINE is set to YES. SEARCHENGINE_URL = @@ -1629,21 +1873,35 @@ LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. # -# Note that when enabling USE_PDFLATEX this option is only used for generating -# bitmaps for formulas in the HTML output, but not in the Makefile that is -# written to the output directory. -# The default file is: latex. +# Note that when not enabling USE_PDFLATEX the default is latex when enabling +# USE_PDFLATEX the default is pdflatex and when in the later case latex is +# chosen this is overwritten by pdflatex. For specific output languages the +# default can have been set differently, this depends on the implementation of +# the output language. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate # index for LaTeX. +# Note: This tag is used in the Makefile / make.bat. +# See also: LATEX_MAKEINDEX_CMD for the part in the generated output file +# (.tex). # The default file is: makeindex. # This tag requires that the tag GENERATE_LATEX is set to YES. MAKEINDEX_CMD_NAME = makeindex +# The LATEX_MAKEINDEX_CMD tag can be used to specify the command name to +# generate index for LaTeX. In case there is no backslash (\) as first character +# it will be automatically added in the LaTeX code. +# Note: This tag is used in the generated output file (.tex). +# See also: MAKEINDEX_CMD_NAME for the part in the Makefile / make.bat. +# The default value is: makeindex. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_MAKEINDEX_CMD = makeindex + # If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX # documents. This may be useful for small projects and may help to save some # trees in general. @@ -1659,7 +1917,7 @@ COMPACT_LATEX = NO # The default value is: a4. # This tag requires that the tag GENERATE_LATEX is set to YES. -PAPER_TYPE = a4wide +PAPER_TYPE = a4 # The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names # that should be included in the LaTeX output. The package can be specified just @@ -1671,31 +1929,33 @@ PAPER_TYPE = a4wide # If left blank no extra packages will be included. # This tag requires that the tag GENERATE_LATEX is set to YES. -EXTRA_PACKAGES = $(WM_PROJECT_DIR)/doc/Doxygen/Macros/tensorOperator +EXTRA_PACKAGES = $LIBWMLES_DIR/docs/Macros/tensorOperator -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the -# generated LaTeX document. The header should contain everything until the first -# chapter. If it is left blank doxygen will generate a standard header. See -# section "Doxygen usage" for information on how to let doxygen write the -# default header to a separate file. +# The LATEX_HEADER tag can be used to specify a user-defined LaTeX header for +# the generated LaTeX document. The header should contain everything until the +# first chapter. If it is left blank doxygen will generate a standard header. It +# is highly recommended to start with a default header using +# doxygen -w latex new_header.tex new_footer.tex new_stylesheet.sty +# and then modify the file new_header.tex. See also section "Doxygen usage" for +# information on how to generate the default header that doxygen normally uses. # -# Note: Only use a user-defined header if you know what you are doing! The -# following commands have a special meaning inside the header: $title, -# $datetime, $date, $doxygenversion, $projectname, $projectnumber, -# $projectbrief, $projectlogo. Doxygen will replace $title with the empty -# string, for the replacement values of the other commands the user is referred -# to HTML_HEADER. +# Note: Only use a user-defined header if you know what you are doing! +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. The following +# commands have a special meaning inside the header (and footer): For a +# description of the possible markers and block names see the documentation. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_HEADER = -# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the -# generated LaTeX document. The footer should contain everything after the last -# chapter. If it is left blank doxygen will generate a standard footer. See +# The LATEX_FOOTER tag can be used to specify a user-defined LaTeX footer for +# the generated LaTeX document. The footer should contain everything after the +# last chapter. If it is left blank doxygen will generate a standard footer. See # LATEX_HEADER for more information on how to generate a default footer and what -# special commands can be used inside the footer. -# -# Note: Only use a user-defined footer if you know what you are doing! +# special commands can be used inside the footer. See also section "Doxygen +# usage" for information on how to generate the default footer that doxygen +# normally uses. Note: Only use a user-defined footer if you know what you are +# doing! # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_FOOTER = @@ -1728,9 +1988,11 @@ LATEX_EXTRA_FILES = PDF_HYPERLINKS = YES -# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate -# the PDF file directly from the LaTeX files. Set this option to YES, to get a -# higher quality PDF documentation. +# If the USE_PDFLATEX tag is set to YES, doxygen will use the engine as +# specified with LATEX_CMD_NAME to generate the PDF file directly from the LaTeX +# files. Set this option to YES, to get a higher quality PDF documentation. +# +# See also section LATEX_CMD_NAME for selecting the engine. # The default value is: YES. # This tag requires that the tag GENERATE_LATEX is set to YES. @@ -1738,8 +2000,7 @@ USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode # command to the generated LaTeX files. This will instruct LaTeX to keep running -# if errors occur, instead of asking the user for help. This option is also used -# when generating formulas in HTML. +# if errors occur, instead of asking the user for help. # The default value is: NO. # This tag requires that the tag GENERATE_LATEX is set to YES. @@ -1752,19 +2013,9 @@ LATEX_BATCHMODE = NO LATEX_HIDE_INDICES = NO -# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source -# code with syntax highlighting in the LaTeX output. -# -# Note that which sources are shown also depends on other settings such as -# SOURCE_BROWSER. -# The default value is: NO. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_SOURCE_CODE = NO - # The LATEX_BIB_STYLE tag can be used to specify the style to use for the # bibliography, e.g. plainnat, or ieeetr. See -# http://en.wikipedia.org/wiki/BibTeX and \cite for more info. +# https://en.wikipedia.org/wiki/BibTeX and \cite for more info. # The default value is: plain. # This tag requires that the tag GENERATE_LATEX is set to YES. @@ -1778,6 +2029,14 @@ LATEX_BIB_STYLE = plain LATEX_TIMESTAMP = NO +# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute) +# path from which the emoji images will be read. If a relative path is entered, +# it will be relative to the LATEX_OUTPUT directory. If left blank the +# LATEX_OUTPUT directory will be used. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_EMOJI_DIRECTORY = + #--------------------------------------------------------------------------- # Configuration options related to the RTF output #--------------------------------------------------------------------------- @@ -1817,9 +2076,9 @@ COMPACT_RTF = NO RTF_HYPERLINKS = NO -# Load stylesheet definitions from file. Syntax is similar to doxygen's config -# file, i.e. a series of assignments. You only have to provide replacements, -# missing definitions are set to their default value. +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# configuration file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. # # See also section "Doxygen usage" for information on how to generate the # default style sheet that doxygen normally uses. @@ -1828,22 +2087,12 @@ RTF_HYPERLINKS = NO RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an RTF document. Syntax is -# similar to doxygen's config file. A template extensions file can be generated -# using doxygen -e rtf extensionFile. +# similar to doxygen's configuration file. A template extensions file can be +# generated using doxygen -e rtf extensionFile. # This tag requires that the tag GENERATE_RTF is set to YES. RTF_EXTENSIONS_FILE = -# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code -# with syntax highlighting in the RTF output. -# -# Note that which sources are shown also depends on other settings such as -# SOURCE_BROWSER. -# The default value is: NO. -# This tag requires that the tag GENERATE_RTF is set to YES. - -RTF_SOURCE_CODE = NO - #--------------------------------------------------------------------------- # Configuration options related to the man page output #--------------------------------------------------------------------------- @@ -1896,7 +2145,7 @@ MAN_LINKS = NO # captures the structure of the code including all documentation. # The default value is: NO. -GENERATE_XML = YES +GENERATE_XML = YES # The XML_OUTPUT tag is used to specify where the XML pages will be put. If a # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of @@ -1915,6 +2164,13 @@ XML_OUTPUT = xml XML_PROGRAMLISTING = YES +# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, doxygen will include +# namespace members in file scope as well, matching the HTML output. +# The default value is: NO. +# This tag requires that the tag GENERATE_XML is set to YES. + +XML_NS_MEMB_FILE_SCOPE = NO + #--------------------------------------------------------------------------- # Configuration options related to the DOCBOOK output #--------------------------------------------------------------------------- @@ -1933,23 +2189,14 @@ GENERATE_DOCBOOK = NO DOCBOOK_OUTPUT = docbook -# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the -# program listings (including syntax highlighting and cross-referencing -# information) to the DOCBOOK output. Note that enabling this will significantly -# increase the size of the DOCBOOK output. -# The default value is: NO. -# This tag requires that the tag GENERATE_DOCBOOK is set to YES. - -DOCBOOK_PROGRAMLISTING = NO - #--------------------------------------------------------------------------- # Configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an -# AutoGen Definitions (see http://autogen.sf.net) file that captures the -# structure of the code including all documentation. Note that this feature is -# still experimental and incomplete at the moment. +# AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures +# the structure of the code including all documentation. Note that this feature +# is still experimental and incomplete at the moment. # The default value is: NO. GENERATE_AUTOGEN_DEF = NO @@ -2028,7 +2275,8 @@ SEARCH_INCLUDES = NO # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by the -# preprocessor. +# preprocessor. Note that the INCLUDE_PATH is not recursive, so the setting of +# RECURSIVE has no effect here. # This tag requires that the tag SEARCH_INCLUDES is set to YES. INCLUDE_PATH = @@ -2116,41 +2364,10 @@ EXTERNAL_GROUPS = YES EXTERNAL_PAGES = YES -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of 'which perl'). -# The default file (with absolute path) is: /usr/bin/perl. - -PERL_PATH = /usr/bin/perl - #--------------------------------------------------------------------------- -# Configuration options related to the dot tool +# Configuration options related to diagram generator tools #--------------------------------------------------------------------------- -# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram -# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to -# NO turns the diagrams off. Note that this option also works with HAVE_DOT -# disabled, but it is recommended to install and use dot, since it yields more -# powerful graphs. -# The default value is: YES. - -CLASS_DIAGRAMS = YES - -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see: -# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the -# default search path. - -MSCGEN_PATH = - -# You can include diagrams made with dia in doxygen documentation. Doxygen will -# then run dia to produce the diagram and insert it in the documentation. The -# DIA_PATH tag allows you to specify the directory where the dia binary resides. -# If left empty dia is assumed to be found in the default search path. - -DIA_PATH = - # If set to YES the inheritance and collaboration graphs will hide inheritance # and usage relations if the target is undocumented or is not a class. # The default value is: YES. @@ -2162,7 +2379,7 @@ HIDE_UNDOC_RELATIONS = YES # http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent # Bell Labs. The other options in this section have no effect if this option is # set to NO -# The default value is: YES. +# The default value is: NO. HAVE_DOT = YES @@ -2176,35 +2393,52 @@ HAVE_DOT = YES DOT_NUM_THREADS = 0 -# When you want a differently looking font in the dot files that doxygen -# generates you can specify the font name using DOT_FONTNAME. You need to make -# sure dot is able to find the font, which can be done by putting it in a -# standard location or by setting the DOTFONTPATH environment variable or by -# setting DOT_FONTPATH to the directory containing the font. -# The default value is: Helvetica. +# DOT_COMMON_ATTR is common attributes for nodes, edges and labels of +# subgraphs. When you want a differently looking font in the dot files that +# doxygen generates you can specify fontname, fontcolor and fontsize attributes. +# For details please see Node, +# Edge and Graph Attributes specification You need to make sure dot is able +# to find the font, which can be done by putting it in a standard location or by +# setting the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the +# directory containing the font. Default graphviz fontsize is 14. +# The default value is: fontname=Helvetica,fontsize=10. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_COMMON_ATTR = "fontname=FreeSans,fontsize=10" + +# DOT_EDGE_ATTR is concatenated with DOT_COMMON_ATTR. For elegant style you can +# add 'arrowhead=open, arrowtail=open, arrowsize=0.5'. Complete documentation about +# arrows shapes. +# The default value is: labelfontname=Helvetica,labelfontsize=10. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_FONTNAME = FreeSans +DOT_EDGE_ATTR = "labelfontname=FreeSans,labelfontsize=10" -# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of -# dot graphs. -# Minimum value: 4, maximum value: 24, default value: 10. +# DOT_NODE_ATTR is concatenated with DOT_COMMON_ATTR. For view without boxes +# around nodes set 'shape=plain' or 'shape=plaintext' Shapes specification +# The default value is: shape=box,height=0.2,width=0.4. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_FONTSIZE = 10 +DOT_NODE_ATTR = "shape=box,height=0.2,width=0.4" -# By default doxygen will tell dot to use the default font as specified with -# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set -# the path where dot can find it using this tag. +# You can set the path where dot can find font specified with fontname in +# DOT_COMMON_ATTR and others dot attributes. # This tag requires that the tag HAVE_DOT is set to YES. DOT_FONTPATH = -# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for -# each documented class showing the direct and indirect inheritance relations. -# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO. +# If the CLASS_GRAPH tag is set to YES or GRAPH or BUILTIN then doxygen will +# generate a graph for each documented class showing the direct and indirect +# inheritance relations. In case the CLASS_GRAPH tag is set to YES or GRAPH and +# HAVE_DOT is enabled as well, then dot will be used to draw the graph. In case +# the CLASS_GRAPH tag is set to YES and HAVE_DOT is disabled or if the +# CLASS_GRAPH tag is set to BUILTIN, then the built-in generator will be used. +# If the CLASS_GRAPH tag is set to TEXT the direct and indirect inheritance +# relations will be shown as texts / links. +# Possible values are: NO, YES, TEXT, GRAPH and BUILTIN. # The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. CLASS_GRAPH = YES @@ -2218,7 +2452,8 @@ CLASS_GRAPH = YES COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for -# groups, showing the direct groups dependencies. +# groups, showing the direct groups dependencies. See also the chapter Grouping +# in the manual. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. @@ -2241,10 +2476,32 @@ UML_LOOK = NO # but if the number exceeds 15, the total amount of fields shown is limited to # 10. # Minimum value: 0, maximum value: 100, default value: 10. -# This tag requires that the tag HAVE_DOT is set to YES. +# This tag requires that the tag UML_LOOK is set to YES. UML_LIMIT_NUM_FIELDS = 10 +# If the DOT_UML_DETAILS tag is set to NO, doxygen will show attributes and +# methods without types and arguments in the UML graphs. If the DOT_UML_DETAILS +# tag is set to YES, doxygen will add type and arguments for attributes and +# methods in the UML graphs. If the DOT_UML_DETAILS tag is set to NONE, doxygen +# will not generate fields with class member information in the UML graphs. The +# class diagrams will look similar to the default class diagrams but using UML +# notation for the relationships. +# Possible values are: NO, YES and NONE. +# The default value is: NO. +# This tag requires that the tag UML_LOOK is set to YES. + +DOT_UML_DETAILS = NO + +# The DOT_WRAP_THRESHOLD tag can be used to set the maximum number of characters +# to display on a single line. If the actual line length exceeds this threshold +# significantly it will wrapped across multiple lines. Some heuristics are apply +# to avoid ugly line breaks. +# Minimum value: 0, maximum value: 1000, default value: 17. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_WRAP_THRESHOLD = 17 + # If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and # collaboration graphs will show the relations between templates and their # instances. @@ -2311,6 +2568,13 @@ GRAPHICAL_HIERARCHY = YES DIRECTORY_GRAPH = YES +# The DIR_GRAPH_MAX_DEPTH tag can be used to limit the maximum number of levels +# of child directories generated in directory dependency graphs by dot. +# Minimum value: 1, maximum value: 25, default value: 1. +# This tag requires that the tag DIRECTORY_GRAPH is set to YES. + +DIR_GRAPH_MAX_DEPTH = 1 + # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. For an explanation of the image formats see the section # output formats in the documentation of the dot tool (Graphviz (see: @@ -2318,9 +2582,7 @@ DIRECTORY_GRAPH = YES # Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order # to make the SVG files visible in IE 9+ (other browsers do not have this # requirement). -# Possible values are: png, png:cairo, png:cairo:cairo, png:cairo:gd, png:gd, -# png:gd:gd, jpg, jpg:cairo, jpg:cairo:gd, jpg:gd, jpg:gd:gd, gif, gif:cairo, -# gif:cairo:gd, gif:gd, gif:gd:gd, svg, png:gd, png:gd:gd, png:cairo, +# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo, # png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and # png:gdiplus:gdiplus. # The default value is: png. @@ -2353,11 +2615,12 @@ DOT_PATH = DOTFILE_DIRS = -# The MSCFILE_DIRS tag can be used to specify one or more directories that -# contain msc files that are included in the documentation (see the \mscfile -# command). +# You can include diagrams made with dia in doxygen documentation. Doxygen will +# then run dia to produce the diagram and insert it in the documentation. The +# DIA_PATH tag allows you to specify the directory where the dia binary resides. +# If left empty dia is assumed to be found in the default search path. -MSCFILE_DIRS = +DIA_PATH = # The DIAFILE_DIRS tag can be used to specify one or more directories that # contain dia files that are included in the documentation (see the \diafile @@ -2366,10 +2629,10 @@ MSCFILE_DIRS = DIAFILE_DIRS = # When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the -# path where java can find the plantuml.jar file. If left blank, it is assumed -# PlantUML is not used or called during a preprocessing step. Doxygen will -# generate a warning when it encounters a \startuml command in this case and -# will not generate output for the diagram. +# path where java can find the plantuml.jar file or to the filename of jar file +# to be used. If left blank, it is assumed PlantUML is not used or called during +# a preprocessing step. Doxygen will generate a warning when it encounters a +# \startuml command in this case and will not generate output for the diagram. PLANTUML_JAR_PATH = @@ -2407,18 +2670,6 @@ DOT_GRAPH_MAX_NODES = 50 MAX_DOT_GRAPH_DEPTH = 1 -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, because dot on Windows does not seem -# to support this out of the box. -# -# Warning: Depending on the platform used, enabling this option may lead to -# badly anti-aliased labels on the edges of a graph (i.e. they become hard to -# read). -# The default value is: NO. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_TRANSPARENT = YES - # Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) support @@ -2431,14 +2682,34 @@ DOT_MULTI_TARGETS = YES # If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page # explaining the meaning of the various boxes and arrows in the dot generated # graphs. +# Note: This tag requires that UML_LOOK isn't set, i.e. the doxygen internal +# graphical representation for inheritance and collaboration diagrams is used. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. GENERATE_LEGEND = YES -# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot +# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate # files that are used to generate the various graphs. +# +# Note: This setting is not only used for dot files but also for msc temporary +# files. # The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. DOT_CLEANUP = NO + +# You can define message sequence charts within doxygen comments using the \msc +# command. If the MSCGEN_TOOL tag is left empty (the default), then doxygen will +# use a built-in version of mscgen tool to produce the charts. Alternatively, +# the MSCGEN_TOOL tag can also specify the name an external tool. For instance, +# specifying prog as the value, doxygen will call the tool as prog -T +# -o . The external tool should support +# output file formats "png", "eps", "svg", and "ismap". + +MSCGEN_TOOL = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the \mscfile +# command). + +MSCFILE_DIRS = diff --git a/docs/Macros/tensorOperator.sty b/docs/Macros/tensorOperator.sty new file mode 100644 index 0000000..fad485e --- /dev/null +++ b/docs/Macros/tensorOperator.sty @@ -0,0 +1,129 @@ +%----------------------------------------------------------------------------- +% ========= | +% \\ / F ield | OpenFOAM: The Open Source CFD Toolbox +% \\ / O peration | +% \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation +% \\/ M anipulation | +%------------------------------------------------------------------------------ +% License +% This file is part of OpenFOAM. +% +% OpenFOAM is free software: you can redistribute it and/or modify it +% under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% OpenFOAM is distributed in the hope that it will be useful, but WITHOUT +% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +% FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +% for more details. +% +% You should have received a copy of the GNU General Public License +% along with OpenFOAM. If not, see . +% +% LaTeX Style file +% tensorOperator.sty +% +% Description +% Standard OpenFOAM LaTeX macros for typesetting tensor algebra. +% +%------------------------------------------------------------------------------ + +% tensor style +% ~~~~~~~~~~~~ +\renewcommand{\vec}[1] {\ensuremath{\mathbf #1}} +\newcommand{\gvec}[1] {\ensuremath{\mbox{\boldmath$\bf#1$}}} + +% products +% ~~~~~~~~ +\newcommand{\anyprod}{\star} +\newcommand{\cprod} {\times} +\newcommand{\dprod} {\,{\scriptscriptstyle \stackrel{\bullet}{{}}}\,} +\newcommand{\ddprod} {\,{\scriptscriptstyle \stackrel{\bullet}{\bullet}}\,} +\newcommand{\tdprod} {\,{\scriptscriptstyle \stackrel{3}{\bullet}}\,} +\newcommand{\tprod} {\,{\scriptscriptstyle \stackrel{\otimes}{{}}}\,} + +% operations +% ~~~~~~~~~~ +\newcommand{\adj} {\ensuremath{\operatorname{adj}}} +\newcommand{\cof} {\ensuremath{\operatorname{cof}}} +\newcommand{\diag} {\ensuremath{\operatorname{diag}}} +\newcommand{\dev} {\ensuremath{\operatorname{dev}}} + +\newcommand{\Hodge} {\ensuremath{\operatorname{\stackrel{\displaystyle \ast}{}}}} +\newcommand{\hyd} {\ensuremath{\operatorname{hyd}}} +\renewcommand{\max} {\ensuremath{\operatorname{max}}} +\renewcommand{\min} {\ensuremath{\operatorname{min}}} +\newcommand{\inv} {\ensuremath{\operatorname{inv}}} +\newcommand{\sym} {\ensuremath{\operatorname{symm}}} % symm ? +\newcommand{\skw} {\ensuremath{\operatorname{skew}}} % skew already defined +\newcommand{\tr} {\ensuremath{\operatorname{tr}}} +\newcommand{\trans}[1] {\ensuremath{#1^{\operatorname{T}}}} + +% alternative tensor operators for hypersonics etc. +% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +\newcommand{\devs}[1] {\overset{\scriptscriptstyle\circ}{#1}} +%\newcommand{\trans}[1] {\ensuremath{#1^{\operatorname{T}}}} +\newcommand{\symms}[1] {\overleftrightarrow{#1}} +\newlength{\skewslength} +\newlength{\skewsheight} +\newcommand{\skews}[1]{ + \settowidth{\skewslength}{#1}% + \settoheight{\skewsheight}{#1}% + \addtolength{\skewsheight}{0.4mm}% + {\overleftrightarrow{#1}\hspace{-.5\skewslength}% + \rule[\skewsheight]{.4pt}{1.4mm} + \hspace{.5\skewslength}% +}} +%\newcommand{\skew}[1] {\ensuremath{#1^{\operatorname{A}}}} + +% spatial derivatives +% ~~~~~~~~~~~~~~~~~~~ +\newcommand{\curl}{\ensuremath{\nabla\cprod}} +\renewcommand{\div} {\ensuremath{\nabla\dprod}} +\newcommand{\grad}{\ensuremath{\nabla}} +\newcommand{\laplacian}{\ensuremath{\nabla^{2}}} + +% temporal derivatives +% ~~~~~~~~~~~~~~~~~~~~ +\newcommand{\ddt}[1] {\ensuremath{\frac{\partial #1}{\partial t }}} +\newcommand{\DDt}[1] {\ensuremath{\frac{D #1}{D t}}} +\newcommand{\DpDt}[2] {\ensuremath{\frac{d_{#1} #2}{d t }}} +\newcommand{\dsdts}[1] {\ensuremath{\frac{\partial ^2 #1}{\partial t^2}}} +\newcommand{\rate}[1] {\ensuremath{\dot{#1}}} + +\newcommand{\genDer}{\mathcal{L}} + +% time average symbols +% ~~~~~~~~~~~~~~~~~~~~ +\newcommand{\av}[1] {\ensuremath{\overline{#1}}} +\newcommand{\corrtwo}[2] {{\dwea{\dprime{#1} \dprime{#2}}}} +\newcommand{\curly}[1] {{\cal #1}} +\newcommand{\dprime}[1] {\ensuremath{{#1}^{^{\prime \prime}}}} +\newcommand{\dwea}[1] {\ensuremath{\widetilde{#1}}} +\newcommand{\dweafluc}[1] {\ensuremath{\dprime{#1}}} +\newcommand{\fluc}[1] {\ensuremath{#1^{\prime}}} + +% index style +% ~~~~~~~~~~~ +\newcommand{\veci}[2][i] {\ensuremath{#2_{#1}}} +\newcommand{\teni}[2][ij] {\ensuremath{#2_{#1}}} +\newcommand{\tenTi}[2][ji] {\ensuremath{#2_{#1}}} + +% index operations +% ~~~~~~~~~~~~~~~~ +\newcommand{\deltai}[1] {\ensuremath{\partial_{#1}}} + +% Sub-subscripts +% ~~~~~~~~~~~~~~ +\newcommand{\eff} {{\scriptscriptstyle e\!f\!\!f\!}} + +% unknown use +% ~~~~~~~~~~~ +%\font\bigtenrm=cmr12 scaled 1200 +%\newcommand{\eexp}[1]{{\hbox{$\textfont1=\bigtenrm e$}}^{\raise3pt +%\hbox{$#1$}}} + + +% ------------------------------------------------------------------------------ + diff --git a/docs/conf.py b/docs/conf.py index 765ce2f..94f9ce1 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -53,7 +53,6 @@ 'exhale', 'sphinx_rtd_theme', 'sphinxcontrib.bibtex', - 'sphinx.ext.autosectionlabel' ] bibtex_bibfiles = ['bibl.bib'] @@ -204,7 +203,7 @@ "rootFileTitle": "Library API", "doxygenStripFromPath": "..", # Suggested optional arguments - "createTreeView": True, + "createTreeView": False, # TIP: if using the sphinx-bootstrap-theme, you need # "treeViewIsBootstrap": True, "exhaleExecutesDoxygen": True, @@ -214,4 +213,4 @@ "doxygenStripFromPath": "../" } -numfig = True \ No newline at end of file +numfig = True diff --git a/docs/environment.yaml b/docs/environment.yaml new file mode 100644 index 0000000..6ae0fb7 --- /dev/null +++ b/docs/environment.yaml @@ -0,0 +1,12 @@ +name: rtd +channels: + - conda-forge + - defaults +dependencies: + - doxygen==1.9.6 + - sphinx==4.5.0 + - pip: + - exhale==0.3.6 + - breathe==4.35.0 + - sphinxcontrib.bibtex + - docutils==0.16 diff --git a/docs/grid_construction.rst b/docs/grid_construction.rst index 715e65f..dbfc062 100644 --- a/docs/grid_construction.rst +++ b/docs/grid_construction.rst @@ -1,3 +1,5 @@ +.. _grid-construction: + Grid construction ================= diff --git a/docs/index.rst b/docs/index.rst index cc3a453..6f29b32 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -22,12 +22,12 @@ If you use the library, please cite the following publication: wallmodelling grid_construction sampling + troubleshooting zzreferences - api/class_view_hierarchy.rst - api/file_view_hierarchy.rst + api/library_root .. important:: This offering is not approved or endorsed by OpenCFD Limited, producer and distributor of the OpenFOAM software and - owner of the OPENFOAM\ :sup:`®` and OpenCFD\ :sup:`®` trade marks. \ No newline at end of file + owner of the OPENFOAM\ :sup:`®` and OpenCFD\ :sup:`®` trade marks. diff --git a/docs/install.rst b/docs/install.rst index da5dd1d..5fe79b4 100644 --- a/docs/install.rst +++ b/docs/install.rst @@ -6,11 +6,11 @@ OpenFOAM version compatibility The libWMLES library supports two forks of OpenFOAM, developed by `OpenCFD `_, and the `OpenFOAM Foundation `_, repsectively. -Curently, all releases from OpenCFD up to v2212 are supported, as well as releases 3.0.x to 9 from the Foundation. +Curently, all releases from OpenCFD up to v2212 are supported, as well as releases 3.0.x to 7 from the Foundation. It should be stressed that *supported* means that it is checked that the library compiles. This should in principle entail that it also works properly, but due to time constraints and the ambitious number of versions suported, it is impossible to actually run test cases for all of them. -That being said, libWMLES has been extensively used with version 3.0.x, 4.1, and v1806 of OpenFOAM. +That being said, libWMLES has been extensively used with version 3.0.x, 4.1, v1806 and v1912 of OpenFOAM. Reports regarding difficulties with running a particular version are welcome: please open an issue on Bitbucket. The best level of testing is done for latest available release from OpenCFD, for which the test harness is run. @@ -18,10 +18,13 @@ This consists of unit and integration tests that aim to cover all the functional A single system test is also run, which is a simulation of channel flow on a coarse grid, using the Spalding-law wall model and otherwise default parameters in the :code:`nut` dictionary. -The aim is to support all new OpenCFD and Foundation releases, meaning that the amount of supported versions grows with -three per year. +The aim is to support all new OpenCFD, meaning that the amount of supported versions grows with +two per year. This is likely to become unsustainable, leading to deprecation of support for the oldest versions. +The support for new Foundation versions would be nice, but currently dropped due to lack of time and familiarity with the codebase. +Contributions from users of the Foundation version to provide support are most welcome. + Compilation ----------- @@ -29,6 +32,7 @@ Clone the repository with git or download it as an archive by navigating Downloa A prerequisite for installing is having Python installed, but no packages are needed and any modern Python version should do. To compile, run ``Allwmake``. +Consider using the ``-j`` flag with a number of processors, to speed up the process. If you get compilation errors, please make sure your OpenFOAM environment is properly set up before opening a Bitbucket issue. In particular, take notice of the first couple of lines in the output for ``Allwmake``, which are of the following diff --git a/docs/quickstart.rst b/docs/quickstart.rst index b41262f..2c053a2 100644 --- a/docs/quickstart.rst +++ b/docs/quickstart.rst @@ -24,26 +24,22 @@ following: type Spalding; } -* In your :code:`0` directory, you should add a new volScalarField, :code:`h`, see the :ref:`Sampling` section for details. - For a quick start, set the value of :code:`h` to :code:`uniform 0` at the wall, and use :code:`zeroGradient` at all +* In your :code:`0` directory, you should add a new volScalarField, :code:`hSampler`, see the :ref:`sampling` section for details. + For a quick start, set the value of :code:`hSampler` to :code:`uniform 0` at the wall, and use :code:`zeroGradient` at all non-wall patch boundaries. This will lead to sampling from the wall adjacent-cell, which is very robust, but inaccurate. The settings above are not optimal, but should get your case running. Of course, you should never run your WMLES on a wall-resolving mesh. -Instead, we recommend using a meshing strategy presented in :ref:`Grid construction`. +Instead, we recommend using a meshing strategy presented in :ref:`grid-construction`. Miscellaneous tips ------------------ -* In regions where the TBL is attached, set :code:`h` to be the distance to the second consecutive off-the-wall cell centre. +* In regions where the TBL is attached, set :code:`hSampler` to be the distance to the second consecutive off-the-wall cell centre. In other regions, set it to 0, i.e. sample from the wall-adjacent cell. * Use a mildly diffusive numerical scheme, e.g. :code:`LUST`. Tips regarding what other schemes worked well are welcome :). * The WALE model is a good first choice for SGS modelling. Don't use implicit LES on a WMLES mesh. -* If your simulation crashes because of the wall model (you can usually see that in the log), make sure you have a good - initial condition. -* If your simulation crashed anyway, use :math:`h = 0`, this is pretty much guaranteed to be stable. -* Large values of :math:`h` are known to sometimes lead to a crash, in particular, if the grid below :math:`h` is refined. * If you use :math:`h = 0`, use an algebraic wall model in integral formulation, i.e. the :code:`LOTWWallModel` with e.g. the :code:`IntegratedReichardt` law. @@ -58,4 +54,4 @@ These can serve as good examples on how to setup your simulation! - WMLES of channel flow and flow over a backward-facing step. https://doi.org/10.6084/m9.figshare.6790013.v1 - WMLES of a flat-plate TBL using unstructured grids. - https://doi.org/10.6084/m9.figshare.6061298.v2 \ No newline at end of file + https://doi.org/10.6084/m9.figshare.6061298.v2 diff --git a/docs/requirements.txt b/docs/requirements.txt index 7b41be2..5eadfbe 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,4 +1,4 @@ -exhale +exhale>=0.3.0 sphinxcontrib.bibtex docutils==0.16 -sphinx==3.3.1 +sphinx==4.5.0 diff --git a/docs/sampling.rst b/docs/sampling.rst index 4ae54da..ebfd77d 100644 --- a/docs/sampling.rst +++ b/docs/sampling.rst @@ -1,3 +1,5 @@ +.. _sampling: + Sampling ======== @@ -42,19 +44,19 @@ We encourage the users to examine :code:`SamplingCells` to confirm that the cell Prescribing :math:`h` --------------------- -The values of :math:`h` should be set in a field called :code:`h`. +The values of :math:`h` should be set in a field called :code:`hSampler`. The setting of appropriate values is done in the same way as for any other solution field. -To that end, at the wall boundaries, the boundary condition for :code:`h` should be set to :code:`fixedValue`. +To that end, at the wall boundaries, the boundary condition for :code:`hSampler` should be set to :code:`fixedValue`. The desired values are then either set for the whole patch using the :code:`uniform` keyword or alternatively prescribed on a face-by-face basis using an OpenFOAM list. On other boundaries of type :code:`patch`, the :code:`zeroGradient` boundary condition can be used. -When the :code:`Tree` sampler is used, the values in the :code:`h` will be interpreted as the desired distance to the +When the :code:`Tree` sampler is used, the values in the :code:`hSampler` will be interpreted as the desired distance to the sampling point. Note, that the value 0 is reserved for sampling from the wall-adjacent cell. By default, the same will be done by the :code:`Crawling` sampler, however alternatively one can let the sampler interpret the set values as the index of the consecutive off-wall cell, from which to do the sampling. -So, for example, :code:`h` equal to 2 will refer to sampling from the second off-wall cell. +So, for example, :code:`hSampler` equal to 2 will refer to sampling from the second off-wall cell. In order to do this, the :code:`hIsIndex` keyword should be set to :code:`yes` in the dictionary of the wall model in :code:`nut`. diff --git a/docs/troubleshooting.rst b/docs/troubleshooting.rst new file mode 100644 index 0000000..653a01a --- /dev/null +++ b/docs/troubleshooting.rst @@ -0,0 +1,31 @@ +.. _troubleshooting + +Troubleshooting +=============== + +The number 1 cause of the case crashing is the divergence in the Newton solver +used in algebraic models. +Look at the error trace, does crash occur in a function called :code:`value` or +:code:`derivative`? +Then it is the Newton solver. + +The divergence occurs due to a bad velocity value being sampled to the wall model. +This typically occurs due to bad (e.g. uniform) initial conditions. +The remedy is therefore to run your case for a bit without wall modelling to get +a reasonable initial field and then turn on the wall model. + +However, often one can also run with :code:`hSampler` set to 0, i.e. sampling +from the near-wall cell. +This tends to be very stable. + +If your case crashes anyway, try setting :code:`copyToPatchInternalField` to 1 +in the boundary condition configuration. +This copies the wall value of the viscosity to the near-wall cell. +This a trick, but it tends to stabilize the velocity value in the near-wall cell. +This should certainly be used id you see that your wall :code:`nut` values are +starting to climb up unreasonably. +The latter is, in fact, how ODE models "diverge", even if the case will be +able to run for a long time. + +Finally, don't refine the mesh towards the wall, at least not a lot. +This tends to lead to less stable simulations and won't improve the accuracy. \ No newline at end of file diff --git a/docs/wallmodelling.rst b/docs/wallmodelling.rst index 9798281..3c9ed20 100644 --- a/docs/wallmodelling.rst +++ b/docs/wallmodelling.rst @@ -48,15 +48,16 @@ Algebraic models These are essentially wall functions: some law of the wall is used to connect the sampled LES solution to the wall shear stress. -Implemented in the library as the :code:`LOTWWallModelFvPatchScalarField` class, see its documentation for further +Implemented in the library as the :class:`Foam::LOTWWallModelFvPatchScalarField` class, see its documentation for further details. A multitude of laws of the wall are implemented: -- Spalding's law, :code:`SpaldingLawOfTheWall.H` -- Reichard's law, :code:`ReichardtLawOfTheWall.H`. -- Werner & Wengel's law, :code:`WernerWengleLawOfTheWall`. -- Integrated Reichard's law, :code:`IntegratedReichardtLawOfTheWall.H`. -- Integrated Werner & Wengel's law, :code:`IntegratedWernerWengleLawOfTheWall`. +- Spalding's law, :class:`Foam::SpaldingLawOfTheWall` +- Reichard's law, :class:`Foam::ReichardtLawOfTheWall`. +- Werner & Wengel's law, :class:`Foam::WernerWengleLawOfTheWall`. +- Integrated Reichard's law, :class:`Foam::IntegratedReichardtLawOfTheWall`. +- Integrated Werner & Wengel's law, :class:`Foam::IntegratedWernerWengleLawOfTheWall`. +- Log law for rough walls, :class:`Foam::RoughLogLawOfTheWall`. The integrated versions are preferable if you use the wall-adjacent cell for sampling. Otherwise, there is no large difference in what law to use, and Spalding's law is a reasonable default choice. @@ -68,12 +69,12 @@ ODE-based models These models are based on an ODE formulation, yet the ODE is integrated, and the model therefore only performs numerical integration using the trapezoidal rule, and does not solve and ODE directly. The models differ in the treatment of the right-hand side of the underlying ODE. -For more details see the :code:`ODEWallModelFvPatchScalarField` class. +For more details see the :class:`Foam::ODEWallModelFvPatchScalarField` class. The following models are available -- Equilibrium ODE model, :code:`EquilibriumODEWallModelFvPatchScalarField.H`. Right-hand side of the ODE is set to 0. -- Pressure gradient ODE model, :code:`PGradODEWallModelFvPatchScalarField.H` the right-hand side is set equal to the pressure gradient. +- Equilibrium ODE model, :class:`Foam::EquilibriumODEWallModelFvPatchScalarField`. Right-hand side of the ODE is set to 0. +- Pressure gradient ODE model, :class:`Foam::PGradODEWallModelFvPatchScalarField` the right-hand side is set equal to the pressure gradient. Further reading diff --git a/eddyViscosities/Duprat/DupratEddyViscosity.H b/eddyViscosities/Duprat/DupratEddyViscosity.H index bed9852..4fe7d4c 100644 --- a/eddyViscosities/Duprat/DupratEddyViscosity.H +++ b/eddyViscosities/Duprat/DupratEddyViscosity.H @@ -19,7 +19,7 @@ License Class Foam::DupratEddyViscosity -Description +@brief Eddy viscosity model based on the work of Duprat et al. [Duprat]. \f[ diff --git a/eddyViscosities/EddyViscosity/EddyViscosity.H b/eddyViscosities/EddyViscosity/EddyViscosity.H index 97cd23c..28a012b 100644 --- a/eddyViscosities/EddyViscosity/EddyViscosity.H +++ b/eddyViscosities/EddyViscosity/EddyViscosity.H @@ -19,7 +19,7 @@ License Class Foam::EddyViscosity -Description +@brief Base abstract class for 1D turbulence models based on eddy viscosity. Meant to be used with ODE based wall models that need the distribution diff --git a/eddyViscosities/VanDriest/VanDriestEddyViscosity.H b/eddyViscosities/VanDriest/VanDriestEddyViscosity.H index ae6df1f..67346c3 100644 --- a/eddyViscosities/VanDriest/VanDriestEddyViscosity.H +++ b/eddyViscosities/VanDriest/VanDriestEddyViscosity.H @@ -19,7 +19,7 @@ License Class Foam::VanDriestEddyViscosity -Description +@brief A mixing-length based eddy viscosity model using a van Driest damping function. Corresponds to the formulation used by Cabot in [Cabot]. diff --git a/helpers/helpers.H b/helpers/helpers.H index 52b0e32..71c657a 100644 --- a/helpers/helpers.H +++ b/helpers/helpers.H @@ -19,7 +19,7 @@ License Class Foam::PatchProjector -Description +@brief Class for projecting fields and lists onto a patch. Contributors/Copyright: diff --git a/lawsOfTheWall/IntegratedReichardtLawOfTheWall/IntegratedReichardtLawOfTheWall.C b/lawsOfTheWall/IntegratedReichardtLawOfTheWall/IntegratedReichardtLawOfTheWall.C index 7d77f02..5661c98 100644 --- a/lawsOfTheWall/IntegratedReichardtLawOfTheWall/IntegratedReichardtLawOfTheWall.C +++ b/lawsOfTheWall/IntegratedReichardtLawOfTheWall/IntegratedReichardtLawOfTheWall.C @@ -136,6 +136,39 @@ Foam::scalar Foam::IntegratedReichardtLawOfTheWall::value } +Foam::scalar Foam::IntegratedReichardtLawOfTheWall::valueMulticell +( + + const MultiCellSampler & sampler, + label index, + scalar uTau, + scalar nu +) const +{ + const scalarListList & U = + sampler.db().lookupObject("U")[index]; + + + scalarList h = sampler.h()[index]; + scalarList l = sampler.lengthList()[index]; + + // Compute cell-length weighted mean of u across sampling cells + scalar uMean = 0; + + for(int i=0; i < h.size(); i++) + { + uMean += l[i]*mag(vector(U[i][0], U[i][1], U[i][2])); + } + + scalar h1 = mag(h[0] - l[0]/2); + scalar h2 = h[h.size()-1] + l[h.size()-1]/2; + + uMean = uMean/(h2 - h1); + + return value(uMean, h1, h2, uTau, nu); +} + + Foam::scalar Foam::IntegratedReichardtLawOfTheWall::value ( scalar u, @@ -169,54 +202,35 @@ Foam::scalar Foam::IntegratedReichardtLawOfTheWall::derivative } -Foam::scalar Foam::IntegratedReichardtLawOfTheWall::derivative +Foam::scalar Foam::IntegratedReichardtLawOfTheWall::derivativeMulticell ( - scalar h1, - scalar h2, + const MultiCellSampler & sampler, + label index, scalar uTau, scalar nu ) const { - return -(logTermDerivative(h2, uTau, nu) - logTermDerivative(h1, uTau, nu) + - expTermDerivative(h2, uTau, nu) - expTermDerivative(h1, uTau, nu)); + scalarList h = sampler.h()[index]; + scalar h1 = mag(h[0] - sampler.lengthList()[index][0]/2); + scalar h2 = h[h.size()-1] + + sampler.lengthList()[index][h.size()-1]/2; + + return derivative(h1, h2, uTau, nu); } -Foam::scalar Foam::IntegratedReichardtLawOfTheWall::value +Foam::scalar Foam::IntegratedReichardtLawOfTheWall::derivative ( - - const MultiCellSampler & sampler, - label index, + scalar h1, + scalar h2, scalar uTau, - scalar nu + scalar nu ) const -{ - - const scalarListList U = sampler.db().lookupObject("U")[index]; - const scalarList lengthList = sampler.lengthList()[index]; - const scalarList h = sampler.h()[index]; - - - // The integrated value of U from h1 to h2 - scalar integratedU = 0; - - - forAll (lengthList, i) - { - const scalar h1 = mag(h[i] - lengthList[i]/2); - const scalar h2 = h[i] + lengthList[i]/2; - const scalar u = mag(vector(U[i][0], U[i][1], U[i][2])); - integratedU += (h2 - h1)*u; - } - - const scalar h1 = h[0] - lengthList[0]/2; - const scalar h2 = h[h.size()] + lengthList[h.size()]/2; - return integratedU - (logTerm(h2, uTau, nu) - logTerm(h1, uTau, nu) + - expTerm(h2, uTau, nu) - expTerm(h1, uTau, nu)); - +{ + return -(logTermDerivative(h2, uTau, nu) - logTermDerivative(h1, uTau, nu) + + expTermDerivative(h2, uTau, nu) - expTermDerivative(h1, uTau, nu)); } - Foam::scalar Foam::IntegratedReichardtLawOfTheWall::logTerm ( scalar y, diff --git a/lawsOfTheWall/IntegratedReichardtLawOfTheWall/IntegratedReichardtLawOfTheWall.H b/lawsOfTheWall/IntegratedReichardtLawOfTheWall/IntegratedReichardtLawOfTheWall.H index e65adb9..f8704a7 100644 --- a/lawsOfTheWall/IntegratedReichardtLawOfTheWall/IntegratedReichardtLawOfTheWall.H +++ b/lawsOfTheWall/IntegratedReichardtLawOfTheWall/IntegratedReichardtLawOfTheWall.H @@ -19,7 +19,7 @@ License Class Foam::IntegratedReichardtLawOfTheWall -Description +@brief Model based on integrating the law of the wall proposed by Reichardt. \f[ @@ -116,10 +116,10 @@ public: //- Construct from model constants IntegratedReichardtLawOfTheWall ( - const scalar kappa, - const scalar B1, - const scalar B2, - const scalar C + const scalar kappa=0.4, + const scalar B1=11, + const scalar B2=3, + const scalar C=7.8 ); // Destructor @@ -184,9 +184,17 @@ public: scalar nu ) const override; + scalar valueMulticell + ( + const MultiCellSampler & sampler, + label index, + scalar uTau, + scalar nu + ) const; + scalar value ( - scalar u, + scalar uIntegral, scalar h1, scalar h2, scalar uTau, @@ -204,20 +212,19 @@ public: scalar nu ) const override; - scalar - derivative + scalar derivativeMulticell ( - scalar h1, - scalar h2, + const MultiCellSampler & sampler, + label index, scalar uTau, scalar nu ) const; - //- Return the value of the implicit function defining the law - virtual scalar value + scalar + derivative ( - const MultiCellSampler & sampler, - label index, + scalar h1, + scalar h2, scalar uTau, scalar nu ) const; diff --git a/lawsOfTheWall/IntegratedWernerWengleLawOfTheWall/IntegratedWernerWengleLawOfTheWall.H b/lawsOfTheWall/IntegratedWernerWengleLawOfTheWall/IntegratedWernerWengleLawOfTheWall.H index c8937cc..90ba0cb 100644 --- a/lawsOfTheWall/IntegratedWernerWengleLawOfTheWall/IntegratedWernerWengleLawOfTheWall.H +++ b/lawsOfTheWall/IntegratedWernerWengleLawOfTheWall/IntegratedWernerWengleLawOfTheWall.H @@ -19,7 +19,7 @@ License Class Foam::IntegratedWernerWengleLawOfTheWall -Description +@brief The integrated version of the wall proposed by Werner and Wengle. Explicitely couples shear stress with the wall-normal-averaged velocity. Derived assuming that the sampling is from the wall-adjacent cell. @@ -28,8 +28,7 @@ Description \f{eqnarray*}{ u^+ &=& y^+ \quad y+ \leq 11.81\\ - u^+ &=& A(y^+)^B \quad y+ > 11.81 - + u^+ &=& A(y^+)^B \quad y^+ > 11.81 \f} Usage: diff --git a/lawsOfTheWall/LawOfTheWall/LawOfTheWall.H b/lawsOfTheWall/LawOfTheWall/LawOfTheWall.H index 49c9e52..cf250f3 100644 --- a/lawsOfTheWall/LawOfTheWall/LawOfTheWall.H +++ b/lawsOfTheWall/LawOfTheWall/LawOfTheWall.H @@ -19,7 +19,7 @@ License Class Foam::LawOfTheWall -Description +@brief Base abstract class for laws of the wall. It is to be used in conjuction diff --git a/lawsOfTheWall/ReichardtLawOfTheWall/ReichardtLawOfTheWall.H b/lawsOfTheWall/ReichardtLawOfTheWall/ReichardtLawOfTheWall.H index c4f9e94..4d085db 100644 --- a/lawsOfTheWall/ReichardtLawOfTheWall/ReichardtLawOfTheWall.H +++ b/lawsOfTheWall/ReichardtLawOfTheWall/ReichardtLawOfTheWall.H @@ -19,7 +19,7 @@ License Class Foam::ReichardtLawOfTheWall -Description +@brief The law of the wall proposed by Reichardt. \f[ diff --git a/lawsOfTheWall/RoughLogLawOfTheWall/RoughLogLawOfTheWall.C b/lawsOfTheWall/RoughLogLawOfTheWall/RoughLogLawOfTheWall.C new file mode 100644 index 0000000..cf76699 --- /dev/null +++ b/lawsOfTheWall/RoughLogLawOfTheWall/RoughLogLawOfTheWall.C @@ -0,0 +1,158 @@ +/*---------------------------------------------------------------------------* \ +License + This file is part of libWallModelledLES. + + libWallModelledLES is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + libWallModelledLES is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with libWallModelledLES. + If not, see . + + \*---------------------------------------------------------------------------*/ + +#include "RoughLogLawOfTheWall.H" +#include "addToRunTimeSelectionTable.H" +#include "volFields.H" +#include "scalarListIOList.H" +#include "SingleCellSampler.H" +#include "codeRules.H" + +#if !defined(DOXYGEN_SHOULD_SKIP_THIS) +namespace Foam +{ + defineTypeNameAndDebug(RoughLogLawOfTheWall, 0); + addToRunTimeSelectionTable(LawOfTheWall, RoughLogLawOfTheWall, Dictionary); + addToRunTimeSelectionTable(LawOfTheWall, RoughLogLawOfTheWall, TypeAndDictionary); + +} +#endif + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::RoughLogLawOfTheWall::RoughLogLawOfTheWall +( + const dictionary & dict +) +: + LawOfTheWall(dict), + kappa_(constDict_.lookupOrAddDefault("kappa", 0.4)), +#ifdef FOAM_DICTIONARY_NO_GET +#ifdef FOAM_DICTIONARY_HAS_LOOKUP + B_(constDict_.lookup("B")), + ks_(constDict_.lookup("ks")) +#else + B_(constDict_.lookupType("B")), + ks_(constDict_.lookupType("ks")) +#endif +#else + B_(constDict_.get("B")), + ks_(constDict_.get("ks")) +#endif +{ + if (debug) + { + printCoeffs(); + } +} + + +Foam::RoughLogLawOfTheWall::RoughLogLawOfTheWall +( + const word & lawName, + const dictionary & dict +) +: + RoughLogLawOfTheWall(dict) +{ +} + + +Foam::RoughLogLawOfTheWall::RoughLogLawOfTheWall +( + const scalar kappa, + const scalar B, + const scalar ks +) +: + LawOfTheWall(), + kappa_(kappa), + B_(B), + ks_(ks) +{ + constDict_.add("kappa", kappa); + constDict_.add("B", B); + constDict_.add("ks", ks_); + + if (debug) + { + printCoeffs(); + } + +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::RoughLogLawOfTheWall::printCoeffs() const +{ + Info<< nl << "RoughLogLaw law of the wall" << nl; + Info<< token::BEGIN_BLOCK << incrIndent << nl; + Info<< indent << "kappa" << indent << kappa_ << nl; + Info<< indent << "B" << indent << B_ << nl; + Info<< indent << "ks" << indent << ks_ << nl; + Info<< token::END_BLOCK << nl << nl; +} + +Foam::scalar Foam::RoughLogLawOfTheWall::value +( + const SingleCellSampler & sampler, + label index, + scalar uTau, + scalar nu +) const +{ + const scalarListIOList & U = sampler.db().lookupObject("U"); + + scalar u = mag(vector(U[index][0], U[index][1], U[index][2])); + scalar y = sampler.h()[index]; + return value(u, y, uTau, nu); +} + +Foam::scalar Foam::RoughLogLawOfTheWall::value +( + scalar u, + scalar y, + scalar uTau, + scalar nu +) const +{ + scalar denom = 1/kappa_*log(y/ks_) + B_; + return uTau - u/denom; +} + +Foam::scalar Foam::RoughLogLawOfTheWall::derivative +( + const SingleCellSampler & sampler, + label index, + scalar uTau, + scalar nu +) const +{ + return 1; +} + +Foam::scalar Foam::RoughLogLawOfTheWall::derivative() const +{ + return 1; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + diff --git a/lawsOfTheWall/RoughLogLawOfTheWall/RoughLogLawOfTheWall.H b/lawsOfTheWall/RoughLogLawOfTheWall/RoughLogLawOfTheWall.H new file mode 100644 index 0000000..9f52448 --- /dev/null +++ b/lawsOfTheWall/RoughLogLawOfTheWall/RoughLogLawOfTheWall.H @@ -0,0 +1,176 @@ +/*---------------------------------------------------------------------------* \ +License + This file is part of libWallModelledLES. + + libWallModelledLES is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + libWallModelledLES is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with libWallModelledLES. + If not, see . + +Class + Foam::RoughLogLawOfTheWall + +@brief + A log-law, in which the wall-normal distance is scaled by roughness + length-scale. + + \f[ + u^+ = 1/\kappa \log \left( y/k_s \right) + B + \f] + + Since the formula above provides an explicit value for the friction velocity + Newton's method will converge in a single iteration. + + Usage: + \verbatim + Law + { + type RoughLogLaw; + kappa value; (default 0.4) + B value; + ks value; + } + \endverbatim + +Contributors/Copyright: + 2019-2023 Timofey Mukha + +SourceFiles + RoughLogLawOfTheWall.C + +\*---------------------------------------------------------------------------*/ + +#ifndef RoughLogLawOfTheWall_H +#define RoughLogLawOfTheWall_H + +#include "LawOfTheWall.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class RoughLogLawOfTheWall Declaration +\*---------------------------------------------------------------------------*/ + +class RoughLogLawOfTheWall: public LawOfTheWall +{ + + // Private data + + //- The kappa model constant + scalar kappa_; + + //- The B model constant + scalar B_; + + //- The roughness length-scale + scalar ks_; + +public: + +#if !defined(DOXYGEN_SHOULD_SKIP_THIS) + TypeName("RoughLogLaw"); +#endif + + // Constructors + + //- Construct provided dictionary + RoughLogLawOfTheWall(const dictionary &); + + //- Construct provided TypeName and dictionary + RoughLogLawOfTheWall + ( + const word & lawname, + const dictionary & + ); + + //- Construct from model constants + RoughLogLawOfTheWall + ( + const scalar kappa, + const scalar B, + const scalar ks + ); + + //- Copy constructor + RoughLogLawOfTheWall(const RoughLogLawOfTheWall &) = default; + + //- Assignment + RoughLogLawOfTheWall & operator=(const RoughLogLawOfTheWall &) = default; + + //- Clone + virtual autoPtr clone() const override + { + return autoPtr + ( + new RoughLogLawOfTheWall(*this) + ); + } + + //- Destructor + virtual ~RoughLogLawOfTheWall() {}; + + // Member Functions + + scalar kappa() const + { + return kappa_; + } + + scalar B() const + { + return B_; + } + + scalar ks() const + { + return ks_; + } + + //- Print the model coefficients to terminal + virtual void printCoeffs() const override; + + //- Return the value of the implicit function defining the law + virtual scalar value + ( + const SingleCellSampler & sampler, + label index, + scalar uTau, + scalar nu + ) const override; + + scalar value(scalar u, scalar y, scalar uTau, scalar nu) const; + + + //- Return the value of the derivative of the implicit function + // defining the law. + virtual scalar derivative + ( + const SingleCellSampler & sampler, + label index, + scalar uTau, + scalar nu + ) const override; + + scalar derivative() const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif diff --git a/lawsOfTheWall/SpaldingLawOfTheWall/SpaldingLawOfTheWall.H b/lawsOfTheWall/SpaldingLawOfTheWall/SpaldingLawOfTheWall.H index 423d795..df93b94 100644 --- a/lawsOfTheWall/SpaldingLawOfTheWall/SpaldingLawOfTheWall.H +++ b/lawsOfTheWall/SpaldingLawOfTheWall/SpaldingLawOfTheWall.H @@ -19,7 +19,7 @@ License Class Foam::SpaldingLawOfTheWall -Description +@brief The law of the wall proposed by Spalding. \f[ diff --git a/lawsOfTheWall/WernerWengleLawOfTheWall/WernerWengleLawOfTheWall.H b/lawsOfTheWall/WernerWengleLawOfTheWall/WernerWengleLawOfTheWall.H index c7db67e..ceba696 100644 --- a/lawsOfTheWall/WernerWengleLawOfTheWall/WernerWengleLawOfTheWall.H +++ b/lawsOfTheWall/WernerWengleLawOfTheWall/WernerWengleLawOfTheWall.H @@ -19,15 +19,14 @@ License Class Foam::WernerWengleLawOfTheWall -Description +@brief The law of the wall proposed by Werner and Wengle. Note that the model in the reference uses the integrated version of this law, also present in the library. \f{eqnarray*}{ - u^+ &=& y^+ \quad y+ \leq 11.81\\ - u^+ &=& A(y^+)^B \quad y+ > 11.81 - + u^+ &=& y^+ \quad y^+ \leq 11.81\\ + u^+ &=& A(y^+)^B \quad y^+ > 11.81 \f} Usage: diff --git a/rootFinding/BisectionRootFinder/BisectionRootFinder.H b/rootFinding/BisectionRootFinder/BisectionRootFinder.H index c08b8b8..f1233ec 100644 --- a/rootFinding/BisectionRootFinder/BisectionRootFinder.H +++ b/rootFinding/BisectionRootFinder/BisectionRootFinder.H @@ -19,7 +19,7 @@ License Class Foam::BisectionRootFinder -Description +@brief Root finder based on the bisection method. Controlled by three paramters: diff --git a/rootFinding/NewtonRootFinder/NewtonRootFinder.H b/rootFinding/NewtonRootFinder/NewtonRootFinder.H index e38900f..73605e1 100644 --- a/rootFinding/NewtonRootFinder/NewtonRootFinder.H +++ b/rootFinding/NewtonRootFinder/NewtonRootFinder.H @@ -19,7 +19,7 @@ License Class Foam::NewtonRootFinder -Description +@brief Root finder based on Newton's method. Controlled by two parameters: the max number of iterations and the relative diff --git a/rootFinding/RootFinder/RootFinder.H b/rootFinding/RootFinder/RootFinder.H index 015889f..dae8999 100644 --- a/rootFinding/RootFinder/RootFinder.H +++ b/rootFinding/RootFinder/RootFinder.H @@ -19,7 +19,7 @@ License Class Foam::RootFinder -Description +@brief Base abstract class for finding roots of non-linear algebraic equations. In the context of wall modelling the latter are provided by laws of the diff --git a/samplers/MultiCellSampler/MultiCellSampler.C b/samplers/MultiCellSampler/MultiCellSampler.C index 767a337..005957b 100644 --- a/samplers/MultiCellSampler/MultiCellSampler.C +++ b/samplers/MultiCellSampler/MultiCellSampler.C @@ -35,6 +35,8 @@ License #include "scalarListListIOList.H" #include "TreeCellFinder.H" #include "CrawlingCellFinder.H" +#include "Sampler.H" +#include "surfaceMesh.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -52,10 +54,21 @@ namespace Foam void Foam::MultiCellSampler::createIndexList() { const label patchIndex = patch().index(); - + + word hName; + // Grab h for the current patch + if (mesh_.foundObject("hSampler")) + { + hName = "hSampler"; + } + else + { + hName = "h"; + } + volScalarField & hField = - const_cast(mesh_.lookupObject ("h")); + const_cast(mesh_.lookupObject (hName)); scalarField hPatch = hField.boundaryField()[patchIndex]; @@ -150,7 +163,20 @@ void Foam::MultiCellSampler::createIndexList() } } -void Foam::MultiCellSampler::createLengthList() +void Foam::MultiCellSampler::createLengthList(const word lengthScaleType) +{ + if (lengthScaleType == "CubeRootVol") + { + createLengthListCubeRootVol(); + } + else if (lengthScaleType == "WallNormalDistance") + { + createLengthListWallNormalDistance(); + } + +} + +void Foam::MultiCellSampler::createLengthListCubeRootVol() { // Cell volumes const scalarField & V = mesh_.V(); @@ -164,7 +190,48 @@ void Foam::MultiCellSampler::createLengthList() lengthList_[i][j] = pow(V[indexList_[i][j]], 1.0/3.0); } } - +} + +void Foam::MultiCellSampler::createLengthListWallNormalDistance() +{ + const vectorField & faceCentres = mesh().Cf().primitiveField(); + const List & cells = mesh().cells(); + const vectorField & patchFaceCentres = patch().Cf(); + const List & faces = mesh().faces(); + forAll(lengthList_, i) + { + lengthList_[i] = scalarList(indexList_[i].size()); + const vector patchFaceI = patchFaceCentres[i]; + + forAll(lengthList_[i], j) + { + const label index = indexList_[i][j]; + const cell cellI = cells[index]; + + scalar minDist = GREAT; + label minDistFace = 0; + + for (int k=0; k > interpolator_; + //- Interpolation type + const word interpolationType_; public: +#if !defined(DOXYGEN_SHOULD_SKIP_THIS) + //- Runtime type information + TypeName("SampledField"); +#endif + // Constructors //- Construct from patch and interpolation type @@ -76,7 +81,7 @@ public: : patch_(patch), mesh_(patch_.boundaryMesh().mesh()), - interpolator_(nullptr) + interpolationType_(interpolationType) { } @@ -89,7 +94,7 @@ public: patch_(orig.patch()), mesh_(orig.mesh()), // #ifdef FOAM_AUTOPTR_HAS_CLONE_METHOD - interpolator_(nullptr) + interpolationType_(orig.interpolationType()) // #else // interpolator_(orig.interpolator_, false) // #endif @@ -158,11 +163,14 @@ public: //- Recompute the values of the field virtual void recompute() const = 0; - //- Set interplator - virtual void setInterpolator(const word interpolationType) = 0; - //- Create the global field that will be sampled virtual void createField() const = 0; + + //- Get interpolation type + word interpolationType() const + { + return interpolationType_; + } }; diff --git a/samplers/SampledField/SampledPGradField.C b/samplers/SampledField/SampledPGradField.C index f0ddfcc..71dcae8 100644 --- a/samplers/SampledField/SampledPGradField.C +++ b/samplers/SampledField/SampledPGradField.C @@ -24,6 +24,15 @@ License #include "List.H" #include "helpers.H" +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#if !defined(DOXYGEN_SHOULD_SKIP_THIS) +namespace Foam +{ + defineTypeNameAndDebug(SampledPGradField, 0); +} +#endif + // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // void Foam::SampledPGradField::sample @@ -33,18 +42,29 @@ void Foam::SampledPGradField::sample const Foam::scalarField & h ) const { - Info<< "Sampling pressure gradient for patch " << patch_.name() << nl; + if (debug) + { + Info<< "Sampling pressure gradient for patch " << patch_.name() << nl; + } const vectorField & faceCentres = patch().Cf(); const tmp tfaceNormals = patch().nf(); const vectorField & faceNormals = tfaceNormals(); + const volVectorField & pGradField = + mesh().lookupObject("pGrad"); + autoPtr > interpolator; + interpolator.operator= + ( + interpolation::New(interpolationType(), pGradField) + ); + vectorField sampledPGrad(indexList.size()); for (int i=0; iinterpolate(p, indexList[i]); + const vector interp = interpolator->interpolate(p, indexList[i]); sampledPGrad[i] = interp; scalarList temp(3, 0.0); @@ -205,37 +225,23 @@ void Foam::SampledPGradField::recompute() const } -void Foam::SampledPGradField::setInterpolator +void Foam::SampledPGradField::createField ( - const word interpolationType -) +) const { - if (mesh().foundObject("pGrad")) + word hName; + + // Grab h for the current patch + if (mesh_.foundObject("hSampler")) { - const volVectorField & pGrad = - mesh().lookupObject("pGrad"); - interpolator_.operator= - ( - interpolation::New(interpolationType, pGrad) - ); + hName = "hSampler"; } else { - interpolator_.reset(nullptr); - // WarningIn("SampledPGradField::setInterpolator()") - // << "No pGrad field is present, attempting to sample will lead " - // << "to a crash." - // << nl; + hName = "h"; } -} - -void Foam::SampledPGradField::createField -( -) const -{ - // Grab h to copy bcs from it. - const volScalarField & h = mesh().lookupObject("h"); + const volScalarField & h = mesh_.lookupObject (hName); if (!mesh().foundObject("pGrad")) { diff --git a/samplers/SampledField/SampledPGradField.H b/samplers/SampledField/SampledPGradField.H index 64853e2..7f97b8c 100644 --- a/samplers/SampledField/SampledPGradField.H +++ b/samplers/SampledField/SampledPGradField.H @@ -19,11 +19,11 @@ License Class Foam::SampledPGradField -Description +@brief Class for the sampled pressure gradient field. Contributors/Copyright: - 2018-2021 Timofey Mukha + 2018-2023 Timofey Mukha SourceFiles SampledPGradField.C @@ -50,6 +50,10 @@ class SampledPGradField { public: +#if !defined(DOXYGEN_SHOULD_SKIP_THIS) + //- Runtime type information + TypeName("SampledPGradField"); +#endif // Constructors @@ -63,19 +67,13 @@ public: SampledField(patch, interpolationType) { createField(); - setInterpolator(interpolationType); } //- Copy constructor SampledPGradField(const SampledPGradField & orig) : SampledField(orig) - { - if (orig.interpolator_.valid()) - { - setInterpolator(orig.interpolator_().type()); - } - } + {} //- Clone the object autoPtr clone() const override @@ -129,9 +127,6 @@ public: //- Recompute the field void recompute() const override; - //- Reset the interpolator - void setInterpolator(const word interpolationType) override; - //- Create the global pressure gradient field that will be sampled virtual void createField() const override; }; diff --git a/samplers/SampledField/SampledVelocityField.C b/samplers/SampledField/SampledVelocityField.C index 8eb8afa..0bde999 100644 --- a/samplers/SampledField/SampledVelocityField.C +++ b/samplers/SampledField/SampledVelocityField.C @@ -22,6 +22,15 @@ License #include "volFields.H" #include "helpers.H" #include "interpolation.H" +// +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#if !defined(DOXYGEN_SHOULD_SKIP_THIS) +namespace Foam +{ + defineTypeNameAndDebug(SampledVelocityField, 0); +} +#endif // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // @@ -33,7 +42,10 @@ void Foam::SampledVelocityField::sample const Foam::scalarField & h ) const { - Info<< "Sampling velocity for patch " << patch_.name() << nl; + if (debug) + { + Info<< "Sampling velocity for patch " << patch_.name() << nl; + } const vectorField & faceCentres = patch().Cf(); const tmp tfaceNormals = patch().nf(); @@ -44,11 +56,17 @@ void Foam::SampledVelocityField::sample vectorField sampledU(indexList.size()); + autoPtr > interpolator; + interpolator.operator= + ( + interpolation::New(interpolationType(), UField) + ); + for (int i=0; iinterpolate(p, indexList[i]); + const vector interp = interpolator->interpolate(p, indexList[i]); sampledU[i] = interp - Uwall[i]; scalarList temp(3, 0.0); @@ -82,7 +100,6 @@ void Foam::SampledVelocityField::sample { scalarList temp(3, 0.0); - //Info << i << " " << j << " " << UField[indexList[i][j]] - Uwall[i] << nl for (int k=0; k<3; k++) { temp[k] = @@ -198,30 +215,4 @@ void Foam::SampledVelocityField::registerFields } - -void Foam::SampledVelocityField::setInterpolator -( - word interpolationType -) -{ - if (mesh().foundObject("U")) - { - const volVectorField & U = - mesh().lookupObject("U"); - interpolator_.operator= - ( - interpolation::New(interpolationType, U) - ); - } - else - { - interpolator_.reset(nullptr); - // WarningIn("SampledVelocityField::setInterpolator()") - // << "No U field is present, attempting to sample will lead " - // << "to a crash." - // << nl; - } - -} - // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/samplers/SampledField/SampledVelocityField.H b/samplers/SampledField/SampledVelocityField.H index 2c8d614..ac8c8ab 100644 --- a/samplers/SampledField/SampledVelocityField.H +++ b/samplers/SampledField/SampledVelocityField.H @@ -19,11 +19,11 @@ License Class Foam::SampledVelocityField -Description +@brief Class for the sampled velocity field. Contributors/Copyright: - 2019-2021 Timofey Mukha + 2019-2023 Timofey Mukha SourceFiles SampledVelocityField.C @@ -52,6 +52,10 @@ class SampledVelocityField { public: +#if !defined(DOXYGEN_SHOULD_SKIP_THIS) + //- Runtime type information + TypeName("SampledVelocityField"); +#endif // Constructors @@ -65,18 +69,12 @@ public: SampledField(patch, interpolationType) { createField(); - setInterpolator(interpolationType); } SampledVelocityField(const SampledVelocityField & orig) : SampledField(orig) - { - if (orig.interpolator_.valid()) - { - setInterpolator(orig.interpolator_().type()); - } - } + {} //- Clone the object autoPtr clone() const override { @@ -133,9 +131,6 @@ public: //- Recompute the field void recompute() const override {} - //- Set the inerpolator - void setInterpolator(const word interpolationType) override; - //- Create the field. Redunant, U should be created by the solver. void createField() const override {} }; diff --git a/samplers/SampledField/SampledWallGradUField.C b/samplers/SampledField/SampledWallGradUField.C index e932a05..9fd488f 100644 --- a/samplers/SampledField/SampledWallGradUField.C +++ b/samplers/SampledField/SampledWallGradUField.C @@ -22,6 +22,15 @@ License #include "volFields.H" #include "codeRules.H" #include "helpers.H" +// +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#if !defined(DOXYGEN_SHOULD_SKIP_THIS) +namespace Foam +{ + defineTypeNameAndDebug(SampledWallGradUField, 0); +} +#endif // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // @@ -34,8 +43,11 @@ Foam::SampledWallGradUField::sample const Foam::scalarField & h ) const { - Info<< "Sampling wall-normal velocity gradient for patch " - << patch_.name() << nl; + if (debug) + { + Info<< "Sampling wall-normal velocity gradient for patch " + << patch_.name() << nl; + } label pI = patch().index(); @@ -224,8 +236,20 @@ void Foam::SampledWallGradUField::recompute() const void Foam::SampledWallGradUField::createField() const { - // Grab h to copy bcs from it. - const volScalarField & h = mesh().lookupObject("h"); + bool foundhSampler = mesh_.foundObject("hSampler"); + word hName; + + // Grab h for the current patch + if (foundhSampler) + { + hName = "hSampler"; + } + else + { + hName = "h"; + } + + const volScalarField & h = mesh_.lookupObject (hName); if (!mesh().foundObject("wallGradU")) { diff --git a/samplers/SampledField/SampledWallGradUField.H b/samplers/SampledField/SampledWallGradUField.H index 924654b..aaed2cb 100644 --- a/samplers/SampledField/SampledWallGradUField.H +++ b/samplers/SampledField/SampledWallGradUField.H @@ -19,11 +19,11 @@ License Class Foam::SampledWallGradUField -Description +@brief Class for the sampled velocity gradient field at the wall. Contributors/Copyright: - 2019-2021 Timofey Mukha + 2019-2023 Timofey Mukha SourceFiles SampledWallGradUField.C @@ -51,6 +51,10 @@ class SampledWallGradUField { public: +#if !defined(DOXYGEN_SHOULD_SKIP_THIS) + //- Runtime type information + TypeName("SampledWallGradUField"); +#endif // Constructors @@ -64,19 +68,13 @@ public: SampledField(patch, interpolationType) { createField(); - setInterpolator(interpolationType); } //- Copy constructor SampledWallGradUField(const SampledWallGradUField & orig) : SampledField(orig) - { - if (orig.interpolator_.valid()) - { - setInterpolator(orig.interpolator_().type()); - } - } + {} //- Clone the object autoPtr clone() const override @@ -130,10 +128,6 @@ public: //- Recompute the field void recompute() const override; - //- Set interpolator. Redundant, no interpolation for this field. - void setInterpolator(const word interpolationType) override - {} - //- Create the global wallGrad gradient field that will be sampled virtual void createField() const override; }; diff --git a/samplers/Sampler/Sampler.C b/samplers/Sampler/Sampler.C index e350fd8..9d4e6b2 100644 --- a/samplers/Sampler/Sampler.C +++ b/samplers/Sampler/Sampler.C @@ -49,7 +49,9 @@ Foam::autoPtr Foam::Sampler::New scalar averagingTime, const word interpolationType, const word cellFinderType, - bool hIsIndex + const word lengthScaleType, + bool hIsIndex, + bool excludeWallAdjacent ) { auto cstrIter = @@ -75,7 +77,9 @@ Foam::autoPtr Foam::Sampler::New averagingTime, interpolationType, cellFinderType, - hIsIndex + lengthScaleType, + hIsIndex, + excludeWallAdjacent ); } @@ -91,8 +95,12 @@ Foam::autoPtr Foam::Sampler::New dict.lookupOrDefault("interpolationType", "cell"); word cellFinderType = dict.lookupOrDefault("sampler", "Tree"); + word lengthScaleType = + dict.lookupOrDefault("lengthScale", "CubeRootVol"); bool hIsIndex = dict.lookupOrDefault("hIsIndex", false); + bool excludeWallAdjacent = + dict.lookupOrDefault("excludeWallAdjacent", false); return Foam::Sampler::New ( @@ -101,7 +109,9 @@ Foam::autoPtr Foam::Sampler::New averagingTime, interpolationType, cellFinderType, - hIsIndex + lengthScaleType, + hIsIndex, + excludeWallAdjacent ); } @@ -110,8 +120,21 @@ Foam::autoPtr Foam::Sampler::New void Foam::Sampler::createFields() { + bool foundhSampler = mesh_.foundObject("hSampler"); + word hName; + + // Grab h for the current patch + if (foundhSampler) + { + hName = "hSampler"; + } + else + { + hName = "h"; + } + + const volScalarField & h = mesh_.lookupObject (hName); - const volScalarField & h = mesh_.lookupObject ("h"); // Field that marks cells that are used for sampling if (!mesh_.thisDb().found("samplingCells")) { @@ -149,7 +172,9 @@ Foam::Sampler::Sampler scalar averagingTime, const word interpolationType, const word cellFinderType, - bool hIsIndex + const word lengthScaleType, + bool hIsIndex, + bool excludeWallAdjacent ) : patch_(p), @@ -158,7 +183,9 @@ Foam::Sampler::Sampler sampledFields_(0), interpolationType_(interpolationType), cellFinderType_(cellFinderType), - hIsIndex_(hIsIndex) + lengthScaleType_(lengthScaleType), + hIsIndex_(hIsIndex), + excludeWallAdjacent_(excludeWallAdjacent) { if (debug) { @@ -213,10 +240,21 @@ Foam::Sampler::Sampler scalar averagingTime, const word interpolationType, const word cellFinderType, - bool hIsIndex + const word lengthScaleType, + bool hIsIndex, + bool excludeWallAdjacent ) : - Sampler(p, averagingTime, interpolationType, cellFinderType, hIsIndex) + Sampler + ( + p, + averagingTime, + interpolationType, + cellFinderType, + lengthScaleType, + hIsIndex, + excludeWallAdjacent + ) { } @@ -228,7 +266,9 @@ Foam::Sampler::Sampler(const Sampler & copy) sampledFields_(copy.sampledFields_), interpolationType_(copy.interpolationType_), cellFinderType_(copy.cellFinderType_), - hIsIndex_(copy.hIsIndex_) + lengthScaleType_(copy.lengthScaleType_), + hIsIndex_(copy.hIsIndex_), + excludeWallAdjacent_(copy.excludeWallAdjacent_) { if (debug) { diff --git a/samplers/Sampler/Sampler.H b/samplers/Sampler/Sampler.H index 77c9b60..d59a842 100644 --- a/samplers/Sampler/Sampler.H +++ b/samplers/Sampler/Sampler.H @@ -19,7 +19,7 @@ License Class Foam::Sampler -Description +@brief Class for sampling data to the wall models. Contributors/Copyright: @@ -76,16 +76,23 @@ protected: //- Type of cellFinder to use for finding sampling cells. word cellFinderType_; - //- Whether the h field is the consecutive index of the samping cell + //- Way to compute the length-scale for the cells + word lengthScaleType_; + + //- Whether the h field is the consecutive index of the sampling cell bool hIsIndex_; + //- Whether to exclude wall-adjacent cell from the sampling cells + bool excludeWallAdjacent_; + + // Protected Member Functions //- Create list of cell-indices from where data is sampled virtual void createIndexList() = 0; //- Compute the length-scales - virtual void createLengthList(){} + virtual void createLengthList(const word lengthScaleType){} //- Create fields virtual void createFields(); @@ -99,17 +106,19 @@ public: // Constructors - //- Construct from patch and averaging time + //- Construct without typename Sampler ( const fvPatch &, scalar averagingTime, const word interpolationType, const word cellFinderType, - bool hIsIndex + const word lengthScaleType, + bool hIsIndex, + bool excludeWallAdjacent ); - //- Construct from type, patch and averaging time + //- Construct from typename Sampler ( const word & samplerName, @@ -117,7 +126,9 @@ public: scalar averagingTime, const word interpolationType, const word cellFinderType, - bool hIsIndex + const word lengthScaleType, + bool hIsIndex, + bool excludeWallAdjacent ); @@ -135,7 +146,9 @@ public: scalar averagingTime, const word interpolationType, const word cellFinderType, - bool hIsIndex + const word lengthScaleType, + bool hIsIndex, + bool excludeWallAjdacent ); static autoPtr New @@ -170,21 +183,37 @@ public: return averagingTime_; } + //- Get the number of sampled fields label nSampledFields() const { return sampledFields_.size(); } + //- Get the interpolation type word interpolationType() const { return interpolationType_; } + //- Get the cell finder type word cellFinderType() const { return cellFinderType_; } + + //- Get the length-scale type + word lengthScaleType() const + { + return lengthScaleType_; + } + + //- Check if wall-adjacent cell is excluded in the multicell sampler + bool excludeWallAdjacent() const + { + return excludeWallAdjacent_; + } + //- Check if h holds the cell index bool hIsIndex() const { return hIsIndex_; @@ -217,7 +246,9 @@ public: scalar averagingTime, const word interpolationType, const word cellFinderType, - bool hIsIndex + const word lengthScaleType, + bool hIsIndex, + bool excludeWallAdjacent ), ( samplerName, @@ -225,7 +256,9 @@ public: averagingTime, interpolationType, cellFinderType, - hIsIndex + lengthScaleType, + hIsIndex, + excludeWallAdjacent ) ); #endif diff --git a/samplers/SingleCellSampler/SingleCellSampler.C b/samplers/SingleCellSampler/SingleCellSampler.C index 24e40cf..6e3ad97 100644 --- a/samplers/SingleCellSampler/SingleCellSampler.C +++ b/samplers/SingleCellSampler/SingleCellSampler.C @@ -32,6 +32,7 @@ License #include "scalarListIOList.H" #include "CrawlingCellFinder.H" #include "TreeCellFinder.H" +#include "surfaceMesh.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -51,9 +52,21 @@ void Foam::SingleCellSampler::createIndexList() { const label patchIndex = patch().index(); + word hName; + + // Grab h for the current patch + if (mesh_.foundObject("hSampler")) + { + hName = "hSampler"; + } + else + { + hName = "h"; + } + // Grab h for the current patch volScalarField & h = - const_cast(mesh_.lookupObject ("h")); + const_cast(mesh_.lookupObject (hName)); scalarField hPatch = h.boundaryField()[patchIndex]; @@ -160,7 +173,21 @@ void Foam::SingleCellSampler::createIndexList() } -void Foam::SingleCellSampler::createLengthList() +void Foam::SingleCellSampler::createLengthList(const word lengthScaleType) +{ + if (lengthScaleType == "CubeRootVol") + { + createLengthListCubeRootVol(); + } + else if (lengthScaleType == "WallNormalDistance") + { + createLengthListWallNormalDistance(); + } + +} + + +void Foam::SingleCellSampler::createLengthListCubeRootVol() { // Cell volumes const scalarField & V = mesh_.V(); @@ -169,7 +196,47 @@ void Foam::SingleCellSampler::createLengthList() { lengthList_[i] = pow(V[indexList_[i]], 1.0/3.0); } - +} + + +void Foam::SingleCellSampler::createLengthListWallNormalDistance() +{ + + const vectorField & faceCentres = mesh().Cf().primitiveField(); + const List & cells = mesh().cells(); + const vectorField & patchFaceCentres = patch().Cf(); + const List & faces = mesh().faces(); + + forAll(lengthList_, i) + { + const label index = indexList_[i]; + const cell cellI = cells[index]; + + const vector patchFaceI = patchFaceCentres[i]; + + // Find face with min distance from the wall face + scalar minDist = GREAT; + label minDistFace = 0; + for (int j=0; jregisterFields(indexList()); - field->setInterpolator(interpolationType_); } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/samplers/SingleCellSampler/SingleCellSampler.H b/samplers/SingleCellSampler/SingleCellSampler.H index 85944bb..8c3ee0f 100644 --- a/samplers/SingleCellSampler/SingleCellSampler.H +++ b/samplers/SingleCellSampler/SingleCellSampler.H @@ -19,7 +19,7 @@ License Class Foam::SingleCellSampler -Description +@brief Class for sampling data to the wall models for a single cell per face. Contributors/Copyright: @@ -66,9 +66,15 @@ protected: //- Create list of cell-indices from where data is sampled void createIndexList() override; - + //- Compute the length-scales - void createLengthList() override; + void createLengthList(const word lengthScaleType) override; + + //- Compute length-scales as cubic root of the volume + void createLengthListCubeRootVol(); + + //- Compute length-scales as distance across wall-normal direction + void createLengthListWallNormalDistance(); public: @@ -79,17 +85,17 @@ public: // Constructors - //- Construct from patch and averaging time SingleCellSampler ( const fvPatch&, scalar averagingTime, const word interpolationType="cell", const word cellFinderType="Tree", - bool hIsIndex=false + const word lengthScaleType="CubeRootVol", + bool hIsIndex=false, + bool excludeWallAdjacent=false ); - //- Construct from type, patch and averaging time SingleCellSampler ( const word & samplerName, @@ -97,7 +103,9 @@ public: scalar averagingTime, const word interpolationType="cell", const word cellFinderType="Tree", - bool hIsIndex=false + const word lengthScaleType="CubeRootVol", + bool hIsIndex=false, + bool excludeWallAdjacent=false ); SingleCellSampler(const SingleCellSampler &) = default; diff --git a/scalarListListIOList/scalarListListIOList.H b/scalarListListIOList/scalarListListIOList.H index 9419d7b..bbc44ba 100644 --- a/scalarListListIOList/scalarListListIOList.H +++ b/scalarListListIOList/scalarListListIOList.H @@ -19,7 +19,7 @@ License Class Foam::SingleCellSampler -Description +@brief Contributors/Copyright: diff --git a/tests/.gitignore b/tests/.gitignore index 11d0510..9a35010 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -1,9 +1,7 @@ **/testRunner -**/system **/constant -**/0 -/tests/test_cases/channelFlow/constant/polyMesh -!/tests/test_cases/channelFlow/system -!/tests/test_cases/channelFlow/constant -!/tests/test_cases/channelFlow/0 +/tests/testCases/channelFlow/constant/polyMesh +!/tests/testCases/channelFlow/system +!/tests/testCases/channelFlow/constant +!/tests/testCases/channelFlow/0 logs diff --git a/tests/Make/files b/tests/Make/files index 5956c82..795e812 100644 --- a/tests/Make/files +++ b/tests/Make/files @@ -7,6 +7,7 @@ fixtures.C ./samplers/SampledField/testSampledVelocityField.C ./samplers/SampledField/testSampledWallGradUField.C ./samplers/SampledField/testSampledPGradField.C +./lawsOfTheWall/RoughLogLawOfTheWall/testRoughLogLawOfTheWall.C ./lawsOfTheWall/SpaldingLawOfTheWall/testSpaldingLawOfTheWall.C ./lawsOfTheWall/ReichardtLawOfTheWall/testReichardtLawOfTheWall.C ./lawsOfTheWall/WernerWengleLawOfTheWall/testWernerWengleLawOfTheWall.C @@ -17,7 +18,6 @@ fixtures.C ./eddyViscosities/DupratEddyViscosity/testDupratEddyViscosity.C ./eddyViscosities/EddyViscosity/testEddyViscosity.C ./scalarListListIOList/testScalarListListIOList.C -./wallModels/testWallModel.C ./cellFinders/Compatibility/testCellFinderCompatibility.C ./cellFinders/CrawlingCellFinder/testCrawlingCellFinder.C ./cellFinders/TreeCellFinder/testTreeCellFinder.C diff --git a/tests/Make/options b/tests/Make/options index 477fac0..47ec4d2 100644 --- a/tests/Make/options +++ b/tests/Make/options @@ -2,7 +2,7 @@ ifeq ($(findstring clang, $(CC)), clang) FLAGS = -Wno-inconsistent-missing-override endif -EXE_INC = -std=c++0x $(FLAGS) \ +EXE_INC = -std=c++14 $(FLAGS) \ -I$(LIB_SRC)/finiteVolume/lnInclude \ -I$(LIB_SRC)/OpenFOAM/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \ diff --git a/tests/cellFinders/Compatibility/testCellFinderCompatibility.C b/tests/cellFinders/Compatibility/testCellFinderCompatibility.C index 518772c..8a5b30b 100644 --- a/tests/cellFinders/Compatibility/testCellFinderCompatibility.C +++ b/tests/cellFinders/Compatibility/testCellFinderCompatibility.C @@ -22,7 +22,7 @@ TEST_F(CellFinderCompatibilityTest, ExactDistance) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const fvPatch & patch = mesh.boundary()["bottomWall"]; @@ -104,7 +104,7 @@ TEST_F(CellFinderCompatibilityTest, NegativeDistance) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const fvPatch & patch = mesh.boundary()["bottomWall"]; @@ -149,7 +149,7 @@ TEST_F(CellFinderCompatibilityTest, TooLargeDistance) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const fvPatch & patch = mesh.boundary()["bottomWall"]; @@ -193,7 +193,7 @@ TEST_F(CellFinderCompatibilityTest, InexactDistance) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const fvPatch & patch = mesh.boundary()["bottomWall"]; @@ -293,7 +293,7 @@ TEST_F(CellFinderCompatibilityTest, ExactDistanceMulticell) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const fvPatch & patch = mesh.boundary()["bottomWall"]; @@ -391,7 +391,7 @@ TEST_F(CellFinderCompatibilityTest, ExactDistanceExcludeMulticell) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const fvPatch & patch = mesh.boundary()["bottomWall"]; @@ -490,7 +490,7 @@ TEST_F(CellFinderCompatibilityTest, NegativeDistanceMulticell) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const fvPatch & patch = mesh.boundary()["bottomWall"]; @@ -540,7 +540,7 @@ TEST_F(CellFinderCompatibilityTest, TooLargeDistanceMulticell) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const fvPatch & patch = mesh.boundary()["bottomWall"]; diff --git a/tests/cellFinders/CrawlingCellFinder/testCrawlingCellFinder.C b/tests/cellFinders/CrawlingCellFinder/testCrawlingCellFinder.C index db4a703..98db08a 100644 --- a/tests/cellFinders/CrawlingCellFinder/testCrawlingCellFinder.C +++ b/tests/cellFinders/CrawlingCellFinder/testCrawlingCellFinder.C @@ -20,7 +20,7 @@ TEST_F(CrawlingCellFinderTest, FullConstructor) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const fvPatch & patch = mesh.boundary()["bottomWall"]; h.boundaryFieldRef()[patch.index()] == 2; @@ -39,7 +39,7 @@ TEST_F(CrawlingCellFinderTest, FindIndexBasedBottomWall) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const volVectorField & C = mesh.C(); @@ -99,7 +99,7 @@ TEST_F(CrawlingCellFinderTest, FindIndexBasedTopWall) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const volVectorField & C = mesh.C(); @@ -160,7 +160,7 @@ TEST_F(CrawlingCellFinderTest, FindIndexBasedInvalidIndex) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const volVectorField & C = mesh.C(); @@ -195,7 +195,7 @@ TEST_F(CrawlingCellFinderTest, FindIndexBasedTooLargeIndex) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const volVectorField & C = mesh.C(); @@ -230,7 +230,7 @@ TEST_F(CrawlingCellFinderTest, FindDistanceBasedBottomWall) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const volVectorField & C = mesh.C(); @@ -291,7 +291,7 @@ TEST_F(CrawlingCellFinderTest, FindDistanceBasedTopWall) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const volVectorField & C = mesh.C(); @@ -352,7 +352,7 @@ TEST_F(CrawlingCellFinderTest, FindDistanceInvalidDistance) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const volVectorField & C = mesh.C(); @@ -386,7 +386,7 @@ TEST_F(CrawlingCellFinderTest, FindDistanceZeroDistance) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const volVectorField & C = mesh.C(); @@ -421,7 +421,7 @@ TEST_F(CrawlingCellFinderTest, FindDistanceTooLargeDistance) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const volVectorField & C = mesh.C(); @@ -456,7 +456,7 @@ TEST_F(CrawlingCellFinderTest, FindIndexBasedBottomWallMulticell) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const volVectorField & C = mesh.C(); @@ -509,7 +509,7 @@ TEST_F(CrawlingCellFinderTest, FindIndexBasedTopWallMulticell) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const volVectorField & C = mesh.C(); @@ -563,7 +563,7 @@ TEST_F(CrawlingCellFinderTest, FindDistanceBasedBottomWallMulticell) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const volVectorField & C = mesh.C(); @@ -617,7 +617,7 @@ TEST_F(CrawlingCellFinderTest, FindDistanceBasedTopWallMulticell) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const volVectorField & C = mesh.C(); @@ -671,7 +671,7 @@ TEST_F(CrawlingCellFinderTest, NegativeIndexMulticell) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const volVectorField & C = mesh.C(); @@ -708,7 +708,7 @@ TEST_F(CrawlingCellFinderTest, NegativeDistanceMulticell) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const volVectorField & C = mesh.C(); @@ -745,7 +745,7 @@ TEST_F(CrawlingCellFinderTest, LargeIndexMulticell) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const volVectorField & C = mesh.C(); @@ -782,7 +782,7 @@ TEST_F(CrawlingCellFinderTest, LargeDistanceMulticell) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const volVectorField & C = mesh.C(); @@ -819,7 +819,7 @@ TEST_F(CrawlingCellFinderTest, ExcludeWallAdjacentMulticell) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const volVectorField & C = mesh.C(); @@ -856,7 +856,7 @@ TEST_F(CrawlingCellFinderTest, ExcludeWallAdjacentOneCellMulticell) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const volVectorField & C = mesh.C(); diff --git a/tests/cellFinders/TreeCellFinder/testTreeCellFinder.C b/tests/cellFinders/TreeCellFinder/testTreeCellFinder.C index 530fd86..b56af1b 100644 --- a/tests/cellFinders/TreeCellFinder/testTreeCellFinder.C +++ b/tests/cellFinders/TreeCellFinder/testTreeCellFinder.C @@ -21,7 +21,7 @@ TEST_F(TreeCellFinderTest, FullConstructor) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const fvPatch & patch = mesh.boundary()["bottomWall"]; h.boundaryFieldRef()[patch.index()] == 0.25; @@ -41,7 +41,7 @@ TEST_F(TreeCellFinderTest, FindDistanceBasedBottomWallSingleCell) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const volVectorField & C = mesh.C(); @@ -99,7 +99,7 @@ TEST_F(TreeCellFinderTest, FindDistanceBasedTopWallSingleCell) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const volVectorField & C = mesh.C(); @@ -157,7 +157,7 @@ TEST_F(TreeCellFinderTest, FindDistanceInvalidDistanceSingleCell) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const volVectorField & C = mesh.C(); @@ -190,7 +190,7 @@ TEST_F(TreeCellFinderTest, FindDistanceZeroDistanceSingleCell) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const volVectorField & C = mesh.C(); @@ -224,7 +224,7 @@ TEST_F(TreeCellFinderTest, FindDistanceTooLargeDistanceSingleCell) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const volVectorField & C = mesh.C(); @@ -388,7 +388,7 @@ TEST_F(TreeCellFinderTest, FindDistanceBasedBottomWallMultiCell) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const volVectorField & C = mesh.C(); @@ -456,7 +456,7 @@ TEST_F(TreeCellFinderTest, FindDistanceBasedBottomWallWithExclusionMultiCell) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const volVectorField & C = mesh.C(); @@ -523,7 +523,7 @@ TEST_F(TreeCellFinderTest, ZeroDistanceMultiCell) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const volVectorField & C = mesh.C(); @@ -559,7 +559,7 @@ TEST_F(TreeCellFinderTest, InvalidDistanceMultiCell) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const volVectorField & C = mesh.C(); @@ -594,7 +594,7 @@ TEST_F(TreeCellFinderTest, TooLargeDistanceMultiCell) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const volVectorField & C = mesh.C(); diff --git a/tests/eddyViscosities/DupratEddyViscosity/testDupratEddyViscosity.C b/tests/eddyViscosities/DupratEddyViscosity/testDupratEddyViscosity.C index b302055..0830adc 100644 --- a/tests/eddyViscosities/DupratEddyViscosity/testDupratEddyViscosity.C +++ b/tests/eddyViscosities/DupratEddyViscosity/testDupratEddyViscosity.C @@ -138,7 +138,8 @@ TEST_F(DupratEddyViscosityTest, AddFieldsToSampler) patch, 3.0, "cell", - "Tree", + "Tree", + "CubeRootVol", false ); diff --git a/tests/eddyViscosities/VanDriestEddyViscosity/testVanDriestEddyViscosity.C b/tests/eddyViscosities/VanDriestEddyViscosity/testVanDriestEddyViscosity.C index 7c8d69d..d97a177 100644 --- a/tests/eddyViscosities/VanDriestEddyViscosity/testVanDriestEddyViscosity.C +++ b/tests/eddyViscosities/VanDriestEddyViscosity/testVanDriestEddyViscosity.C @@ -137,6 +137,7 @@ TEST_F(VanDriestEddyViscosityTest, ValueSampler) 3.0, "cell", "Tree", + "CubeRootVol", false ); VanDriestEddyViscosity eddy = VanDriestEddyViscosity(0.4, 18); diff --git a/tests/fixtures.C b/tests/fixtures.C index 6a0fa91..f456d64 100644 --- a/tests/fixtures.C +++ b/tests/fixtures.C @@ -8,7 +8,7 @@ void createSamplingHeightField(const Foam::fvMesh & mesh) ( IOobject ( - "h", + "hSampler", mesh.time().timeName(), mesh, IOobject::MUST_READ, @@ -43,7 +43,7 @@ void createVelocityField(const Foam::fvMesh & mesh) void createPGradField(const Foam::fvMesh & mesh) { // Grab h to copy bcs from it. - const volScalarField & h = mesh.lookupObject("h"); + const volScalarField & h = mesh.lookupObject("hSampler"); if (!mesh.foundObject("pGrad")) { diff --git a/tests/fixtures.H b/tests/fixtures.H index aaf718f..a1eb441 100644 --- a/tests/fixtures.H +++ b/tests/fixtures.H @@ -16,7 +16,7 @@ License along with libWallModelledLES. If not, see . -Description +@brief Various helper functions for testing the software. Contributors/Copyright: @@ -65,17 +65,17 @@ class ChannelFlow : public ::testing::Test public: ChannelFlow() { - system("cp -r $LIBWMLES_DIR/tests/testCases/channel_flow/system ."); - system("cp -r $LIBWMLES_DIR/tests/testCases/channel_flow/constant ."); - system("cp -r $LIBWMLES_DIR/tests/testCases/channel_flow/0 ."); + auto code = system("cp -r $LIBWMLES_DIR/tests/testCases/channel_flow/system ."); + code = system("cp -r $LIBWMLES_DIR/tests/testCases/channel_flow/constant ."); + code = system("cp -r $LIBWMLES_DIR/tests/testCases/channel_flow/0 ."); } virtual ~ChannelFlow() { - system("rm -r system"); - system("rm -r constant"); - system("rm -r 0"); + auto code = system("rm -r system"); + code = system("rm -r constant"); + code = system("rm -r 0"); } }; diff --git a/tests/integrationTests/Make/options b/tests/integrationTests/Make/options index d6d3a7c..53b6b19 100644 --- a/tests/integrationTests/Make/options +++ b/tests/integrationTests/Make/options @@ -2,7 +2,7 @@ ifeq ($(findstring clang, $(CC)), clang) FLAGS = -Wno-inconsistent-missing-override endif -EXE_INC = -std=c++0x $(FLAGS) \ +EXE_INC = -std=c++14 $(FLAGS) \ -I$(LIB_SRC)/finiteVolume/lnInclude \ -I$(LIB_SRC)/OpenFOAM/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \ diff --git a/tests/integrationTests/testIntegrationKnownWallShearStress.C b/tests/integrationTests/testIntegrationKnownWallShearStress.C index 4c76eed..fca158c 100644 --- a/tests/integrationTests/testIntegrationKnownWallShearStress.C +++ b/tests/integrationTests/testIntegrationKnownWallShearStress.C @@ -7,18 +7,18 @@ class ChannelFlow : public ::testing::Test public: ChannelFlow() { - std::system("cp -r ../testCases/channel_flow/system ."); - std::system("cp -r ../testCases/channel_flow/constant ."); - std::system("cp -r ../testCases/channel_flow/0 ."); + auto code = std::system("cp -r ../testCases/channel_flow/system ."); + code = std::system("cp -r ../testCases/channel_flow/constant ."); + code = std::system("cp -r ../testCases/channel_flow/0 ."); } virtual ~ChannelFlow() { - std::system("rm -r system"); - std::system("rm -r constant"); - std::system("rm -r 0"); - std::system("rm -r 0.01"); - std::system("rm -r processor*"); + auto code = std::system("rm -r system"); + code = std::system("rm -r constant"); + code = std::system("rm -r 0"); + code = std::system("rm -r 0.01"); + code = std::system("rm -r processor*"); } }; diff --git a/tests/integrationTests/testIntegrationLOTW.C b/tests/integrationTests/testIntegrationLOTW.C index 01e5e63..a309ed3 100644 --- a/tests/integrationTests/testIntegrationLOTW.C +++ b/tests/integrationTests/testIntegrationLOTW.C @@ -7,18 +7,18 @@ class ChannelFlow : public ::testing::Test public: ChannelFlow() { - std::system("cp -r ../testCases/channel_flow/system ."); - std::system("cp -r ../testCases/channel_flow/constant ."); - std::system("cp -r ../testCases/channel_flow/0 ."); + auto code = std::system("cp -r ../testCases/channel_flow/system ."); + code = std::system("cp -r ../testCases/channel_flow/constant ."); + code = std::system("cp -r ../testCases/channel_flow/0 ."); } virtual ~ChannelFlow() { - std::system("rm -r system"); - std::system("rm -r constant"); - std::system("rm -r 0"); - std::system("rm -r 0.01"); - std::system("rm -r processor*"); + auto code = std::system("rm -r system"); + code = std::system("rm -r constant"); + code = std::system("rm -r 0"); + code = std::system("rm -r 0.01"); + code = std::system("rm -r processor*"); } }; @@ -67,6 +67,16 @@ TEST_F(IntegrationTest, RunLOTWWernerWengle) ASSERT_EQ(WEXITSTATUS(success), 0); } +TEST_F(IntegrationTest, RunLOTWRoughLogLaw) +{ + int success = std::system("changeDictionary -dict system/setNutLOTWRoughLogLaw"); + ASSERT_EQ(WIFEXITED(success), true); + ASSERT_EQ(WEXITSTATUS(success), 0); + success = std::system("pimpleFoam"); + ASSERT_EQ(WIFEXITED(success), true); + ASSERT_EQ(WEXITSTATUS(success), 0); +} + TEST_F(IntegrationTest, RunLOTWIntegratedWernerWengle) { int success = std::system("changeDictionary -dict system/setNutLOTWWernerWengle"); @@ -129,6 +139,16 @@ TEST_F(IntegrationTest, DecomposeLOTWIntegratedWernerWengle) ASSERT_EQ(WEXITSTATUS(success), 0); } +TEST_F(IntegrationTest, DecomposeLOTWIntegratedRoughLogLaw) +{ + int success = std::system("changeDictionary -dict system/setNutLOTWRoughLogLaw"); + ASSERT_EQ(WIFEXITED(success), true); + ASSERT_EQ(WEXITSTATUS(success), 0); + success = std::system("decomposePar -force"); + ASSERT_EQ(WIFEXITED(success), true); + ASSERT_EQ(WEXITSTATUS(success), 0); +} + // * * * * * * * * * * * * * * * Run in parallel with LOTW * * * * * * * * * * * * * // TEST_F(IntegrationTest, ParallelRunLOTWSpalding) @@ -211,6 +231,22 @@ TEST_F(IntegrationTest, ParallelRunLOTWIntegratedReichardt) ASSERT_EQ(WEXITSTATUS(success), 0); } +TEST_F(IntegrationTest, ParallelRunLOTWRoughLogLaw) +{ + int success = std::system("changeDictionary -dict system/setNutFixedValue"); + ASSERT_EQ(WIFEXITED(success), true); + ASSERT_EQ(WEXITSTATUS(success), 0); + success = std::system("decomposePar -force"); + ASSERT_EQ(WIFEXITED(success), true); + ASSERT_EQ(WEXITSTATUS(success), 0); + success = std::system("mpirun -np 2 changeDictionary -dict system/setNutLOTWRoughLogLaw -parallel"); + ASSERT_EQ(WIFEXITED(success), true); + ASSERT_EQ(WEXITSTATUS(success), 0); + success = std::system("mpirun -np 2 pimpleFoam -parallel"); + ASSERT_EQ(WIFEXITED(success), true); + ASSERT_EQ(WEXITSTATUS(success), 0); +} + // * * * * * * * * * * * * * * * Reconstruct with LOTW * * * * * * * * * * * * * // TEST_F(IntegrationTest, ReconstructLOTWSpalding) @@ -291,4 +327,20 @@ TEST_F(IntegrationTest, ReconstructLOTWIntegratedWernerWengle) success = std::system("reconstructPar -withZero"); ASSERT_EQ(WIFEXITED(success), true); ASSERT_EQ(WEXITSTATUS(success), 0); +} + +TEST_F(IntegrationTest, ReconstructLOTWRoughLogLaw) +{ + int success = std::system("changeDictionary -dict system/setNutFixedValue"); + ASSERT_EQ(WIFEXITED(success), true); + ASSERT_EQ(WEXITSTATUS(success), 0); + success = std::system("decomposePar -force"); + ASSERT_EQ(WIFEXITED(success), true); + ASSERT_EQ(WEXITSTATUS(success), 0); + success = std::system("mpirun -np 2 changeDictionary -dict system/setNutLOTWRoughLogLaw -parallel"); + ASSERT_EQ(WIFEXITED(success), true); + ASSERT_EQ(WEXITSTATUS(success), 0); + success = std::system("reconstructPar -withZero"); + ASSERT_EQ(WIFEXITED(success), true); + ASSERT_EQ(WEXITSTATUS(success), 0); } \ No newline at end of file diff --git a/tests/lawsOfTheWall/IntegratedReichardtLawOfTheWall/testIntegratedReichardtLawOfTheWall.C b/tests/lawsOfTheWall/IntegratedReichardtLawOfTheWall/testIntegratedReichardtLawOfTheWall.C index a9762d3..4a01208 100644 --- a/tests/lawsOfTheWall/IntegratedReichardtLawOfTheWall/testIntegratedReichardtLawOfTheWall.C +++ b/tests/lawsOfTheWall/IntegratedReichardtLawOfTheWall/testIntegratedReichardtLawOfTheWall.C @@ -189,6 +189,56 @@ TEST_F(IntegratedReichardtLawOfTheWallTest, ValueSampler) ASSERT_FLOAT_EQ(value, -0.20040621277606402); } + +TEST_F(IntegratedReichardtLawOfTheWallTest, ValueMulticellSampler) +{ + extern argList * mainArgs; + const argList & args = *mainArgs; + Time runTime(Foam::Time::controlDictName, args); + + autoPtr meshPtr = createMesh(runTime); + const fvMesh & mesh = meshPtr(); + createSamplingHeightField(mesh); + + const fvPatch & patch = mesh.boundary()["bottomWall"]; + volScalarField & h = const_cast + ( + mesh.thisDb().lookupObject("hSampler") + ); + + createVelocityField(mesh); + volVectorField & U = mesh.lookupObjectRef("U"); + + // Init U to something varying + for (int i=0; i< U.size(); i++) + { + U.primitiveFieldRef()[i] = vector(5, 0, 0); + } + + h.boundaryFieldRef()[patch.index()] == 2; + MultiCellSampler sampler + ( + patch, + 3.0, + "cell", + "Crawling", + "WallNormalDistance", + true, + false + ); + IntegratedReichardtLawOfTheWall law = + IntegratedReichardtLawOfTheWall(0.4, 11, 3, 7.8); + + // label index = 5; + // const scalarListList & sampledU = + // sampler.db().lookupObject("U")[index]; + // scalarList samplerh = sampler.h()[index]; + // scalarList samplerl = sampler.lengthList()[index]; + + scalar value = law.valueMulticell(sampler, 5, 0.04, 8e-6); + ASSERT_FLOAT_EQ(value, 1.6481687); +} + TEST_F(IntegratedReichardtLawOfTheWallTest, DerivativeSampler) { extern argList * mainArgs; @@ -206,6 +256,7 @@ TEST_F(IntegratedReichardtLawOfTheWallTest, DerivativeSampler) 3.0, "cell", "Tree", + "CubeRootVol", false ); IntegratedReichardtLawOfTheWall law = diff --git a/tests/lawsOfTheWall/RoughLogLawOfTheWall/testRoughLogLawOfTheWall.C b/tests/lawsOfTheWall/RoughLogLawOfTheWall/testRoughLogLawOfTheWall.C new file mode 100644 index 0000000..8efc29a --- /dev/null +++ b/tests/lawsOfTheWall/RoughLogLawOfTheWall/testRoughLogLawOfTheWall.C @@ -0,0 +1,213 @@ +#include "codeRules.H" +#include "fvCFD.H" +#include "RoughLogLawOfTheWall.H" +#undef Log +#include "gtest.h" +#include "gmock/gmock.h" +#include "fixtures.H" +#include "SingleCellSampler.H" + +class RoughLogLawOfTheWallTest : public ChannelFlow +{}; + +TEST_F(RoughLogLawOfTheWallTest, ConstructFromConstants) +{ + RoughLogLawOfTheWall law = RoughLogLawOfTheWall(0.395, 11, 3); + + ASSERT_DOUBLE_EQ(law.kappa(), 0.395); + ASSERT_DOUBLE_EQ(law.B(), 11); + ASSERT_DOUBLE_EQ(law.ks(), 3); + + dictionary dict = law.constDict(); + ASSERT_DOUBLE_EQ(dict.lookupOrDefault("kappa", 0.0), 0.395); + ASSERT_DOUBLE_EQ(dict.lookupOrDefault("B", 0.0), 11); + ASSERT_DOUBLE_EQ(dict.lookupOrDefault("ks", 0.0), 3); +} + +TEST_F(RoughLogLawOfTheWallTest, ConstructFromDictionary) +{ + dictionary dict = dictionary(); + dict.add("kappa", 0.395); + dict.add("B", 11); + dict.add("ks", 3); + + + RoughLogLawOfTheWall law = RoughLogLawOfTheWall(dict); + + ASSERT_DOUBLE_EQ(law.kappa(), 0.395); + ASSERT_DOUBLE_EQ(law.B(), 11); + ASSERT_DOUBLE_EQ(law.ks(), 3); + + dict = law.constDict(); + ASSERT_DOUBLE_EQ(dict.lookupOrDefault("kappa", 0.0), 0.395); + ASSERT_DOUBLE_EQ(dict.lookupOrDefault("B", 0.0), 11); + ASSERT_DOUBLE_EQ(dict.lookupOrDefault("ks", 0.0), 3); +} + +TEST_F(RoughLogLawOfTheWallTest, ConstructFromDictionaryDefaultValues) +{ + dictionary dict = dictionary(); + dict.add("B", 11); + dict.add("ks", 3); + RoughLogLawOfTheWall law = RoughLogLawOfTheWall(dict); + + ASSERT_DOUBLE_EQ(law.kappa(), 0.4); + ASSERT_DOUBLE_EQ(law.B(), 11); + ASSERT_DOUBLE_EQ(law.ks(), 3); + + dict = law.constDict(); + ASSERT_DOUBLE_EQ(dict.lookupOrDefault("kappa", 0.0), 0.4); + ASSERT_DOUBLE_EQ(dict.lookupOrDefault("B", 0.0), 11); + ASSERT_DOUBLE_EQ(dict.lookupOrDefault("ks", 0.0), 3); +} + +TEST_F(RoughLogLawOfTheWallTest, ConstructFromTypeDictionary) +{ + dictionary dict = dictionary(); + dict.add("kappa", 0.395); + dict.add("B", 11); + dict.add("ks", 3); + RoughLogLawOfTheWall law = + RoughLogLawOfTheWall("RoughLogLawOfTheWall", dict); + + ASSERT_DOUBLE_EQ(law.kappa(), 0.395); + ASSERT_DOUBLE_EQ(law.B(), 11); + ASSERT_DOUBLE_EQ(law.ks(), 3); + + dict = law.constDict(); + ASSERT_DOUBLE_EQ(dict.lookupOrDefault("kappa", 0.0), 0.395); + ASSERT_DOUBLE_EQ(dict.lookupOrDefault("B", 0.0), 11); + ASSERT_DOUBLE_EQ(dict.lookupOrDefault("ks", 0.0), 3); +} + +TEST_F(RoughLogLawOfTheWallTest, CopyConstructor) +{ + RoughLogLawOfTheWall law = RoughLogLawOfTheWall(0.395, 11, 3); + RoughLogLawOfTheWall law2(law); + + ASSERT_DOUBLE_EQ(law2.kappa(), 0.395); + ASSERT_DOUBLE_EQ(law2.B(), 11); + ASSERT_DOUBLE_EQ(law2.ks(), 3); + + dictionary dict = law2.constDict(); + ASSERT_DOUBLE_EQ(dict.lookupOrDefault("kappa", 0.0), 0.395); + ASSERT_DOUBLE_EQ(dict.lookupOrDefault("B", 0.0), 11); + ASSERT_DOUBLE_EQ(dict.lookupOrDefault("ks", 0.0), 3); +} + +TEST_F(RoughLogLawOfTheWallTest, CopyAssignment) +{ + RoughLogLawOfTheWall law = RoughLogLawOfTheWall(0.395, 11, 3); + RoughLogLawOfTheWall law2 = RoughLogLawOfTheWall(1, 2, 4); + law2 = law; + + ASSERT_DOUBLE_EQ(law2.kappa(), 0.395); + ASSERT_DOUBLE_EQ(law2.B(), 11); + ASSERT_DOUBLE_EQ(law2.ks(), 3); + + dictionary dict = law2.constDict(); + ASSERT_DOUBLE_EQ(dict.lookupOrDefault("kappa", 0.0), 0.395); + ASSERT_DOUBLE_EQ(dict.lookupOrDefault("B", 0.0), 11); + ASSERT_DOUBLE_EQ(dict.lookupOrDefault("ks", 0.0), 3); +} + +TEST_F(RoughLogLawOfTheWallTest, Clone) +{ + RoughLogLawOfTheWall law = RoughLogLawOfTheWall(0.395, 11, 3); + autoPtr law2 = law.clone(); + + ASSERT_DOUBLE_EQ(dynamic_cast(law2()).kappa(), 0.395); + ASSERT_DOUBLE_EQ(dynamic_cast(law2()).B(), 11); + ASSERT_DOUBLE_EQ(dynamic_cast(law2()).ks(), 3); + + dictionary dict = law2().constDict(); + ASSERT_DOUBLE_EQ(dict.lookupOrDefault("kappa", 0.0), 0.395); + ASSERT_DOUBLE_EQ(dict.lookupOrDefault("B", 0.0), 11); + ASSERT_DOUBLE_EQ(dict.lookupOrDefault("ks", 0.0), 3); +} + +TEST_F(RoughLogLawOfTheWallTest, Value) +{ + scalar u = 1; + scalar kappa = 0.4; + scalar B = 5; + scalar ks = 0.1; + RoughLogLawOfTheWall law = RoughLogLawOfTheWall(kappa, B, ks); + + scalar value = law.value(u, 0.2, 0.04, 8e-6); + ASSERT_DOUBLE_EQ(value, 0.04 - u/(1/kappa*Foam::log(0.2/ks) + B)); +} + +TEST_F(RoughLogLawOfTheWallTest, Derivative) +{ + RoughLogLawOfTheWall law = RoughLogLawOfTheWall(0.395, 11, 3); + + scalar derivative = law.derivative(); + ASSERT_DOUBLE_EQ(derivative, 1); +} + +TEST_F(RoughLogLawOfTheWallTest, ValueSampler) +{ + extern argList * mainArgs; + const argList & args = *mainArgs; + Time runTime(Foam::Time::controlDictName, args); + + autoPtr meshPtr = createMesh(runTime); + const fvMesh & mesh = meshPtr(); + createSamplingHeightField(mesh); + createVelocityField(mesh); + + volScalarField & h = const_cast + ( + mesh.thisDb().lookupObject("hSampler") + ); + + const fvPatch & patch = mesh.boundary()["bottomWall"]; + + h.boundaryFieldRef()[patch.index()] == 0; + auto & U = const_cast + ( + mesh.thisDb().lookupObject("U") + ); + + U.primitiveFieldRef() = vector(1, 0, 0); + + SingleCellSampler sampler + ( + "SingleCellSampler", + patch, + 3.0 + ); + scalar u = 1; + scalar kappa = 0.4; + scalar B = 5; + scalar ks = 0.1; + RoughLogLawOfTheWall law = RoughLogLawOfTheWall(kappa, B, ks); + + scalar value = law.value(sampler, 5, 0.04, 8e-6); + ASSERT_DOUBLE_EQ(value, 0.04 - u/(1/kappa*Foam::log(0.1/ks) + B)); +} + +TEST_F(RoughLogLawOfTheWallTest, DerivativeSampler) +{ + extern argList * mainArgs; + const argList & args = *mainArgs; + Time runTime(Foam::Time::controlDictName, args); + + autoPtr meshPtr = createMesh(runTime); + const fvMesh & mesh = meshPtr(); + createSamplingHeightField(mesh); + + const fvPatch & patch = mesh.boundary()["bottomWall"]; + SingleCellSampler sampler + ( + "SingleCellSampler", + patch, + 3.0 + ); + RoughLogLawOfTheWall law = RoughLogLawOfTheWall(0.395, 11, 3); + + scalar derivative = law.derivative(sampler, 5, 0.04, 8e-6); + ASSERT_DOUBLE_EQ(derivative, 1); +} + diff --git a/tests/samplers/MultiCellSampler/testMultiCellSampler.C b/tests/samplers/MultiCellSampler/testMultiCellSampler.C index e3b3e59..aa5b72f 100644 --- a/tests/samplers/MultiCellSampler/testMultiCellSampler.C +++ b/tests/samplers/MultiCellSampler/testMultiCellSampler.C @@ -32,7 +32,9 @@ TEST_F(MultiCellSamplerTest, ConstructorDefaults) ASSERT_EQ(sampler.averagingTime(), 3.0); ASSERT_EQ(sampler.interpolationType(), "cell"); ASSERT_EQ(sampler.cellFinderType(), "Tree"); + ASSERT_EQ(sampler.lengthScaleType(), "CubeRootVol"); ASSERT_EQ(sampler.hIsIndex(), false); + ASSERT_EQ(sampler.excludeWallAdjacent(), false); ASSERT_EQ(&sampler.mesh(), &mesh); ASSERT_EQ(sampler.indexList().size(), patch.size()); ASSERT_EQ(sampler.lengthList().size(), patch.size()); @@ -53,7 +55,7 @@ TEST_F(MultiCellSamplerTest, ConstructorCellCrawling) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); h.boundaryFieldRef()[patch.index()] == 2; @@ -64,6 +66,7 @@ TEST_F(MultiCellSamplerTest, ConstructorCellCrawling) 3.0, "cell", "Crawling", + "CubeRootVol", true ); @@ -72,6 +75,7 @@ TEST_F(MultiCellSamplerTest, ConstructorCellCrawling) ASSERT_EQ(sampler.interpolationType(), "cell"); ASSERT_EQ(sampler.cellFinderType(), "Crawling"); ASSERT_EQ(sampler.hIsIndex(), true); + ASSERT_EQ(sampler.excludeWallAdjacent(), false); ASSERT_EQ(&sampler.mesh(), &mesh); ASSERT_EQ(sampler.indexList().size(), patch.size()); ASSERT_EQ(sampler.lengthList().size(), patch.size()); @@ -107,6 +111,7 @@ TEST_F(MultiCellSamplerTest, ConstructorAttemptCellPoint) 3.0, "cellPoint", "Crawling", + "CubeRootVol", false ); }, @@ -138,6 +143,7 @@ TEST_F(MultiCellSamplerTest, ConstructorAttemptTreeHIsIndex) 3.0, "cell", "Tree", + "CubeRootVol", true ); }, @@ -162,7 +168,7 @@ TEST_F(MultiCellSamplerTest, ConstructorTree) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); h.boundaryFieldRef()[patch.index()] == 0.5; @@ -173,6 +179,7 @@ TEST_F(MultiCellSamplerTest, ConstructorTree) 3.0, "cell", "Tree", + "CubeRootVol", false ); @@ -181,6 +188,7 @@ TEST_F(MultiCellSamplerTest, ConstructorTree) ASSERT_EQ(sampler.interpolationType(), "cell"); ASSERT_EQ(sampler.cellFinderType(), "Tree"); ASSERT_EQ(sampler.hIsIndex(), false); + ASSERT_EQ(sampler.excludeWallAdjacent(), false); ASSERT_EQ(&sampler.mesh(), &mesh); ASSERT_EQ(sampler.indexList().size(), patch.size()); ASSERT_EQ(sampler.lengthList().size(), patch.size()); @@ -218,6 +226,7 @@ TEST_F(MultiCellSamplerTest, AttemptInvalidCellFinderName) 3.0, "cell", "RandomName", + "CubeRootCol", true ); }, @@ -226,6 +235,35 @@ TEST_F(MultiCellSamplerTest, AttemptInvalidCellFinderName) } +TEST_F(MultiCellSamplerTest, AttemptInvalidLengthScaleName) +{ + extern argList * mainArgs; + const argList & args = *mainArgs; + Time runTime(Foam::Time::controlDictName, args); + + autoPtr meshPtr = createMesh(runTime); + const fvMesh & mesh = meshPtr(); + createSamplingHeightField(mesh); + + const fvPatch & patch = mesh.boundary()["bottomWall"]; + + ASSERT_DEATH + ( + { + MultiCellSampler sampler + ( + "MultiCellSampler", + patch, + 3.0, + "cell", + "Tree", + "RandomName", + true + ); + }, + "FATAL ERROR" + ); +} TEST_F(MultiCellSamplerTest, Sample) { extern argList * mainArgs; @@ -241,7 +279,7 @@ TEST_F(MultiCellSamplerTest, Sample) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); h.boundaryFieldRef()[patch.index()] == 3; @@ -260,6 +298,7 @@ TEST_F(MultiCellSamplerTest, Sample) 0.02, "cell", "Crawling", + "CubeRootVol", 3 ); @@ -297,7 +336,7 @@ TEST_F(MultiCellSamplerTest, AddField) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); h.boundaryFieldRef()[patch.index()] == 3; @@ -309,6 +348,7 @@ TEST_F(MultiCellSamplerTest, AddField) 0.02, "cell", "Crawling", + "CubeRootVol", 3 ); @@ -316,4 +356,83 @@ TEST_F(MultiCellSamplerTest, AddField) ASSERT_EQ(sampler.nSampledFields(), 3); ASSERT_TRUE(sampler.db().foundObject("pGrad")); +} + +TEST_F(MultiCellSamplerTest, LengthCubeRootVol) { + extern argList * mainArgs; + const argList & args = *mainArgs; + Time runTime(Foam::Time::controlDictName, args); + + autoPtr meshPtr = createMesh(runTime); + const fvMesh & mesh = meshPtr(); + createSamplingHeightField(mesh); + + volScalarField & h = const_cast + ( + mesh.thisDb().lookupObject("hSampler") + ); + + const fvPatch & patch = mesh.boundary()["bottomWall"]; + + h.boundaryFieldRef()[patch.index()] == 0.3; + + MultiCellSampler sampler + ( + "MultiCellSampler", + patch, + 3.0 + ); + + ASSERT_EQ(sampler.lengthList().size(), patch.size()); + + for (int i=0; i< sampler.lengthList().size(); i++) + { + + ASSERT_EQ(sampler.lengthList()[i].size(), 2); + forAll(sampler.lengthList()[i], j) + { + ASSERT_FLOAT_EQ(sampler.lengthList()[i][j], 0.9283177667225558); + } + } +} + +TEST_F(MultiCellSamplerTest, LengthWallNormalDistance) { + extern argList * mainArgs; + const argList & args = *mainArgs; + Time runTime(Foam::Time::controlDictName, args); + + autoPtr meshPtr = createMesh(runTime); + const fvMesh & mesh = meshPtr(); + createSamplingHeightField(mesh); + + volScalarField & h = const_cast + ( + mesh.thisDb().lookupObject("hSampler") + ); + + const fvPatch & patch = mesh.boundary()["bottomWall"]; + + h.boundaryFieldRef()[patch.index()] == 0.3; + + MultiCellSampler sampler + ( + "MultiCellSampler", + patch, + 3.0, + "cell", + "Crawling", + "WallNormalDistance" + ); + + ASSERT_EQ(sampler.lengthList().size(), patch.size()); + + for (int i=0; i< sampler.lengthList().size(); i++) + { + + ASSERT_EQ(sampler.lengthList()[i].size(), 2); + forAll(sampler.lengthList()[i], j) + { + ASSERT_FLOAT_EQ(sampler.lengthList()[i][j], 0.2); + } + } } \ No newline at end of file diff --git a/tests/samplers/SampledField/testSampledPGradField.C b/tests/samplers/SampledField/testSampledPGradField.C index faedcc1..3ae2e3a 100644 --- a/tests/samplers/SampledField/testSampledPGradField.C +++ b/tests/samplers/SampledField/testSampledPGradField.C @@ -129,7 +129,7 @@ TEST_F(SampledPGradTest, RegisterFieldsZeroMultiCell) createSamplingHeightField(mesh); volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); h.boundaryFieldRef()[patch.index()] == 2; @@ -142,6 +142,7 @@ TEST_F(SampledPGradTest, RegisterFieldsZeroMultiCell) 3.0, "cell", "Crawling", + "CubeRootVol", true ) ); @@ -238,7 +239,7 @@ TEST_F(SampledPGradTest, RegisterFieldsInitializeMultiCell) createSamplingHeightField(mesh); volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const fvPatch & patch = mesh.boundary()["bottomWall"]; @@ -260,6 +261,7 @@ TEST_F(SampledPGradTest, RegisterFieldsInitializeMultiCell) 3.0, "cell", "Crawling", + "CubeRootVol", true ) ); @@ -350,7 +352,8 @@ TEST_F(SampledPGradTest, RegisterFieldsReadMulticell) Time runTime(Foam::Time::controlDictName, args); // Make previously sampled data readable - system("cp -r 0/wallModelSamplingMulti 0/wallModelSampling"); + auto code = system("cp -r 0/wallModelSamplingMulti 0/wallModelSampling"); + ASSERT_EQ(code, 0); autoPtr meshPtr = createMesh(runTime); const fvMesh & mesh = meshPtr(); @@ -366,7 +369,7 @@ TEST_F(SampledPGradTest, RegisterFieldsReadMulticell) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); h.boundaryFieldRef()[patch.index()] == 2; @@ -379,6 +382,7 @@ TEST_F(SampledPGradTest, RegisterFieldsReadMulticell) 3.0, "cell", "Crawling", + "CubeRootVol", true ) ); @@ -476,7 +480,7 @@ TEST_F(SampledPGradTest, SampleMulticell) createSamplingHeightField(mesh); volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); h.boundaryFieldRef()[patch.index()] == 2; @@ -489,6 +493,7 @@ TEST_F(SampledPGradTest, SampleMulticell) 3.0, "cell", "Crawling", + "CubeRootVol", true, false ) diff --git a/tests/samplers/SampledField/testSampledVelocityField.C b/tests/samplers/SampledField/testSampledVelocityField.C index 6721596..488e76d 100644 --- a/tests/samplers/SampledField/testSampledVelocityField.C +++ b/tests/samplers/SampledField/testSampledVelocityField.C @@ -119,7 +119,7 @@ TEST_F(SampledVelocityTest, RegisterFieldsZeroMultiCell) createSamplingHeightField(mesh); volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); h.boundaryFieldRef()[patch.index()] == 2; @@ -131,8 +131,7 @@ TEST_F(SampledVelocityTest, RegisterFieldsZeroMultiCell) patch, 3.0, "cell", - "Crawling", - true + "Crawling" ) ); @@ -240,7 +239,7 @@ TEST_F(SampledVelocityTest, RegisterFieldsInitializeMultiCell) createSamplingHeightField(mesh); volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); h.boundaryFieldRef()[patch.index()] == 3; @@ -253,6 +252,7 @@ TEST_F(SampledVelocityTest, RegisterFieldsInitializeMultiCell) 3.0, "cell", "Crawling", + "CubeRootVol", true ) ); @@ -337,14 +337,16 @@ TEST_F(SampledVelocityTest, RegisterFieldsRead) } -TEST_F(SampledVelocityTest, RegisterFieldsReadMulticell) +TEST_F(SampledVelocityTest, RegisterFieldsReadMultiCell) { extern argList * mainArgs; const argList & args = *mainArgs; Time runTime(Foam::Time::controlDictName, args); // Make previously sampled data readable - system("cp -r 0/wallModelSamplingMulti 0/wallModelSampling"); + auto code = system("cp -r 0/wallModelSamplingMulti 0/wallModelSampling"); + ASSERT_EQ(code, 0); + autoPtr meshPtr = createMesh(runTime); const fvMesh & mesh = meshPtr(); @@ -353,14 +355,14 @@ TEST_F(SampledVelocityTest, RegisterFieldsReadMulticell) volVectorField & U = mesh.lookupObjectRef("U"); // Init U to something varying - U.primitiveFieldRef() = mesh.C(); + //U.primitiveFieldRef() = mesh.C(); const fvPatch & patch = mesh.boundary()["bottomWall"]; createSamplingHeightField(mesh); volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); h.boundaryFieldRef()[patch.index()] == 2; @@ -373,6 +375,7 @@ TEST_F(SampledVelocityTest, RegisterFieldsReadMulticell) 3.0, "cell", "Crawling", + "CubeRootVol", true ) ); @@ -393,6 +396,7 @@ TEST_F(SampledVelocityTest, RegisterFieldsReadMulticell) const scalarListListIOList & sampledFieldIOobject = sampledField.db().lookupObject("U"); + // The mesh has 3 cells in x, 3 in z and 10 in y forAll(sampledFieldIOobject, i) { forAll(sampledFieldIOobject[i], j) @@ -470,7 +474,7 @@ TEST_F(SampledVelocityTest, SampleMulticell) createSamplingHeightField(mesh); volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); h.boundaryFieldRef()[patch.index()] == 2; @@ -483,6 +487,7 @@ TEST_F(SampledVelocityTest, SampleMulticell) 3.0, "cell", "Crawling", + "CubeRootVol", true, false ) @@ -573,8 +578,7 @@ TEST_F(SampledVelocityTest, CheckInterpolationWorks) ASSERT_EQ(sampledValues[i][j], 0); } else - { // Here we just check that pointMVC gives us a different value - // Than stored in the U field cell centres + { ASSERT_FLOAT_EQ ( sampledValues[i][j], @@ -613,8 +617,10 @@ TEST_F(SampledVelocityTest, CheckInterpolationPointOutside) SampledVelocityField sampledField(patch, "cellPointFace"); - labelList indexList(patch.faceCells()); + // we sample from near-wall cell which ends at 0.2 + // but set h to 0.5 + labelList indexList(patch.faceCells()); scalarField h(patch.size(), 0.5); @@ -631,12 +637,11 @@ TEST_F(SampledVelocityTest, CheckInterpolationPointOutside) ASSERT_EQ(sampledValues[i][j], 0); } else - { // Here we just check that pointMVC gives us a different value - // Than stored in the U field cell centres + { ASSERT_FLOAT_EQ ( sampledValues[i][j], - 0.2 + 0.2 // the top value of the cell we sample from ); } } diff --git a/tests/samplers/SampledField/testSampledWallGradUField.C b/tests/samplers/SampledField/testSampledWallGradUField.C index ee7327b..65a814d 100644 --- a/tests/samplers/SampledField/testSampledWallGradUField.C +++ b/tests/samplers/SampledField/testSampledWallGradUField.C @@ -126,7 +126,7 @@ TEST_F(SampledWallGradUTest, RegisterFieldsZeroMultiCell) createSamplingHeightField(mesh); volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); h.boundaryFieldRef()[patch.index()] == 2; @@ -139,6 +139,7 @@ TEST_F(SampledWallGradUTest, RegisterFieldsZeroMultiCell) 3.0, "cell", "Crawling", + "CubeRootVol", true ) ); @@ -237,7 +238,7 @@ TEST_F(SampledWallGradUTest, RegisterInitializeMultiCell) createSamplingHeightField(mesh); volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); h.boundaryFieldRef()[patch.index()] == 2; @@ -250,6 +251,7 @@ TEST_F(SampledWallGradUTest, RegisterInitializeMultiCell) 3.0, "cell", "Crawling", + "CubeRootVol", true ) ); @@ -356,7 +358,7 @@ TEST_F(SampledWallGradUTest, RegisterReadFieldsMultiCell) createSamplingHeightField(mesh); volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); h.boundaryFieldRef()[patch.index()] == 2; @@ -369,6 +371,7 @@ TEST_F(SampledWallGradUTest, RegisterReadFieldsMultiCell) 3.0, "cell", "Crawling", + "CubeRootVol", true ) ); @@ -416,7 +419,7 @@ TEST_F(SampledWallGradUTest, Sample) labelList indexList(patch.size(), -1); // Create wallGradU field - const volScalarField & h = mesh.lookupObject("h"); + const volScalarField & h = mesh.lookupObject("hSampler"); volVectorField & wallGradU = mesh.lookupObjectRef("wallGradU"); diff --git a/tests/samplers/Sampler/testSampler.C b/tests/samplers/Sampler/testSampler.C index 51ba1df..8f7f124 100644 --- a/tests/samplers/Sampler/testSampler.C +++ b/tests/samplers/Sampler/testSampler.C @@ -22,12 +22,14 @@ namespace Foam scalar averagingTime, const word interpolationType, const word cellFinderType, - bool hIsIndex + const word lengthScaleType, + bool hIsIndex, + bool excludeWallAdjacent ) : Sampler(p, averagingTime, interpolationType, cellFinderType, - hIsIndex) + lengthScaleType, hIsIndex, excludeWallAdjacent) {} DummySampler @@ -37,11 +39,13 @@ namespace Foam scalar averagingTime, const word interpolationType, const word cellFinderType, - bool hIsIndex + const word lengthScaleType, + bool hIsIndex, + bool excludeWallAdjacent ) : Sampler(p, averagingTime, interpolationType, cellFinderType, - hIsIndex) + lengthScaleType, hIsIndex, excludeWallAdjacent) {} DummySampler(const DummySampler &) = default; @@ -83,6 +87,8 @@ TEST_F(SamplerTest, FullConstructor) 3.0, "cell", "crawling", + "CubeRootVol", + false, false ); @@ -90,9 +96,11 @@ TEST_F(SamplerTest, FullConstructor) ASSERT_EQ(sampler.Sampler::averagingTime(), 3.0); ASSERT_EQ(sampler.Sampler::interpolationType(), "cell"); ASSERT_EQ(sampler.Sampler::cellFinderType(), "crawling"); + ASSERT_EQ(sampler.Sampler::lengthScaleType(), "CubeRootVol"); ASSERT_EQ(sampler.Sampler::hIsIndex(), false); ASSERT_EQ(&sampler.Sampler::mesh(), &mesh); ASSERT_EQ(sampler.Sampler::nSampledFields(), 0); + ASSERT_EQ(sampler.Sampler::excludeWallAdjacent(), false); ASSERT_TRUE(mesh.foundObject("wallModelSampling")); ASSERT_TRUE ( @@ -121,6 +129,8 @@ TEST_F(SamplerTest, NewNamePatchAveragingTime) 3.0, "cell", "crawling", + "CubeRootVol", + false, false ) ); @@ -130,9 +140,11 @@ TEST_F(SamplerTest, NewNamePatchAveragingTime) ASSERT_EQ(sampler().Sampler::averagingTime(), 3.0); ASSERT_EQ(sampler().Sampler::interpolationType(), "cell"); ASSERT_EQ(sampler().Sampler::cellFinderType(), "crawling"); + ASSERT_EQ(sampler().Sampler::lengthScaleType(), "CubeRootVol"); ASSERT_EQ(sampler().Sampler::hIsIndex(), false); ASSERT_EQ(&sampler().Sampler::mesh(), &mesh); ASSERT_EQ(sampler().Sampler::nSampledFields(), 0); + ASSERT_EQ(sampler().Sampler::excludeWallAdjacent(), false); ASSERT_TRUE(mesh.foundObject("wallModelSampling")); ASSERT_TRUE ( @@ -156,6 +168,7 @@ TEST_F(SamplerTest, NewDictionaryPatch) dict.lookupOrAddDefault(word("interpolationType"), word("cell")); dict.lookupOrAddDefault(word("sampler"), word("Crawling")); dict.lookupOrAddDefault(word("hIsIndex"), false); + dict.lookupOrAddDefault(word("excludeWallAdjacent"), true); const fvPatch & patch = mesh.boundary()["bottomWall"]; autoPtr sampler(Sampler::New(dict, patch)); @@ -168,6 +181,7 @@ TEST_F(SamplerTest, NewDictionaryPatch) ASSERT_EQ(sampler().Sampler::hIsIndex(), false); ASSERT_EQ(&sampler().Sampler::mesh(), &mesh); ASSERT_EQ(sampler().Sampler::nSampledFields(), 0); + ASSERT_EQ(sampler().Sampler::excludeWallAdjacent(), true); ASSERT_TRUE(mesh.foundObject("wallModelSampling")); ASSERT_TRUE ( @@ -193,6 +207,8 @@ TEST_F(SamplerTest, CreateFields) 3.0, "cell", "crawling", + "CubeRootVol", + false, false ); @@ -217,6 +233,8 @@ TEST_F(SamplerTest, Copy) 3.0, "cell", "crawling", + "CubeRootVol", + false, false ); sampler.addField(new SampledVelocityField(patch)); @@ -231,6 +249,7 @@ TEST_F(SamplerTest, Copy) ASSERT_EQ(sampler.hIsIndex(), sampler2.hIsIndex()); ASSERT_EQ(&sampler.mesh(), &sampler2.mesh()); ASSERT_EQ(sampler.nSampledFields(), sampler2.nSampledFields()); + ASSERT_EQ(sampler.excludeWallAdjacent(), sampler2.excludeWallAdjacent()); } @@ -272,6 +291,8 @@ TEST_F(SamplerTest, AddField) 3.0, "cell", "crawling", + "CubeRootVol", + false, false ); diff --git a/tests/samplers/SingleCellSampler/testSingleCellSampler.C b/tests/samplers/SingleCellSampler/testSingleCellSampler.C index 844b875..452d9bd 100644 --- a/tests/samplers/SingleCellSampler/testSingleCellSampler.C +++ b/tests/samplers/SingleCellSampler/testSingleCellSampler.C @@ -33,6 +33,7 @@ TEST_F(SingleCellSamplerTest, ConstructorDefaults) ASSERT_EQ(sampler.averagingTime(), 3.0); ASSERT_EQ(sampler.interpolationType(), "cell"); ASSERT_EQ(sampler.cellFinderType(), "Tree"); + ASSERT_EQ(sampler.lengthScaleType(), "CubeRootVol"); ASSERT_EQ(sampler.hIsIndex(), false); ASSERT_EQ(&sampler.mesh(), &mesh); ASSERT_EQ(sampler.indexList().size(), patch.size()); @@ -58,6 +59,7 @@ TEST_F(SingleCellSamplerTest, ConstructorCellCrawlingHIsIndex) 3.0, "cell", "Crawling", + "CubeRootVol", true ); @@ -65,6 +67,7 @@ TEST_F(SingleCellSamplerTest, ConstructorCellCrawlingHIsIndex) ASSERT_EQ(sampler.averagingTime(), 3.0); ASSERT_EQ(sampler.interpolationType(), "cell"); ASSERT_EQ(sampler.cellFinderType(), "Crawling"); + ASSERT_EQ(sampler.lengthScaleType(), "CubeRootVol"); ASSERT_EQ(sampler.hIsIndex(), true); ASSERT_EQ(&sampler.mesh(), &mesh); ASSERT_EQ(sampler.indexList().size(), patch.size()); @@ -96,6 +99,7 @@ TEST_F(SingleCellSamplerTest, ConstructorCellCrawlingHIsDistance) 3.0, "cell", "Crawling", + "CubeRootVol", false ); @@ -103,6 +107,7 @@ TEST_F(SingleCellSamplerTest, ConstructorCellCrawlingHIsDistance) ASSERT_EQ(sampler.averagingTime(), 3.0); ASSERT_EQ(sampler.interpolationType(), "cell"); ASSERT_EQ(sampler.cellFinderType(), "Crawling"); + ASSERT_EQ(sampler.lengthScaleType(), "CubeRootVol"); ASSERT_EQ(sampler.hIsIndex(), false); ASSERT_EQ(&sampler.mesh(), &mesh); ASSERT_EQ(sampler.indexList().size(), patch.size()); @@ -135,6 +140,7 @@ TEST_F(SingleCellSamplerTest, ConstructorCellPointCrawlingHIsIndex) 3.0, "cellPoint", "Crawling", + "CubeRootVol", true ); @@ -142,6 +148,7 @@ TEST_F(SingleCellSamplerTest, ConstructorCellPointCrawlingHIsIndex) ASSERT_EQ(sampler.averagingTime(), 3.0); ASSERT_EQ(sampler.interpolationType(), "cell"); ASSERT_EQ(sampler.cellFinderType(), "Crawling"); + ASSERT_EQ(sampler.lengthScaleType(), "CubeRootVol"); ASSERT_EQ(sampler.hIsIndex(), true); ASSERT_EQ(&sampler.mesh(), &mesh); ASSERT_EQ(sampler.indexList().size(), patch.size()); @@ -167,7 +174,7 @@ TEST_F(SingleCellSamplerTest, ConstructorCellPointCrawlingHIsDistance) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const fvPatch & patch = mesh.boundary()["bottomWall"]; @@ -181,6 +188,7 @@ TEST_F(SingleCellSamplerTest, ConstructorCellPointCrawlingHIsDistance) 3.0, "cellPoint", "Crawling", + "WallNormalDistance", false ); @@ -188,6 +196,7 @@ TEST_F(SingleCellSamplerTest, ConstructorCellPointCrawlingHIsDistance) ASSERT_EQ(sampler.averagingTime(), 3.0); ASSERT_EQ(sampler.interpolationType(), "cellPoint"); ASSERT_EQ(sampler.cellFinderType(), "Crawling"); + ASSERT_EQ(sampler.lengthScaleType(), "WallNormalDistance"); ASSERT_EQ(sampler.hIsIndex(), false); ASSERT_EQ(&sampler.mesh(), &mesh); ASSERT_EQ(sampler.indexList().size(), patch.size()); @@ -214,7 +223,7 @@ TEST_F(SingleCellSamplerTest, ConstructorCellPointCrawlingHIsDistanceFirstCell) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const fvPatch & patch = mesh.boundary()["bottomWall"]; @@ -228,6 +237,7 @@ TEST_F(SingleCellSamplerTest, ConstructorCellPointCrawlingHIsDistanceFirstCell) 3.0, "cellPoint", "Crawling", + "CubeRootVol", false ); @@ -235,6 +245,7 @@ TEST_F(SingleCellSamplerTest, ConstructorCellPointCrawlingHIsDistanceFirstCell) ASSERT_EQ(sampler.averagingTime(), 3.0); ASSERT_EQ(sampler.interpolationType(), "cellPoint"); ASSERT_EQ(sampler.cellFinderType(), "Crawling"); + ASSERT_EQ(sampler.lengthScaleType(), "CubeRootVol"); ASSERT_EQ(sampler.hIsIndex(), false); ASSERT_EQ(&sampler.mesh(), &mesh); ASSERT_EQ(sampler.indexList().size(), patch.size()); @@ -270,6 +281,7 @@ TEST_F(SingleCellSamplerTest, ConstructorCellTreeHIsIndex) 3.0, "cell", "Tree", + "CubeRootVol", true ); }, @@ -296,6 +308,7 @@ TEST_F(SingleCellSamplerTest, ConstructorCellTreeHIsDistance) 3.0, "cell", "Tree", + "CubeRootVol", false ); @@ -303,6 +316,7 @@ TEST_F(SingleCellSamplerTest, ConstructorCellTreeHIsDistance) ASSERT_EQ(sampler.averagingTime(), 3.0); ASSERT_EQ(sampler.interpolationType(), "cell"); ASSERT_EQ(sampler.cellFinderType(), "Tree"); + ASSERT_EQ(sampler.lengthScaleType(), "CubeRootVol"); ASSERT_EQ(sampler.hIsIndex(), false); ASSERT_EQ(&sampler.mesh(), &mesh); ASSERT_EQ(sampler.indexList().size(), patch.size()); @@ -327,7 +341,7 @@ TEST_F(SingleCellSamplerTest, ConstructorCellPointTreeHIsDistance) createSamplingHeightField(mesh); volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const fvPatch & patch = mesh.boundary()["bottomWall"]; @@ -341,6 +355,7 @@ TEST_F(SingleCellSamplerTest, ConstructorCellPointTreeHIsDistance) 3.0, "cellPoint", "Tree", + "CubeRootVol", false ); @@ -348,6 +363,7 @@ TEST_F(SingleCellSamplerTest, ConstructorCellPointTreeHIsDistance) ASSERT_EQ(sampler.averagingTime(), 3.0); ASSERT_EQ(sampler.interpolationType(), "cellPoint"); ASSERT_EQ(sampler.cellFinderType(), "Tree"); + ASSERT_EQ(sampler.lengthScaleType(), "CubeRootVol"); ASSERT_EQ(sampler.hIsIndex(), false); ASSERT_EQ(&sampler.mesh(), &mesh); ASSERT_EQ(sampler.indexList().size(), patch.size()); @@ -374,7 +390,7 @@ TEST_F(SingleCellSamplerTest, ConstructorCellPointTreeHIsDistanceFirstCell) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); const fvPatch & patch = mesh.boundary()["bottomWall"]; @@ -388,6 +404,7 @@ TEST_F(SingleCellSamplerTest, ConstructorCellPointTreeHIsDistanceFirstCell) 3.0, "cellPoint", "Tree", + "CubeRootVol", false ); @@ -395,6 +412,7 @@ TEST_F(SingleCellSamplerTest, ConstructorCellPointTreeHIsDistanceFirstCell) ASSERT_EQ(sampler.averagingTime(), 3.0); ASSERT_EQ(sampler.interpolationType(), "cellPoint"); ASSERT_EQ(sampler.cellFinderType(), "Tree"); + ASSERT_EQ(sampler.lengthScaleType(), "CubeRootVol"); ASSERT_EQ(sampler.hIsIndex(), false); ASSERT_EQ(&sampler.mesh(), &mesh); ASSERT_EQ(sampler.indexList().size(), patch.size()); @@ -424,7 +442,7 @@ TEST_F(SingleCellSamplerTest, Sample) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); h.boundaryFieldRef()[patch.index()] == 3; @@ -443,6 +461,7 @@ TEST_F(SingleCellSamplerTest, Sample) 0.02, "cell", "Crawling", + "CubeRootVol", 3 ); @@ -477,7 +496,7 @@ TEST_F(SingleCellSamplerTest, AddField) volScalarField & h = const_cast ( - mesh.thisDb().lookupObject("h") + mesh.thisDb().lookupObject("hSampler") ); h.boundaryFieldRef()[patch.index()] == 3; @@ -492,6 +511,7 @@ TEST_F(SingleCellSamplerTest, AddField) 0.02, "cell", "Crawling", + "CubeRootVol", 3 ); @@ -499,4 +519,76 @@ TEST_F(SingleCellSamplerTest, AddField) ASSERT_EQ(sampler.nSampledFields(), 3); ASSERT_TRUE(sampler.db().foundObject("pGrad")); +} + + +TEST_F(SingleCellSamplerTest, createLengthListCubeRootVol) +{ + extern argList * mainArgs; + const argList & args = *mainArgs; + Time runTime(Foam::Time::controlDictName, args); + + autoPtr meshPtr = createMesh(runTime); + const fvMesh & mesh = meshPtr(); + createSamplingHeightField(mesh); + + volScalarField & h = const_cast + ( + mesh.thisDb().lookupObject("hSampler") + ); + + const fvPatch & patch = mesh.boundary()["bottomWall"]; + + h.boundaryFieldRef()[patch.index()] == 0.5; + + SingleCellSampler sampler + ( + "SingleCellSampler", + patch, + 3.0 + ); + + ASSERT_EQ(sampler.lengthList().size(), patch.size()); + + for (int i=0; i< sampler.lengthList().size(); i++) + { + ASSERT_FLOAT_EQ(sampler.lengthList()[i], 0.9283177667225558); + } +} + +TEST_F(SingleCellSamplerTest, createLengthListWallNormalDistance) +{ + extern argList * mainArgs; + const argList & args = *mainArgs; + Time runTime(Foam::Time::controlDictName, args); + + autoPtr meshPtr = createMesh(runTime); + const fvMesh & mesh = meshPtr(); + createSamplingHeightField(mesh); + + volScalarField & h = const_cast + ( + mesh.thisDb().lookupObject("hSampler") + ); + + const fvPatch & patch = mesh.boundary()["bottomWall"]; + + h.boundaryFieldRef()[patch.index()] == 0.5; + + SingleCellSampler sampler + ( + "SingleCellSampler", + patch, + 3.0, + "cell", + "Crawling", + "WallNormalDistance" + ); + + ASSERT_EQ(sampler.lengthList().size(), patch.size()); + + for (int i=0; i< sampler.lengthList().size(); i++) + { + ASSERT_FLOAT_EQ(sampler.lengthList()[i], 0.2); + } } \ No newline at end of file diff --git a/tests/testCases/channel_flow/0/hSampler b/tests/testCases/channel_flow/0/hSampler new file mode 100755 index 0000000..802793f --- /dev/null +++ b/tests/testCases/channel_flow/0/hSampler @@ -0,0 +1,54 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 3.0.1 | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object hSampler; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 1 0 0 0 0 0]; + +internalField uniform 0; + +boundaryField +{ + inlet + { + type cyclic; + } + outlet + { + type cyclic; + } + bottomWall + { + type fixedValue; + value uniform 0.11; + } + topWall + { + type fixedValue; + //value uniform 0.01; + value uniform 0; + } + left + { + type cyclic; + } + right + { + type cyclic; + } +} + + +// ************************************************************************* // diff --git a/tests/testCases/channel_flow/0/nut b/tests/testCases/channel_flow/0/nut index fe7fb66..4c1200a 100755 --- a/tests/testCases/channel_flow/0/nut +++ b/tests/testCases/channel_flow/0/nut @@ -24,7 +24,7 @@ boundaryField bottomWall { /* * * * * * * * * Law of the wall wall model * * * * * * */ - type LOTWWallModel; + type MulticellLOTWWallModel; //type LSQRWallModel; // value uniform 0; //redundant // @@ -43,8 +43,9 @@ boundaryField } sampler Crawling; - interpolationType cellPointFace; + interpolationType cell; hIsIndex false; + silent false; diff --git a/tests/testCases/channel_flow/0/wallModelSamplingMulti/bottomWall/U b/tests/testCases/channel_flow/0/wallModelSamplingMulti/bottomWall/U new file mode 100644 index 0000000..ae94b6e --- /dev/null +++ b/tests/testCases/channel_flow/0/wallModelSamplingMulti/bottomWall/U @@ -0,0 +1,34 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 2212 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + arch "LSB;label=32;scalar=64"; + class scalarListListList; + location "0.01/wallModelSampling/bottomWall"; + object U; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + + +9 +( +1(3(1 2 3)) +1(3(1 2 3)) +1(3(1 2 3)) +1(3(1 2 3)) +1(3(1 2 3)) +1(3(1 2 3)) +1(3(1 2 3)) +1(3(1 2 3)) +1(3(1 2 3)) +) + + +// ************************************************************************* // diff --git a/tests/testCases/channel_flow/0/wallModelSamplingMulti/bottomWall/pGrad b/tests/testCases/channel_flow/0/wallModelSamplingMulti/bottomWall/pGrad new file mode 100644 index 0000000..82d3b87 --- /dev/null +++ b/tests/testCases/channel_flow/0/wallModelSamplingMulti/bottomWall/pGrad @@ -0,0 +1,34 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 2212 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + arch "LSB;label=32;scalar=64"; + class scalarListListList; + location "0/wallModelSampling/bottomWall"; + object pGrad; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + + +9 +( +1(3(1 2 3)) +1(3(1 2 3)) +1(3(1 2 3)) +1(3(1 2 3)) +1(3(1 2 3)) +1(3(1 2 3)) +1(3(1 2 3)) +1(3(1 2 3)) +1(3(1 2 3)) +) + + +// ************************************************************************* // diff --git a/tests/testCases/channel_flow/0/wallModelSamplingMulti/bottomWall/wallGradU b/tests/testCases/channel_flow/0/wallModelSamplingMulti/bottomWall/wallGradU new file mode 100644 index 0000000..ae94b6e --- /dev/null +++ b/tests/testCases/channel_flow/0/wallModelSamplingMulti/bottomWall/wallGradU @@ -0,0 +1,34 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 2212 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + arch "LSB;label=32;scalar=64"; + class scalarListListList; + location "0.01/wallModelSampling/bottomWall"; + object U; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + + +9 +( +1(3(1 2 3)) +1(3(1 2 3)) +1(3(1 2 3)) +1(3(1 2 3)) +1(3(1 2 3)) +1(3(1 2 3)) +1(3(1 2 3)) +1(3(1 2 3)) +1(3(1 2 3)) +) + + +// ************************************************************************* // diff --git a/tests/testCases/channel_flow/0/wallModelSamplingSingle/bottomWall/pGrad b/tests/testCases/channel_flow/0/wallModelSamplingSingle/bottomWall/pGrad new file mode 100644 index 0000000..0767305 --- /dev/null +++ b/tests/testCases/channel_flow/0/wallModelSamplingSingle/bottomWall/pGrad @@ -0,0 +1,33 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v1812 | +| \\ / A nd | Web: www.OpenFOAM.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class scalarListList; + location "0/wallModelSampling/bottomWall"; + object pGrad; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + + +9 +( +3(1 1 1) +3(2 2 2) +3(3 3 3) +3(4 4 4) +3(5 5 5) +3(6 6 6) +3(7 7 7) +3(8 8 8) +3(9 9 9) +) + + +// ************************************************************************* // diff --git a/tests/testCases/channel_flow/system/controlDict b/tests/testCases/channel_flow/system/controlDict index 56a0c48..3a6982f 100755 --- a/tests/testCases/channel_flow/system/controlDict +++ b/tests/testCases/channel_flow/system/controlDict @@ -61,6 +61,8 @@ DebugSwitches // ODEWallModel 2; // EquilibriumODEWallModel 2; // JohnsonKing 1; +// SampledVelocityField 0; +// SampledWallGradUField 1; } diff --git a/tests/testCases/channel_flow/system/setNutKnownWallShearStress b/tests/testCases/channel_flow/system/setNutKnownWallShearStress new file mode 100644 index 0000000..dc9f178 --- /dev/null +++ b/tests/testCases/channel_flow/system/setNutKnownWallShearStress @@ -0,0 +1,29 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 2.3.0 | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object changeDictionaryDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +nut +{ + boundaryField + { + bottomWall + { + type KnownWallShearStressWallModel; + value uniform 0; + } + } +} + +// ************************************************************************* // diff --git a/tests/testCases/channel_flow/system/setNutLOTWRoughLogLaw b/tests/testCases/channel_flow/system/setNutLOTWRoughLogLaw new file mode 100644 index 0000000..2fbdff0 --- /dev/null +++ b/tests/testCases/channel_flow/system/setNutLOTWRoughLogLaw @@ -0,0 +1,39 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 2.3.0 | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object changeDictionaryDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +nut +{ + boundaryField + { + bottomWall + { + type LOTWWallModel; + value uniform 0; + RootFinder + { + type Newton; + } + Law + { + type RoughLogLaw; + ks 0.1; + B 4; + } + } + } +} + +// ************************************************************************* // diff --git a/tests/wallModels/testWallModel.C b/tests/wallModels/testWallModel.C index 1d84aab..73cc975 100644 --- a/tests/wallModels/testWallModel.C +++ b/tests/wallModels/testWallModel.C @@ -72,7 +72,7 @@ namespace Foam ( fvPatchScalarField, DummyWallModel - ) + ); } class WallModelTest : public ChannelFlow @@ -108,7 +108,7 @@ TEST_F(WallModelTest, ConstructorW1) ASSERT_FLOAT_EQ(model.averagingTime(), 0.0); ASSERT_FLOAT_EQ(model.consumedTime(), 0.0); ASSERT_EQ(model.copyToPatchInternalField(), false); - ASSERT_TRUE(mesh.foundObject("h")); + ASSERT_TRUE(mesh.foundObject("hSampler")); ASSERT_TRUE(mesh.foundObject("wallShearStress")); ASSERT_TRUE(mesh.foundObject("uTauPredicted")); ASSERT_TRUE(mesh.foundObject("wallGradU")); @@ -169,7 +169,7 @@ TEST_F(WallModelTest, ConstructorW3) ASSERT_FLOAT_EQ(model.consumedTime(), 0.0); ASSERT_EQ(model.copyToPatchInternalField(), true); - ASSERT_TRUE(mesh.foundObject("h")); + ASSERT_TRUE(mesh.foundObject("hSampler")); ASSERT_TRUE(mesh.foundObject("wallShearStress")); ASSERT_TRUE(mesh.foundObject("uTauPredicted")); ASSERT_TRUE(mesh.foundObject("wallGradU")); diff --git a/versionRules/codeRules.H b/versionRules/codeRules.H index 7a070a9..3870110 100644 --- a/versionRules/codeRules.H +++ b/versionRules/codeRules.H @@ -19,7 +19,7 @@ License Class -Description +@brief Based on the OpenFOAM version, generates macros that can be used to make the code support multiple versions via #ifdef statements. The file is adopted with minor changes from swak4foam, see list of @@ -31,7 +31,7 @@ Contributors/Copyright: 2012-2018 Bernhard F.W. Gschaider 2015-2016 Bruno Santos 2016-2018 Mark Olesen - 2019-2021 Timofey Mukha + 2019-2023 Timofey Mukha \*---------------------------------------------------------------------------*/ @@ -171,6 +171,22 @@ Contributors/Copyright: #define FOAM_FVPATCHFIELD_NO_COPY #endif +#if (defined(FOAM_VERSION4WMLES_IS_ORG)) +#define FOAM_DICTIONARY_NO_GET +#endif + +#if (defined(FOAM_VERSION4WMLES_IS_ORG) && FOAM_VERSION4WMLES>=VERSION_NR(8,0,0)) +#define FOAM_DICTIONARY_HAS_LOOKUP +#endif + +#if (defined(FOAM_VERSION4SWAK_IS_ORG) && FOAM_VERSION4SWAK >= VERSION_NR(9, 0, 0)) +#define FOAM_FLUID_MOMENTUM_TRANSPORT_IS_NOW_DYNAMIC +#endif + +#if (defined(FOAM_VERSION4SWAK_IS_ORG) && FOAM_VERSION4SWAK >= VERSION_NR(10, 0, 0)) +#define FOAM_FLUID_MOMENTUM_TRANSPORT_IS_NO_LONGER_DYNAMIC +#endif + #endif // ************************************************************************* // diff --git a/wallModels/EquilibriumODEWallModelFvPatchScalarField.H b/wallModels/EquilibriumODEWallModelFvPatchScalarField.H index 60eccb7..11005e5 100644 --- a/wallModels/EquilibriumODEWallModelFvPatchScalarField.H +++ b/wallModels/EquilibriumODEWallModelFvPatchScalarField.H @@ -19,7 +19,7 @@ License Class Foam::EquilibriumODEWallModelFvPatchScalarField -Description +@brief ODE model with a zero source-term. Physically, this means that the total shear stress is assumed to be constant diff --git a/wallModels/KnownWallShearStressWallModelFvPatchScalarField.H b/wallModels/KnownWallShearStressWallModelFvPatchScalarField.H index 4dbde34..4ab6455 100644 --- a/wallModels/KnownWallShearStressWallModelFvPatchScalarField.H +++ b/wallModels/KnownWallShearStressWallModelFvPatchScalarField.H @@ -19,7 +19,7 @@ License Class Foam::KnownWallShearStressWallModelFvPatchScalarField -Description +@brief Wall model that uses the values of the magnitude of the mean wall shear stress known a priori, for example, from a RANS precursor or an analytical solution. diff --git a/wallModels/LOTWWallModelFvPatchScalarField.C b/wallModels/LOTWWallModelFvPatchScalarField.C index 4465bb3..203d192 100644 --- a/wallModels/LOTWWallModelFvPatchScalarField.C +++ b/wallModels/LOTWWallModelFvPatchScalarField.C @@ -50,11 +50,8 @@ Foam::LOTWWallModelFvPatchScalarField::calcNut() const const label patchi = patch().index(); - const volScalarField & nuField = db().lookupObject("nu"); + tmp nuw = this->nu(patchi); - // Velocity and viscosity on boundary - const fvPatchScalarField & nuw = nuField.boundaryField()[patchi]; - const scalarListIOList & wallGradU = sampler_->db().lookupObject("wallGradU"); @@ -74,10 +71,8 @@ calcUTau(const scalarField & magGradU) const const label patchi = patch().index(); const label patchSize = patch().size(); - const volScalarField & nuField = db().lookupObject("nu"); - - // Velocity and viscosity on boundary - const fvPatchScalarField & nuw = nuField.boundaryField()[patchi]; + tmp tnuw = this->nu(patchi); + const scalarField& nuw = tnuw(); // Turbulent viscosity const scalarField & nutw = *this; @@ -211,6 +206,7 @@ LOTWWallModelFvPatchScalarField averagingTime(), dict.lookupOrDefault("interpolationType", "cell"), dict.lookupOrDefault("sampler", "Tree"), + dict.lookupOrDefault("lengthScale", "CubeRootVol"), dict.lookupOrDefault("hIsIndex", false) ) ) diff --git a/wallModels/LOTWWallModelFvPatchScalarField.H b/wallModels/LOTWWallModelFvPatchScalarField.H index 71b5e91..7f04a46 100644 --- a/wallModels/LOTWWallModelFvPatchScalarField.H +++ b/wallModels/LOTWWallModelFvPatchScalarField.H @@ -19,7 +19,7 @@ License Class Foam::LOTWWallModelFvPatchScalarField -Description +@brief Class for the wall models based on a law of the wall. Needs a root finder and a law of the wall to be defined. diff --git a/wallModels/MulticellLOTWWallModelFvPatchScalarField.C b/wallModels/MulticellLOTWWallModelFvPatchScalarField.C new file mode 100644 index 0000000..9bd5af1 --- /dev/null +++ b/wallModels/MulticellLOTWWallModelFvPatchScalarField.C @@ -0,0 +1,330 @@ +/*---------------------------------------------------------------------------* \ +License + This file is part of libWallModelledLES. + + libWallModelledLES is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + libWallModelledLES is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with libWallModelledLES. + If not, see . + +\*---------------------------------------------------------------------------*/ + +#include "MulticellLOTWWallModelFvPatchScalarField.H" +#include "fvPatchFieldMapper.H" +#include "addToRunTimeSelectionTable.H" +#include "codeRules.H" +#include "scalarListIOList.H" +#include "helpers.H" +#include "IntegratedReichardtLawOfTheWall.H" +#include "RootFinder.H" +#include "MultiCellSampler.H" + +using namespace std::placeholders; + +// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // + +void Foam::MulticellLOTWWallModelFvPatchScalarField::writeLocalEntries(Ostream& os) const +{ + wallModelFvPatchScalarField::writeLocalEntries(os); + rootFinder_->write(os); + law_->write(os); + sampler_->write(os); +} + +Foam::tmp +Foam::MulticellLOTWWallModelFvPatchScalarField::calcNut() const +{ + if (debug) + { + Info<< "Updating nut for patch " << patch().name() << nl; + } + + const label patchi = patch().index(); + + const auto & nuField = db().lookupObject("nu"); + + // Velocity and viscosity on boundary + const fvPatchScalarField & nuw = nuField.boundaryField()[patchi]; + + const auto & wallGradUField = + db().lookupObject("wallGradU"); + + const vectorField & wallGradU = + wallGradUField.boundaryField()[patch().index()]; + +// const scalarListIOList & wallGradU = +// sampler_->db().lookupObject("wallGradU"); + + scalarField magGradU(mag(wallGradU)); + + return max + ( + scalar(0), + sqr(calcUTau(magGradU))/(magGradU + ROOTVSMALL) - nuw + ); +} + +Foam::tmp +Foam::MulticellLOTWWallModelFvPatchScalarField:: +calcUTau(const scalarField & magGradU) const +{ + const label patchi = patch().index(); + const label patchSize = patch().size(); + + const volScalarField & nuField = db().lookupObject("nu"); + + // Velocity and viscosity on boundary + const fvPatchScalarField & nuw = nuField.boundaryField()[patchi]; + + // Turbulent viscosity + const scalarField & nutw = *this; + + // Computed uTau + tmp tuTau(new scalarField(patchSize, 0.0)); + scalarField & uTau = +#ifdef FOAM_NEW_TMP_RULES + tuTau.ref(); +#else + tuTau(); +#endif + + // Function to give to the root finder + std::function value; + std::function derivValue; + + // Grab global uTau field + volScalarField & uTauField = + const_cast + ( + db().lookupObject("uTauPredicted") + ); + + // Compute uTau for each face + forAll(uTau, faceI) + { + // Starting guess using old values + scalar ut = sqrt((nuw[faceI] + nutw[faceI])*magGradU[faceI]); + + if (ut > ROOTVSMALL) + { + + // Construct functions dependant on a single parameter (uTau) + // from functions given by the law of the wall + value = + std::bind(&IntegratedReichardtLawOfTheWall::valueMulticell, + &law_(), std::ref(sampler_()), faceI, _1, nuw[faceI]); + + derivValue = + std::bind(&IntegratedReichardtLawOfTheWall::derivativeMulticell, + &law_(), std::ref(sampler_()), faceI, _1, nuw[faceI]); + + // Supply the functions to the root finder + const_cast(rootFinder_()).setFunction(value); + const_cast(rootFinder_()).setDerivative(derivValue); + + // Compute root to get uTau + uTau[faceI] = max(0.0, rootFinder_->root(ut)); + + } + } + + // Assign computed uTau to the boundary field of the global field +#ifdef FOAM_NEW_GEOMFIELD_RULES + uTauField.boundaryFieldRef()[patchi] +#else + uTauField.boundaryField()[patchi] +#endif + == + uTau; + return tuTau; +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::MulticellLOTWWallModelFvPatchScalarField:: +MulticellLOTWWallModelFvPatchScalarField +( + const fvPatch & p, + const DimensionedField & iF +) +: + wallModelFvPatchScalarField(p, iF), + rootFinder_(), + law_(), + sampler_(nullptr) +{ + if (debug) + { + Info<< "Constructing MulticellLOTWwallModelFvPatchScalarField (lotw1) " + << "from fvPatch and DimensionedField for patch " << patch().name() + << nl; + } +} + + +Foam::MulticellLOTWWallModelFvPatchScalarField:: +MulticellLOTWWallModelFvPatchScalarField +( + const MulticellLOTWWallModelFvPatchScalarField & orig, + const fvPatch & p, + const DimensionedField & iF, + const fvPatchFieldMapper & mapper +) +: + wallModelFvPatchScalarField(orig, p, iF, mapper), +#ifdef FOAM_AUTOPTR_HAS_CLONE_METHOD + rootFinder_(orig.rootFinder_.clone()), + law_(new IntegratedReichardtLawOfTheWall()), +#else + rootFinder_(orig.rootFinder_, false), + //law_(orig.law_, false), + law_(new IntegratedReichardtLawOfTheWall()), +#endif + sampler_(new MultiCellSampler(orig.sampler())) +{ + if (debug) + { + Info<< "Constructing MulticellLOTWWallModelFvPatchScalarField (lotw2) " + << "from copy, fvPatch, DimensionedField, and fvPatchFieldMapper" + << " for patch " << patch().name() << nl; + } + law_->addFieldsToSampler(sampler()); +} + +Foam::MulticellLOTWWallModelFvPatchScalarField:: +MulticellLOTWWallModelFvPatchScalarField +( + const fvPatch & p, + const DimensionedField & iF, + const dictionary & dict +) +: + wallModelFvPatchScalarField(p, iF, dict), + rootFinder_(RootFinder::New(dict.subDict("RootFinder"))), + law_(new IntegratedReichardtLawOfTheWall()), + sampler_ + ( + new MultiCellSampler + ( + p, + averagingTime(), + dict.lookupOrDefault("interpolationType", "cell"), + dict.lookupOrDefault("sampler", "Tree"), + dict.lookupOrDefault("lengthScale", "CubeRootVol"), + dict.lookupOrDefault("hIsIndex", false), + dict.lookupOrDefault("excludeAdjacent", false) + ) + ) +{ + if (debug) + { + Info<< "Constructing MulticellLOTWWallModelFvPatchScalarField (lotw3) " + << "from fvPatch, DimensionedField, and dictionary for patch " + << patch().name() << nl; + } + law_->addFieldsToSampler(sampler()); +} + + +#ifdef FOAM_FVPATCHFIELD_NO_COPY +#else +Foam::MulticellLOTWWallModelFvPatchScalarField:: +MulticellLOTWWallModelFvPatchScalarField +( + const MulticellLOTWWallModelFvPatchScalarField & orig +) +: + wallModelFvPatchScalarField(orig), +#ifdef FOAM_AUTOPTR_HAS_CLONE_METHOD + rootFinder_(orig.rootFinder_.clone()), + law_(new IntegratedReichardtLawOfTheWall()), +#else + rootFinder_(orig.rootFinder_, false), + //law_(orig.law_, false), + law_(new IntegratedReichardtLawOfTheWall()), +#endif + sampler_(new MultiCellSampler(orig.sampler_())) +{ + if (debug) + { + Info<< "Constructing MulticellLOTWWallModelFvPatchScalarField (lotw4)" + << "from copy for patch " << patch().name() << nl; + } + law_->addFieldsToSampler(sampler()); +} +#endif + + +Foam::MulticellLOTWWallModelFvPatchScalarField:: +MulticellLOTWWallModelFvPatchScalarField +( + const MulticellLOTWWallModelFvPatchScalarField & orig, + const DimensionedField & iF +) +: + wallModelFvPatchScalarField(orig, iF), +#ifdef FOAM_AUTOPTR_HAS_CLONE_METHOD + rootFinder_(orig.rootFinder_.clone()), + law_(new IntegratedReichardtLawOfTheWall()), +#else + rootFinder_(orig.rootFinder_, false), + //law_(orig.law_, false), + law_(new IntegratedReichardtLawOfTheWall()), +#endif + sampler_(new MultiCellSampler(orig.sampler_())) +{ + + if (debug) + { + Info<< "Constructing MulticellLOTWModelFvPatchScalarField (lotw5) " + << "from copy and DimensionedField for patch " << patch().name() + << nl; + } + law_->addFieldsToSampler(sampler()); +} + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::MulticellLOTWWallModelFvPatchScalarField::write(Ostream& os) const +{ + wallModelFvPatchScalarField::write(os); +} + + +void Foam::MulticellLOTWWallModelFvPatchScalarField::updateCoeffs() +{ + if (updated()) + { + return; + } + + sampler().recomputeFields(); + sampler().sample(); + + wallModelFvPatchScalarField::updateCoeffs(); +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#if !defined(DOXYGEN_SHOULD_SKIP_THIS) +namespace Foam +{ + makePatchTypeField + ( + fvPatchScalarField, + MulticellLOTWWallModelFvPatchScalarField + ); +} +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/wallModels/MulticellLOTWWallModelFvPatchScalarField.H b/wallModels/MulticellLOTWWallModelFvPatchScalarField.H new file mode 100644 index 0000000..3b70d65 --- /dev/null +++ b/wallModels/MulticellLOTWWallModelFvPatchScalarField.H @@ -0,0 +1,198 @@ +/*---------------------------------------------------------------------------* \ +License + This file is part of libWallModelledLES. + + libWallModelledLES is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + libWallModelledLES is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with libWallModelledLES. + If not, see . + +Class + Foam::MulticellLOTWWallModelFvPatchScalarField + +@brief + Class for the wall models based on a law of the wall, sampling data + from multiple cells. Currently hardcoded to use the integrated + Reichardt law. + + Needs a root finder to be defined. + + Usage + \verbatim + patchName + { + type MulticellLOTWWallModel; + value uniform 0; + RootFinder + { + type RootFinderType; + otherParams value; + } + } + \endverbatim + +Contributors/Copyright: + 2016-2019 Timofey Mukha + 2017 Saleh Rezaeiravesh + +SourceFiles + MulticellLOTWWallModelFvPatchScalarField.C + +\*---------------------------------------------------------------------------*/ + +#ifndef MulticellLOTWWallModelFvPatchScalarField_H +#define MulticellLOTWWallModelFvPatchScalarField_H + +#include "wallModelFvPatchScalarField.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +class RootFinder; +class IntegratedReichardtLawOfTheWall; +class MultiCellSampler; + +/*---------------------------------------------------------------------------*\ + Class MulticellLOTWWallModelPatchScalarField Declaration +\*---------------------------------------------------------------------------*/ + +class MulticellLOTWWallModelFvPatchScalarField +: + public wallModelFvPatchScalarField +{ +protected: + + // Protected Data + + //- Pointer to the root finder + autoPtr rootFinder_; + + //- Pointer to the MulticellLOTW to be used + autoPtr law_; + + //- The sampler + autoPtr sampler_; + + // Protected Member Functions + //- Write root finder and MulticellLOTW properties to stream + virtual void writeLocalEntries(Ostream &) const; + + //- Calculate the turbulence viscosity + virtual tmp calcNut() const; + + //- Calculate the friction velocity + virtual tmp calcUTau(const scalarField & magGradU) const; + + + +public: + +#if !defined(DOXYGEN_SHOULD_SKIP_THIS) + //- Runtime type information + TypeName("MulticellLOTWWallModel"); +#endif + + + // Constructors + + //- Construct from patch and internal field + MulticellLOTWWallModelFvPatchScalarField + ( + const fvPatch&, + const DimensionedField& + ); + + //- Construct from patch, internal field and dictionary + MulticellLOTWWallModelFvPatchScalarField + ( + const fvPatch&, + const DimensionedField&, + const dictionary& + ); + + //- Construct by mapping given + // MulticellLOTWWallModelFvPatchScalarField + // onto a new patch + MulticellLOTWWallModelFvPatchScalarField + ( + const MulticellLOTWWallModelFvPatchScalarField&, + const fvPatch&, + const DimensionedField&, + const fvPatchFieldMapper& + ); + + #ifdef FOAM_FVPATCHFIELD_NO_COPY + #else + //- Construct as copy + MulticellLOTWWallModelFvPatchScalarField + ( + const MulticellLOTWWallModelFvPatchScalarField& + ); + #endif + + //- Construct and return a clone + virtual tmp clone() const + { + return tmp + ( + new MulticellLOTWWallModelFvPatchScalarField(*this) + ); + } + + //- Construct as copy setting internal field reference + MulticellLOTWWallModelFvPatchScalarField + ( + const MulticellLOTWWallModelFvPatchScalarField&, + const DimensionedField& + ); + + //- Construct and return a clone setting internal field reference + virtual tmp clone + ( + const DimensionedField& iF + ) const + { + return tmp + ( + new MulticellLOTWWallModelFvPatchScalarField(*this, iF) + ); + } + + // Member functions + + MultiCellSampler & sampler() + { + return sampler_(); + } + + const MultiCellSampler & sampler() const + { + return sampler_(); + } + + virtual void updateCoeffs(); + + //- Write to stream + virtual void write(Ostream& os) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + + +#endif diff --git a/wallModels/ODEWallModelFvPatchScalarField.C b/wallModels/ODEWallModelFvPatchScalarField.C index 1a4d5ba..aa33e46 100644 --- a/wallModels/ODEWallModelFvPatchScalarField.C +++ b/wallModels/ODEWallModelFvPatchScalarField.C @@ -107,10 +107,7 @@ Foam::ODEWallModelFvPatchScalarField::calcNut() const const label patchi = patch().index(); - const volScalarField & nuField = db().lookupObject("nu"); - - // Velocity and viscosity on boundary - const fvPatchScalarField & nuw = nuField.boundaryField()[patchi]; + tmp nuw = this->nu(patchi); const scalarListIOList & wallGradU = sampler_->db().lookupObject("wallGradU"); @@ -132,10 +129,8 @@ calcUTau(const scalarField & magGradU) const const label patchi = patch().index(); const label patchSize = patch().size(); - const volScalarField & nuField = db().lookupObject("nu"); - - // Velocity and viscosity on boundary - const fvPatchScalarField & nuw = nuField.boundaryField()[patchi]; + tmp tnuw = this->nu(patchi); + const scalarField& nuw = tnuw(); // vectorField for storing the source term vectorField sourceField(patchSize, vector(0, 0, 0)); @@ -328,6 +323,7 @@ ODEWallModelFvPatchScalarField averagingTime(), dict.lookupOrDefault("interpolationType", "cell"), dict.lookupOrDefault("sampler", "Tree"), + dict.lookupOrDefault("lengthScaleType", "CubeRootVol"), dict.lookupOrDefault("hIsIndex", false) ) ), diff --git a/wallModels/ODEWallModelFvPatchScalarField.H b/wallModels/ODEWallModelFvPatchScalarField.H index 9ad4499..cbc16fe 100644 --- a/wallModels/ODEWallModelFvPatchScalarField.H +++ b/wallModels/ODEWallModelFvPatchScalarField.H @@ -19,7 +19,7 @@ License Class Foam::ODEWallModelFvPatchScalarField -Description +@brief Base abstract class for ODE-based wall models. All the models are based on the following equation diff --git a/wallModels/PGradODEWallModelFvPatchScalarField.H b/wallModels/PGradODEWallModelFvPatchScalarField.H index 86991c1..8a2e50b 100755 --- a/wallModels/PGradODEWallModelFvPatchScalarField.H +++ b/wallModels/PGradODEWallModelFvPatchScalarField.H @@ -19,7 +19,7 @@ License Class Foam::PGradODEWallModelFvPatchScalarField -Description +@brief ODE wall model with the source term equal to the wall-parallel pressure gradient. diff --git a/wallModels/wallModelFvPatchScalarField.C b/wallModels/wallModelFvPatchScalarField.C index 534d11d..32736f0 100644 --- a/wallModels/wallModelFvPatchScalarField.C +++ b/wallModels/wallModelFvPatchScalarField.C @@ -19,6 +19,7 @@ License \*---------------------------------------------------------------------------*/ #include "wallModelFvPatchScalarField.H" +#include "turbulenceModel.H" #include "meshSearch.H" #include "wallFvPatch.H" #include "codeRules.H" @@ -55,11 +56,66 @@ void Foam::wallModelFvPatchScalarField::writeLocalEntries(Ostream& os) const << averagingTime_ << token::END_STATEMENT << nl; os.writeKeyword("copyToPatchInternalField") << copyToPatchInternalField_ << token::END_STATEMENT << nl; + os.writeKeyword("silent") + << silent_ << token::END_STATEMENT << nl; } void Foam::wallModelFvPatchScalarField::createFields() const { - if (!db().found("h")) + if (debug) + { + Info<< "wallModelFvPatchScalarField creating fields" << nl; + } + + // Name of the h field, default to hSampler + word hName = "hSampler"; + + // Check if hSampler exists + IOobject hHeader + ( + "hSampler", + db().time().timeName(), + db(), + IOobject::NO_READ + ); + + bool foundhSampler = hHeader.typeHeaderOk(); + db().checkOut("hSampler"); + + if (debug) + { + Info<< "wallModelFvPatchScalarField: Found hSampler? " << foundhSampler + << nl; + } + + + if (!foundhSampler) + { + Warning + << "The hSampler field is not found, will try to find h. " + << "Please note that h will not work with compressible solvers. " + << "It is recommended to use hSampler in new cases." << nl; + + IOobject hHeader + ( + "h", + db().time().timeName(), + db(), + IOobject::NO_READ + ); + + if (hHeader.typeHeaderOk()) + { + hName = "h"; + if (debug) + { + Info<< "wallModelFvPatchScalarField: Found field h" << nl; + } + } + db().checkOut("h"); + } + + if (!db().found(hName)) { db().store ( @@ -67,7 +123,7 @@ void Foam::wallModelFvPatchScalarField::createFields() const ( IOobject ( - "h", + hName, db().time().timeName(), db(), IOobject::MUST_READ, @@ -78,7 +134,7 @@ void Foam::wallModelFvPatchScalarField::createFields() const ); } - const volScalarField & h = db().lookupObject("h"); + const volScalarField & h = db().lookupObject(hName); // Create and register wallShearStress field, if not there already. if (!db().found("wallShearStress")) @@ -155,6 +211,34 @@ void Foam::wallModelFvPatchScalarField::createFields() const ) ); } + if (debug) + { + Info<< "wallModelFvPatchScalarField finished creating fields" << nl; + } +} + +Foam::tmp Foam::wallModelFvPatchScalarField::nu() const +{ + const turbulenceModel& turbModel = + db().lookupObject + ( + turbulenceModel::propertiesName + ); + return turbModel.nu(); +} + + +Foam::tmp Foam::wallModelFvPatchScalarField::nu +( + const label patchi +) const +{ + const turbulenceModel& turbModel = + db().lookupObject + ( + turbulenceModel::propertiesName + ); + return turbModel.nu(patchi); } // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // @@ -168,6 +252,7 @@ Foam::wallModelFvPatchScalarField::wallModelFvPatchScalarField fixedValueFvPatchScalarField(p, iF), consumedTime_(0), copyToPatchInternalField_(false), + silent_(false), averagingTime_(0) { if (debug) @@ -193,6 +278,7 @@ Foam::wallModelFvPatchScalarField::wallModelFvPatchScalarField fixedValueFvPatchScalarField(orig, p, iF, mapper), consumedTime_(0), copyToPatchInternalField_(orig.copyToPatchInternalField_), + silent_(orig.silent_), averagingTime_(orig.averagingTime_) { if (debug) @@ -219,6 +305,7 @@ Foam::wallModelFvPatchScalarField::wallModelFvPatchScalarField ( dict.lookupOrDefault("copyToPatchInternalField", false) ), + silent_(dict.lookupOrDefault("silent", false)), averagingTime_(dict.lookupOrDefault("averagingTime", 0)) { if (debug) @@ -243,6 +330,7 @@ Foam::wallModelFvPatchScalarField::wallModelFvPatchScalarField fixedValueFvPatchScalarField(orig), consumedTime_(orig.consumedTime_), copyToPatchInternalField_(orig.copyToPatchInternalField_), + silent_(orig.silent_), averagingTime_(orig.averagingTime_) { if (debug) @@ -265,6 +353,7 @@ Foam::wallModelFvPatchScalarField::wallModelFvPatchScalarField fixedValueFvPatchScalarField(orig, iF), consumedTime_(orig.consumedTime_), copyToPatchInternalField_(orig.copyToPatchInternalField_), + silent_(orig.silent_), averagingTime_(orig.averagingTime_) { if (debug) @@ -303,7 +392,8 @@ void Foam::wallModelFvPatchScalarField::updateCoeffs() const vectorField & wallGradU = wallGradUField.boundaryField()[pI]; - const volScalarField & nu = db().lookupObject("nu"); + tmp tnuw = this->nu(pI); + const scalarField& nuw = tnuw(); // Compute nut and assign scalarField nut(calcNut()); @@ -333,15 +423,19 @@ void Foam::wallModelFvPatchScalarField::updateCoeffs() wss.boundaryField()[pI] #endif == - (nut + nu.boundaryField()[pI])*wallGradU; + (nut + nuw)*wallGradU; consumedTime_ += (db().time().elapsedClockTime() - startCPUTime); // Take the max consumed time across all procs reduce(consumedTime_, maxOp()); - Info<< "Wall modelling time consumption = " << consumedTime_ - << "s " << 100*consumedTime_/(db().time().elapsedClockTime() + SMALL) - << "% of total " << nl; + + if (!silent_) + { + Info<< "Wall modelling time consumption = " << consumedTime_ + << "s " << 100*consumedTime_/(db().time().elapsedClockTime() + SMALL) + << "% of total " << nl; + } } diff --git a/wallModels/wallModelFvPatchScalarField.H b/wallModels/wallModelFvPatchScalarField.H index 4aa347c..cefbe90 100644 --- a/wallModels/wallModelFvPatchScalarField.H +++ b/wallModels/wallModelFvPatchScalarField.H @@ -19,7 +19,7 @@ License Class Foam::wallModelFvPatchScalarField -Description +@brief Base abstract class for LES wall models. Handles creating and storing fields used by the wall models. @@ -48,7 +48,6 @@ SourceFiles #define wallModelFvPatchScalarField_H #include "fixedValueFvPatchFields.H" -#include "Sampler.H" #include "volFields.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -72,6 +71,9 @@ private: //- Switch to copy data to wall-adjacent cells bool copyToPatchInternalField_; + //- Wether to suppress most output to the log file + bool silent_; + protected: // Protected data @@ -86,6 +88,13 @@ protected: //- Check that the patch is a wall virtual void checkType(); + + //- Return the laminar viscosity + // Note: this is the internal field + tmp nu() const; + + //- Return laminar viscosity on patchi + tmp nu(const label patchi) const; //- Calculate the turbulence viscosity virtual tmp calcNut() const = 0; @@ -158,6 +167,11 @@ public: return consumedTime_; } + bool silent() const + { + return silent_; + } + bool copyToPatchInternalField() const { return copyToPatchInternalField_;